title: Endless loop in multi-pipe() C program
body: <p>I have a program that expects a list of commands that would be executed by <code>executeCommand3</code>. The goal is to execute a list of commands that for now are stored in this list but in the future will be typed in a shell-like enviromment to be executed, here is the code:</p>
  
  <p><strong>MAIN.c</strong></p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;    //for getpid()
  #include &lt;sys/types.h&gt; // for pid_t
  
  #include "routines.h" //for executeCommand3()
  
  #define SUB_PROCESSES_NUMBER 2
  
  char *command0[] = {"ls", "tos", NULL};
  char *command1[] = {"wc", NULL}; 
  char *command2[] = {"wc", NULL};
  char **commands[SUB_PROCESSES_NUMBER + 1] = {command0, command1, command2};
  
  int main()
  {   
  
      char input[1024];
      printf("scan: ");
      fgets(input,1024,stdin);
      int value=0;
      while((strcmp(input,"q\n")!=0))
      {
          value=executeCommand3(commands, SUB_PROCESSES_NUMBER+1);
  
          char buffer[1024];
          printf("value %i\nscan: ",value);
          fgets(input,1024,stdin);
          fgets(buffer,1024,stdin);
          printf("%s\n",input);
      }
      return 0;
  }
  </code></pre>
  
  <p><strong>routines.c</strong></p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt; // for open, close,read,write on FD
  #include &lt;error.h&gt;     // for error handling
  #include &lt;sys/types.h&gt; // structs like time_t
  #include &lt;sys/wait.h&gt;  // wait, waitpid, waitid - wait for process to change state
  
  #include "routines.h"
  
  #define READ 0  // for file descriptor index
  #define WRITE 1 // for file descriptor index
  
  #define STDIN 0
  #define STDOUT 1
  
  int executeCommand3(char ***args, int processNumb)
  {
      pid_t pidList[processNumb];    //list of id of cmd processes (one for each child)
      int fdBackLog[processNumb][2]; // list of file desrciptors relative for each cmd (a pair for each child)
  
      int lastProcessFlag = 0;
      int i;
      for (i = 0; i &lt; processNumb; i++) //cycle through the list of commands
      {
          if ((i + 1) == processNumb){
              lastProcessFlag = 1;
          }
  
          if (lastProcessFlag != 1)
          {
              int retPipe = pipe(fdBackLog[i]);
              if (retPipe &lt; 0) // generating pipe for comunication between cmd(i) and cmd(i+1)
              {
                  perror("pipe error");
  
                  if (i &gt; 0)
                  {
                      close(fdBackLog[i - 1][READ]); 
                  }
                  exit(EXIT_FAILURE); //exit with failure code
              }
          }
  
          pidList[i] = fork();
  
          if (pidList[i] &lt; 0) // error fork
          {
              perror("error fork()");
  
              if (i &gt; 0)
              {                                  
                  close(fdBackLog[i - 1][READ]); 
              }
              close(fdBackLog[i][READ]);  // close the read pipe end of cmd(i)
              close(fdBackLog[i][WRITE]); //close the write pipe end of cmd(i)
              exit(EXIT_FAILURE);
          }
  
          if (pidList[i] == 0) // CHILD PROCESS
          {
              printf("children %i process parent %i for: %s \n", getpid(), getppid(), args[i][0]);
              if (lastProcessFlag != 1)
              {
  
  
                  close(fdBackLog[i][READ]); 
  
                  dup2(fdBackLog[i][WRITE], STDOUT);
                  close(fdBackLog[i][WRITE]); // duplicated pipes are not useful any more
  
              }
              else
              {
                  close(fdBackLog[i][WRITE]); //last process has nothing to write on pipe
              }
  
              if (i &gt; 0)
              {
                  // Also need to redirect stdin if this is not first process
                  dup2(fdBackLog[i - 1][READ], STDIN);
                  close(fdBackLog[i - 1][READ]);
              }
  
              int exitValue = execvp(args[i][0], args[i]); 
              perror(args[i][0]);
              exit(EXIT_FAILURE); // Should not be reached;
          }
  
          close(fdBackLog[i][WRITE]); 
          if (i &gt; 0)
          {
              close(fdBackLog[i - 1][READ]);
          }
      }
  
      int wPid, status;
  
      while((wPid = wait(&amp;status))&gt;0)
      {
          printf("Child #%i (%i)\n", wPid, status);
      }
  }
  </code></pre>
  
  <p>My problem is with the error handling, in fact the second item of the first list of commands are some random words.</p>
  
  <p>When I execute the command the output is goood (like in a normal shell) but the problem is that the while loop in MAIN.c continues to call the function <code> executeCommand3()</code>. I thought that this could be happening because some process in <code> executeCommand3()</code> leaves something in the stdin of MAIN.c an so the <code>fgets</code> gets it from the stream and keeps the cicle of the while loop. So I added another fget to interrupt the cycle but the problem still reamins.... </p>
  
  <p>How can i fix the the program so even if I have an error from <code>executeCommand3()</code> the while loop stops and i can redoo the cyclenormally?
  The problem is within the <code>executeCommand3()</code> function (maybe in some <code>dup2()</code>, <code>pipe()</code>...) or in <strong>MAIN.c</strong>?</p>