Hi!
I'm trying to find out what is wrong with the next code which I'm trying to run in Linux:

int e1;
    int e2;
    pid_t pid1;    // pid of child
    pid_t pid2;
    pid_t w1;   // return code of wait()
    pid_t w2;

    // child process 1
    pid1 = fork();
    if (pid1 == 0) {
        // some code...
        exit(e1);
    }

    // child process 2
    pid2 = fork();
    if (pid2 == 0) {
        // some code
        exit(e2);
    }
   
    // wait for children to terminate
    w1 = waitpid(pid1, &e1, WEXITED);
    if (w1 == -1) perror("");
    w2 = waitpid(pid2, &e2, WEXITED);
    if (w2 == -1) perror("");

The problem here is that even if the program compiles all right and runs all the way to end and does what supposed in the child processes, I get "invalid argument" error message from waitpid's and the flow of program just happily passes those waits. What's that? What I don't do right? I have also tried _exit() but with no different results.

I have printed out pids to see what they are and they seem to be ok.

All help appreciated!

WEXITED can be only used with waitid(), not waitpid(). Hum... Ok, it works better when I put

waitpid(pid, &status, 0);

Just as it says in manual. :I

Or wait a minute.

It waits only process number 1, and not number 2. Why?

> It waits only process number 1, and not number 2. Why?
Because you asked it to.

If you use -1 as the pid, then it will wait for any child, and return with the pid of the child which ended.
Put that into a loop until all your children have ended, then carry on as normal.

Ok, here's the solution.
When you have a pipe open in parent process, you have to close the pipe before waiting. It has to do with the file descriptor counters of the pipe ends, they have to be zeroes to not cause a child to block on them (in particular, the read end). The counters are the key if you want to look for more information.

The code which works is here:

close(pipefd[0]);
close(pipefd[1]);
    
// wait for children to terminate
    
w1 = waitpid(pid1, &status1, 0);
if (w1 == -1) perror("");
printf("%d terminated: %d\n", pid1, w1);

w2 = waitpid(pid2, &status2, 0);
if (w2 == -1) perror("");
printf("%d terminated: %d\n", pid2, w2);

This way you can wait for specific pid's one at a time, as is done in this example.

Thanks to my professor.

This article has been dead for over six months. Start a new discussion instead.