0

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.

Tim
  • 1
  • Recommendation: Don't shoot yourself in the foot with `#include `. Using it along with `#include ` suggests you don't know what bits/stdc++.h is and does, so [here's a bit of reading to help you out](https://stackoverflow.com/q/31816095/4581301). Combining it with `using namespace std;` compounds the problems by [making the downsides of `using namespace std;`](https://stackoverflow.com/q/1452721/4581301) much more likely to occur – user4581301 Sep 15 '22 at 18:54
  • Whichever C++ textbook taught you to use `` -- you need to throw it away and get a different C++ textbook. If you copied that off some web site, without any explanation, don't visit that web site any more. If you saw this in some clown's Youtube video, unsubscribe from that channel, you're not learning proper C++. Most C++ compilers in the world don't have this header file, and will not compile the shown code. – Sam Varshavchik Sep 15 '22 at 19:05
  • 1
    "waits for all child process to terminate" -> waits for one child process to terminate – Jeff Garrett Sep 15 '22 at 19:22

1 Answers1

1

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

metageek
  • 11
  • 2