cunixpipepiping

Stuck on using multiple pipes in C


I'm writing a program that just chains together specifically 3 programs, etc "ls | sort | wc".

I looked through the other posts I found on google about multiple pipes but I still can't figure out what I've been doing wrong. Been stuck on this for a while. I believe my program is logically correct, but for some reason it doesn't run. What am I missing?

pipe(pipe1);
pipe(pipe2);

pid = fork();
if(pid > 0){
    close(pipe2[1]);
    dup2(pipe2[0], 0);
    execlp(argv[3], argv[3], NULL);
}
else if(pid == 0){
    pid2 = fork();
    if(pid2 == 0){
        close(pipe1[0]);
        dup2(pipe1[1], 1);
        execlp(argv[1], argv[1], NULL);
    }
    else if(pid2 > 0){
        close(pipe1[1]);
        dup2(pipe1[0], 0);
        close(pipe2[0]);
        dup2(pipe2[1], 1);
        execlp(argv[2], argv[2], NULL);
    }
}

Solution

  • You need to fork three times each time in the parent cases, and execute your commands only inside the child cases. Take a look here

    Adjusted to your case:

    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    
    int main(int argc, char **argv) {
    
      int pid;
      int pipe1[2];
      int pipe2[2];
    
      // create pipe1
      if (pipe(pipe1) == -1) {
        perror("bad pipe1");
        exit(1);
      }
    
      // fork (ps aux)
      if ((pid = fork()) == -1) {
        perror("bad fork1");
        exit(1);
      } 
      else if (pid == 0) {
        // stdin --> ps --> pipe1
        // input from stdin (already done), output to pipe1
        dup2(pipe1[1], 1);
        // close fds
        close(pipe1[0]);
        close(pipe1[1]);
    
        execlp(argv[1], argv[1], NULL);
        // exec didn't work, exit
        perror("bad exec ps");
        _exit(1);
      }
      // parent
    
      // create pipe2
      if (pipe(pipe2) == -1) {
        perror("bad pipe2");
        exit(1);
      }
    
      // fork (grep root)
      if ((pid = fork()) == -1) {
        perror("bad fork2");
        exit(1);
      } 
      else if (pid == 0) {
        // pipe1 --> grep --> pipe2
        // input from pipe1
        dup2(pipe1[0], 0);
        // output to pipe2
        dup2(pipe2[1], 1);
        // close fds
        close(pipe1[0]);
        close(pipe1[1]);
        close(pipe2[0]);
        close(pipe2[1]);
    
        execlp(argv[2], argv[2], NULL);
        // exec didn't work, exit
        perror("bad exec grep root");
        _exit(1);
      }
      // parent
    
      // close unused fds
      close(pipe1[0]);
      close(pipe1[1]);
    
      // fork (grep sbin)
      if ((pid = fork()) == -1) {
        perror("bad fork3");
        exit(1);
      } 
      else if (pid == 0) {
        // pipe2 --> grep --> stdout
        // input from pipe2
        dup2(pipe2[0], 0);
        // output to stdout (already done). Close fds
        close(pipe2[0]);
        close(pipe2[1]);
    
        execlp(argv[3], argv[3], NULL);
        // exec didn't work, exit
        perror("bad exec grep sbin");
        _exit(1);
      }
      // parent
    
      return 0;
    }