-1

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

Taha Exo
  • 1
  • 1
  • 2
    Have you tried to do any kind of debugging? Like printing out the contents of `cmd1` and `cmd2`? Are these arrays properly null-pointer terminated? How about running just the first process? Does it produce the output it's supposed to do? When you run only the second program? Have you checked *any* function for possible failure? – Some programmer dude Feb 27 '23 at 15:18
  • Without the definition of `ft_split`, asking others to debug this is useless. – Oka Feb 27 '23 at 15:21
  • `/dev/random` is not merely a huge file, it is a *device* that will provide an *unbounded* sequence of bytes. But that does not suffice to conclude that the first child does not terminate before the parent does. – John Bollinger Feb 27 '23 at 15:40
  • yes ft_split null terminate, i mentioned that the program run successfully, the question is how parallel process works in that case – Taha Exo Feb 27 '23 at 15:53
  • 2
    You have zero error handling in the code shown. You've no idea where things go wrong. You don't even check that you got enough arguments on the command line. – Jonathan Leffler Feb 27 '23 at 16:02

1 Answers1

1

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.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • thank you sir, first waitpid status is greater than 0, – Taha Exo Feb 27 '23 at 15:55
  • @TahaExo, I'm glad that cleared up some things for you, but it sounds like you may still have some misconceptions. The `status` word provided by `waitpid()` encodes multiple distinct pieces of data. You should not really be looking at its raw value, but instead be using the various [macros](https://man7.org/linux/man-pages/man3/wait.3p.html) provided for extracting the pieces, such as `WIFEXITED()` and `WIFSIGNALED()`. – John Bollinger Feb 27 '23 at 16:02