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 :
- av[1] : Name of file to open, as an input file.
- av[2] : path of command path file
- av[3] : second command path file
- 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
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
SIGPIPEto 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
statusword provided by each (successful) call towaitpid(). 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.