Home > Software engineering >  No correct redirection between pipes
No correct redirection between pipes

Time:01-23

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.

CodePudding user response:

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");

  • Related