4

I am trying to create a small program using Java to fork two new child processes. It's for a beginner's programming class who's tutorials are in C, so I'm looking for some help to understand what this code tidbit is trying to do and what is the best way to adapt it to a Java-based program (to eventually build on it).

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

int main()
{
pid t pid;

    /*fork a child process*/
    pid = fork();

    if (pid < 0) { /*error occurred*/
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) {/*child process */
        execlp("/bin/ls", "ls", NULL); 
    }
    else { /*parent process*/
        /*parent will wait for the child to complete */
        wait(NULL);
        printf("Child Complete");
    }
    return 0;
}

UPDATE:

I am supposed to attach an id to each child process and and its parent, printing the info when the child process executes and printing a termination notification when it terminates. I now see that this bit of code above lists the contents of the current directory and prints "Child Complete" when the process has terminated. Is the listing of the entire directory considered one process? If so, where/how does the second new child process come into the picture?

user25976
  • 1,005
  • 4
  • 18
  • 39

2 Answers2

4

Well, to answer what the program does:

When fork() executes, you get two processes. They do exactly the same thing, except that one of them (the child) gets 0 returned from fork(), while the parent gets any other positive value from fork(). A negative return from fork() means it failed.

So by looking at the return from fork(), the process can determine if it's child or parent. In your case, you let the child execute the "ls" command, which lists files in current directory.

You let the parent wait() for all its child processes to finish. Then you say "Child complete".

You can try removing the wait() system call, to see clearer that the two processes actually run concurrently. Have a look at the man pages for ps(1), ls(1), fork(2) and exec(3).

Rein
  • 477
  • 2
  • 7
  • this gives me a much better idea of what the given code sample does. I still have some confusion, however, on a point that i added in my update above. – user25976 Oct 11 '14 at 23:34
  • 2
    Yes, the listing of the directory is one separate process. When you fork(), the OS starts a new process which executes the same binary as the parent. You can print out the value from getpid(), to really see that they have different process ID:s! Note though, that your execlp() call will "overload" the child process. – Rein Oct 11 '14 at 23:47
3

In Java, that might look something like -

public static void main(String[] args) {
    try {
        Process p = Runtime.getRuntime().exec("/bin/ls");
        final InputStream is = p.getInputStream();
        Thread t = new Thread(new Runnable() {
            public void run() {
                InputStreamReader isr = new InputStreamReader(is);
                int ch;
                try {
                    while ((ch = isr.read()) != -1) {
                        System.out.print((char) ch);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        p.waitFor();
        t.join();
        System.out.println("Child Complete");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • This worked well after adding import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; Like the other answer mentioned this printed the contents of the current directory. Is this considered one child process? I updated my question. – user25976 Oct 11 '14 at 23:36
  • @user25976 Yes. The `/bin/ls` is a child process. There is also a thread running to handle that process' output. – Elliott Frisch Oct 11 '14 at 23:37