Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

No correct redirection between pipes

I’m writing a program that should work like the following unix command: seq 2 number | awk argument | grep argument

#define READ 0
#define WRITE 1

void die(char* msg){
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
  int seq_to_awk[2];

  if(pipe(seq_to_awk) == -1)
    die("pipe");

  pid_t child = fork();
  if(child == -1)
    die("fork");

  if(child == 0){
    if(close(seq_to_awk[READ]) == -1)
      die("close");

    if(dup2(seq_to_awk[WRITE], STDOUT_FILENO) < 0)
      die("dup2");

    if(close(seq_to_awk[WRITE]) == -1)
      die("close");

    execlp("seq", "seq", "2", argv[1], NULL);
  }

  child = fork();
  if(child == -1)
    die("fork");

  int awk_to_grep[2];
  if(pipe(awk_to_grep) == -1)
    die("pipe");

  if(child == 0){

    if(close(seq_to_awk[WRITE]) == -1)
      die("close");
    
    if(dup2(seq_to_awk[READ], STDIN_FILENO) < 0)
      die("dup2");

    if(close(seq_to_awk[READ]) == -1)
      die("close");
/**/
    if(close(awk_to_grep[READ]) < 0)
      die("close");

    if(dup2(awk_to_grep[WRITE], STDOUT_FILENO) < 0)
      die("dup2");

    if(close(awk_to_grep[WRITE]) == -1)
      die("close");
/**/    
    execlp("awk", "awk", argv[2], NULL);
    die("execlp");

  }

  if(close(seq_to_awk[READ]) == -1)
    die("close");
  if(close(seq_to_awk[WRITE]) == -1)
    die("close");

/**/
  child = fork();
  if(child == -1)
    die("fork");

  if(child == 0){

    if(close(awk_to_grep[WRITE]) == -1)
      die("close");

    if(dup2(awk_to_grep[READ], STDIN_FILENO) < 0)
      die("dup2");

    if(close(awk_to_grep[READ]) == -1)
      die("close");

    execlp("grep", "grep", argv[3], NULL);
    die("execlp");

  }
/**/

  if(close(awk_to_grep[READ]) == -1)
    die("close");
  if(close(awk_to_grep[WRITE]) == -1)
    die("close");

  wait(NULL);
  wait(NULL);
  wait(NULL);

  exit(EXIT_SUCCESS);
}

When I run the following code with the command: ./program 26 {print} 5 I get nothing as output, when the correct output should be:

5
15
25

I don’t understand what exactly I’m doing wrong here. When I leave out one of the programs(either awk or grep) the program runs as expected.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The problem is when setting up the awk_to_grep pipe. You fork before creating the pipe, so you in fact create two separate pipes. The pipe in your child process is not available to the parent and other children created after that.

Swap the order to this:

  int awk_to_grep[2];
  if(pipe(awk_to_grep) == -1)
    die("pipe");

 child = fork();
  if(child == -1)
    die("fork");

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading