wait(NULL) system call doesn't seem to wait for all child processes that uses execv()/execvp()

Viewed 28

I know wait(NULL) waits for all child process to terminate. But while working with fork(),execv()/execvp() and wait(), it seems wait(NULL) is not waiting for all the child processed to terminate.

I was trying to understand the unexpected behaviour of the wait(NULL) system call in my code. I tried to recreate the same situation with a different but smaller code, it is shown below.

#include <unistd.h>
#include <filesystem>
#include <sys/wait.h>
#include <bits/stdc++.h>
#include <fcntl.h>

using namespace std;

int main ()
{
    int pid;
    int fd[2];
    char command[] = "square";

    //constructing a pipe
    if(pipe(fd)==-1)
        cout<<"Pipe1 Failed";

    //first fork
    pid = fork();
    if(pid<0)
    {
        cout<<"fork failed";
    }
    else if(pid == 0)
    {
        cout<<"inside child 1\n";
        close(0);

        //opening input file at fd = 0
        if(open("input",O_RDONLY) != 0)
            cerr<<"Failed input open\n";

        //connecting write end of pipe to first child process
        dup2(fd[1],1);
        close(fd[1]);
        close(fd[0]);

        char *args[] = {command,NULL};
        //calling exec system call
        execv(command,args);
        
        cerr<<"execv1 failed\n";
        exit(0);
    }

    //second fork
    pid = fork();
    if(pid<0)
    {
        cout<<"fork failed";
    }
    else if(pid == 0)
    {
        cout<<"inside child 2\n";
        
        //connecting read end of the pipe to second child process
        dup2(fd[0],0);
        close(fd[0]);
        close(fd[1]);

        char *args[] = {command,NULL};
        //calling exec system call
        execv(command,args);

        cerr<<"execv2 failed\n";
        exit(0);
    }

    wait(NULL);
    cout<<"After wait\n";
    return 0;
}

What this code effectively tries to do is something like ./square < input | ./square in bash. input is a file that contains a number (it was 5 when I ran the code), square is a function that takes an integer input and prints its square (n*n). The code of square is

#include<stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    printf("%d",n*n);
    
    return 0;
}

The final output I was expecting is (with input file containing number 5)

inside child 1
inside child 2
625
After wait

But the final output I am getting is

inside child 1
inside child 2
After wait
625

Output image

Can somebody help me figure out what is happening here or where my understanding is wrong.

NOTE: I used g++ compiler to compile this C++ codes.

Thanks in advance.

1 Answers

wait(NULL) doesn't wait for all children to exit. wait(&wstatus) waits for one child, and puts its exit status into the int wstatus. wait(NULL) waits for one child, and ignores its exit status.

Citation: man 2 wait

Related