waiting for multiple childs - C - waitpid

Hi gurus, I would like to fork more children and then write their return values: so far I tried:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
        pid_t pid;
        int rv=0, i;
        pid_t child_pids[5];


        for (i=1; i<=5; i++){

                /* Multiple child forking */
                switch(pid = fork()){
                        case -1:
                                /* something went wrong */
                                /* parent exits */
                                perror("fork");
                                exit(1);

                        case 0:
                                /*Children process*/
                                child_pids = getpid();
                                printf(" CHILD: number (and return value): %d PID: %d PPID: %d \n", i, getpid(), getppid());
                                exit(i);
                                break;

                                /*Missing code for parent process - will be executed out of loop*/
                }
        }
        /*Parent process*/
        if (pid!=0 && pid!=-1) {
                printf("PARENT: my PID is %d\n", getpid());

                for (i=1; i<=5; i++){
                        waitpid(child_pids, NULL, 0);
                        printf("PARENT: Child: %d returned value is: %d\n", i, WEXITSTATUS(child_pids));
                }
        }
}

But returns any random variables for child process:

...
PARENT: Child: 3 returned value is: 13
PARENT: Child: 3 returned value is: 127
...

also tried following

int main(void)
{
        pid_t pid;
        int rv=0, i;
        pid_t child_pids[5];
        int child_state = 9;
        pid_t rc_pid;


        for (i=1; i<=5; i++){

                /* Multiple child forking */
                switch(pid = child_pids = fork()){
                        case -1:
                                /* something went wrong */
                                /* parent exits */
                                perror("fork");
                                exit(1);

                        case 0:
                                /*Children process*/
                                //child_pids = getpid();
                                printf(" CHILD: number (and return value): %d PID: %d PPID: %d \n", i, getpid(), getppid());
                                exit(i);
                                break;

                                /*Missing code for parent process*/
                }
        }
        /*Parent process*/
        if (pid!=0 && pid!=-1) {
                printf("PARENT: my PID is %d\n", getpid());

                for (i=1; i<=5; i++){
                        rc_pid = waitpid(child_pids, NULL, 0);
                        printf("PARENT: Child: %d returned value is: %d\n", i, WEXITSTATUS(child_pids));
                }
        }
}

but returns always number 19 as return code of children
...
PARENT: Child: 4 returned value is: 19
...

Probably something something is wrong with waitpid() function
Thanks a lot.

Yes, you're not supposed to use WEXITSTATUS() on a PID, it's a different integer, but you're throwing that value away. Try:

{
        int status;
        waitpid(child_pids, &status, 0);
        printf("exit status %d = %d\n", i, WEXITSTATUS(status));
}
1 Like

Thanks a lot that worked as expected :slight_smile: just one question is this right way to create children ?

Instead of 'missing code for parent section' I'd do this:

default: /* Parent does nothing in the loop */
        break;

Some compilers need it.

I'd also count errors to make sure you're not waiting for more processes than you actually created.

Otherwise I see nothing incorrect in your code.

if there is

                        case -1:
                                /* something went wrong */
                                /* parent exits */
                                perror("fork");
                                exit(1);

program should quit if some errors happens and no waiting will be called. or am I missed something ?

You're right, I didn't quite catch that.