title: execlp multiple commands using pipes dup2 - c language
body: <p>Im have a little C program which executes bash commands (kind of shell program).</p>
  
  <p>When user sends command such a: </p>
  
  <blockquote>
    <ol>
    <li><p>ls -l | grep .[c,h]$ | wc –l</p></li>
    <li><p>ls</p></li>
    <li><p>echo | ls</p></li>
    </ol>
  </blockquote>
  
  <p>I have decides to use linked list data sturcture, and this is the function that execute</p>
  
  <pre><code>int execute(command *c) {
  //create new procces and execute command 
  
  int numOfPipe = getNumOfPipes(c);   // gets how many commands there is seperated by | (for 1 command with no pipes. getNumOfPipes returns 1
  int fds[numOfPipe][2];
  
  pid_t pids[numOfPipe];
  int i;
  int status;
  
  // create pipes
  for( i = 0; i &lt; numOfPipe; i++ ) {
      pipe(fds[i]);
  }
  
  i=0;
  
  // p set to be the head of the list (first command)
  Pipe* p = c-&gt;pl-&gt;head;  
  
  // running throw all nodes
  while(i&lt;numOfPipe) {
  
      if ((pids[i] = fork()) &lt; 0) {
              perror("fork");
              abort();
      } else if (pids[i] == 0) {
          // children processes
  
          // there is more then one command
          if (numOfPipe &gt; 1) {    
              if (p==c-&gt;pl-&gt;head) // first node (will be first command)
                  dup2(fds[i][1],STDOUT_FILENO);
              else if(p-&gt;next!=NULL) {    // not first / last command
                  dup2(fds[i-1][0],STDIN_FILENO);
                  dup2(fds[i][1],STDOUT_FILENO);
  
              } else if(p-&gt;next==NULL)    // last command
                  dup2(fds[i-1][0],STDIN_FILENO);
  
  
              // closing all pipes
              int j;
              for( j = 0; j &lt; numOfPipe; j++ ){
                  close(fds[j][0]);
                  close(fds[j][1]);
              }
          }
  
          // execute command
          execvp(p-&gt;params[0],p-&gt;params);
  
          // on execute error will print this messege and returns COMMAND_ERROR
          fprintf(stderr, "%s: command not found\n",p-&gt;params[0]);    
          destroyShell(c);
          free(c);
          exit(COMMAND_ERROR);    
      }
  
      // parent closing all end of pipes
      int j;
      for( j = 0; j &lt; numOfPipe &amp;&amp; numOfPipe &gt; 1; j++ ){
          close(fds[j][0]);
          close(fds[j][1]);
      }
  
      // waiting each process
      while(wait(&amp;status)!=pids[i]);
  
      // if the command is valid
      if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status)==COMMAND_ERROR) {
          destroyShell(c);
          return WEXITSTATUS(status);
      }
  
      p=p-&gt;next;
      i++;
  
  
  }
  
  // closing all end of pipes (necessary here????)
  int j;
  for (j = 0; j &lt; numOfPipe; j++) {
      close(fds[j][0]);
      close(fds[j][1]);
  }
  
  // returns all command's return code
  if (WIFEXITED(status))
      return WEXITSTATUS(status);
  
  return 0;
  }
  </code></pre>
  
  <p>By now this code working in unpredicted way, for single command its working, for serval sometimes it working and sometimes not.... Spent many hours on this block of code and google didnt helped at all!!</p>
  
  <p>Few notes:</p>
  
  <ol>
  <li>When user sends command such as:</li>
  </ol>
  
  <blockquote>
    <p>echo|ls|123</p>
  </blockquote>
  
  <p>return code will be COMMAND_ERROR macro define, and there suposed to be this error message:</p>
  
  <blockquote>
    <p>123: command not found</p>
  </blockquote>
  
  <p>but somehow my code will execute 'echo | ls' and show the output of the 2 first commands and after that will show the the error message for '123' command.
  Also for few bad commands - its suposed to show error message only for the first one it founds and its not suposed to continue to exec the next commands...</p>
  
  <p>and for this command:</p>
  
  <blockquote>
    <p>ls -l | grep .[c,h]$ | wc –l</p>
  </blockquote>
  
  <p>it seems like it stocked in endless loop....</p>
  
  <ol>
  <li>Command *c is helding the linked list, each node in the list will be one command and each node will keep array call params which keep all the parameters of the command.
  exmaple:</li>
  </ol>
  
  <blockquote>
    <p>echo 1234 | ls /home</p>
  </blockquote>
  
  <pre><code> ___________                 ___________
  |           |               |           |
  | COMMAND 1 |      ---&gt;     | COMMAND 2 |
  |___________|               |___________|
        |                           |
        |                           |
      ______                     _______
     |      |                   |       |
     | ECHO |                   |  LS   |
     |______|                   |_______|
     |      |                   |       |
     | 1234 |                   | /HOME |
     |______|                   |_______|
  </code></pre>
  
  <p>I hope i was clear enought and explained my issues well.
  Thank you very much!</p>