title: C : Redirect child process output to other child process input and stdout
body: <p>I am a bit of a newbie in programming Linux in C (I searched for similar threads but none helped), so I got stuck at the following problem :</p>
  
  <p>I want to create a shell in C for Linux (using fork(), exec(), pipe(), that gets a command with parameters and pipes as input from the terminal stdin (ex. "sort foo | uniq -c | wc -l"), it executes it and then asks for the next command etc.</p>
  
  <p>I separated the different commands, their parameters etc, I created 1 child process for each one, but I can't chain the output of each child process to the input of the next one (and the last output at stdout in terminal).</p>
  
  <p>Could anyone help do the correct piping to get it up and running ??</p>
  
  <p>For any more info, just ask...
  Thanks in advance</p>
  
  <p>The full code is below:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt; 
  #include &lt;unistd.h&gt;
  
  #define P_READ 0
  #define P_WRITE 1
  
  pid_t pID, chID;
  char input[100];
  char * params[100][100];
  char * funcs[100];
  char * par;
  char * fun;
  int i, j, k, stat, infd[2], outfd[2];
  
  
  //Pipe read
  void read_en(int * infd)
  {
      dup2(infd[P_READ], STDIN_FILENO);
      close(infd[P_READ]);
      close(infd[P_WRITE]);
  }
  
  //Pipe write
  void write_en(int * outfd)
  {
      dup2(outfd[P_WRITE], STDOUT_FILENO);
      close(outfd[P_READ]);
      close(outfd[P_WRITE]);
  }
  
  //Fork, read from pipe, write to pipe, exec   
  void fork_chain(int * infd, int * outfd, int i)
  {
          pID = fork();
  
          if (pID == 0)
          {
              if (infd != NULL)
              {
                  read_en(infd);
              }
  
              if (outfd != NULL)
              {
                  write_en(outfd);
              }
  
              execvp(params[i][0], params[i]);
              fprintf(stderr, "Command not found!\n");
              exit(1);
          }
          else if (pID &lt; 0)
          {
              fprintf(stderr, "Fork error!\n");
              exit(1);
          }
          else
          {
              chID = waitpid(-1, &amp;stat, 0);
          }
  }
  
  
  int main()
  {
      printf("\n$");
      fgets(input, sizeof(input), stdin);
      strtok(input, "\n");
  
  
      while (strcmp(input, "exit") != 0)
      {
          //Separate each command
          k = 0;
          fun = strtok(input, "|");
  
          while (fun != NULL)
          {
              funcs[k] = fun;
              fun = strtok(NULL, "|");
              k++;
          }
  
  
          //Separate each command's parameters
          for (i = 0; i &lt; k; i++)
          {
              j = 0;
              par = strtok(funcs[i], " ");
  
              while (par != NULL)
              {
                  params[i][j] = par;
                  par = strtok(NULL, " ");
                  j++;
              }
              params[i][j] = NULL;
          }
  
          //Fork, pipe and exec for each command
          for (i = 0; i &lt; k; i++)
          {
              if (i == 0)
              {
                  pipe(outfd);
                  fork_chain(NULL, outfd, 0);
                  infd[P_READ] = outfd[P_READ];
                  infd[P_WRITE] = outfd[P_WRITE];
              }
              else if (i == k-1)
              {
                  fork_chain(infd, NULL, 1);
                  close(infd[P_READ]);
                  close(infd[P_WRITE]);
              }
              else
              {
                  pipe(outfd);
                  fork_chain(infd, outfd, i);
                  close(infd[P_READ]);
                  close(infd[P_WRITE]);
                  infd[P_READ] = outfd[P_READ];
                  infd[P_WRITE] = outfd[P_WRITE];
              }
          }
  
          //Ask for next input
          printf("\n$");
          fgets(input, sizeof(input), stdin);
          strtok(input, "\n");
      }
  
      return (0);
  }
  </code></pre>