How a program that uses two child process stop, while first child is not done yet

54 Views Asked by At

This is the program The program is an implementation of pipe ( | )

#include <stdio.h>
#include <fcntl.h>

int main(int ac, char **av, char **env)
{
    int end[2];
    int file[2];
    char **cmd1;
    char **cmd2;
    int status;

    file[0] = open(av[1], O_RDONLY);
    file[1] = open(av[4], O_CREAT | O_TRUNC | O_WRONLY, 0644);
    cmd1 = ft_split(av[2], ' ');
    cmd2 = ft_split(av[3], ' ');
    pipe(end);
    int id = fork();
    if (id == 0)
    {
        close(end[0]);
        dup2(file[0], STDIN_FILENO);
        dup2(end[1], STDOUT_FILENO);
        execve(cmd1[0], cmd1, env);
    }
    int id2 = fork();
    if(id2 == 0)
    {
        close(end[1]);
        dup2(end[0], STDIN_FILENO);
        dup2(file[1], STDOUT_FILENO);
        execve(cmd2[0], cmd2, env);
    }
    close(end[0]);
    close(end[1]);
    waitpid(id, &status,0);
    waitpid(id2,&status,0);
    write(1,"DOne", 5);
    return (0);
}

the program take arguments :

  1. av[1] : Name of file to open, as an input file.
  2. av[2] : path of command path file
  3. av[3] : second command path file
  4. av[4] : the output file

-the program works Fine It takes the first file as an input file, apply first command on it,

then send the output of the first command the second command

then send the output to the output file (If output file does not exist it creates a new one);

But what I do not Understand is in this case : ./a.out /dev/random "/bin/cat" "/usr/bin/head -1" o.txt

/dev/random is a huge file, so why once the second child get the result the main program end successfully

why the main program does not wait until the first child done cutting

1

There are 1 best solutions below

2
John Bollinger On

But what I do not Understand is in this case : ./a.out /dev/random "/bin/cat" "/usr/bin/head -1" o.txt /dev/random is a huge file, so why once the second child get the result the main program end successfully why the main program does not wait until the first child done cutting

Who says it doesn't? That the waitpid() call with that child's pid returns successfully (verify by checking its return value) tells you that that child either terminated or was stopped.

The first child terminating is completely plausible under the circumstances. When the second child terminates, the pipe ceases to have any readers. At that point, I expect the first child's attempts to write to the pipe to cause a SIGPIPE to be delivered to it, killing it.

At that point, the parent's wait for the first child can complete successfully, and it will immediately after be able to collect the second child as well.

You can verify this by interrogating the status word provided by each (successful) call to waitpid(). It can tell you whether the process terminated normally or because of a signal (or was merely stopped). If terminated by a signal then it can tell you which, and if it terminated normally then it can tell you the child's exit status.