title: Pass a value between processes using pipes in a loop
body: <p>I am trying to build a program that forks 4 child processes. The first child takes a value declared before forking, decrements it then passes it through a tube to the second process. The latter increments the value and passes it to the third one. 3 -> 4, 4 - 1 and so on. The program will end when 0 is reached and exit with the PID of the child that got that 0.</p>
  
  <p>This is what I tried:</p>
  
  <pre><code>volatile sig_atomic_t end = 1;
  </code></pre>
  
  <p>First I installed a signal handler:</p>
  
  <pre><code>void sighandler(int sig)
  {
          (void)sig;
          end = 0;
  }
  </code></pre>
  
  <p>Then I assigned the action to <code>SIGUSR1</code>:</p>
  
  <pre><code>void prepare()
  {
          struct sigaction s;
          s.sa_handler = sighandler;
          s.sa_flags = 0;
          sigemptyset(&amp;s.sa_mask);
          sigaddset(&amp;s.sa_mask, SIGUSR1);
          sigaction(SIGUSR1, &amp;s, NULL);
  }
  </code></pre>
  
  <p>This is my main:</p>
  
  <pre><code>int main()
  {
  
      pid_t cpid, first;
      int status;
      int COUNT = 10;
      int pipes[NPROC];
      prepare();
      for (int i = 0; i &lt; 2; i++)
      {
              pipe(pipes + 2 * i);
      }
  
      for (int i = 0; i &lt; NPROC; i++)
      {
              switch (first = fork())
              {
              case -1:
                      perror("fail");
              case 0:
                      if (i % 2 == 0)
                      {
                              while (end)
                              {
                                      dup2(pipes[i], 0);
                                      read(pipes[i], &amp;COUNT, sizeof(COUNT));
                                      COUNT--;
                                      if (COUNT &lt; 0)
                                              kill(getppid(), SIGUSR1);
                                      dup2(pipes[i + 1], 1);
                                      write(pipes[i + 1], &amp;COUNT, sizeof(COUNT));
                                      for (int j = 0; j &lt; NPROC; j++)
                                              close(pipes[j]);
                              }
                      }
                      else
                      {
                              while (end)
                              {
                                      dup2(pipes[i - 1], 0);
                                      read(pipes[i - 1], &amp;COUNT, sizeof(COUNT));
                                      COUNT--;
                                      if (COUNT &lt; 0)
                                              kill(getppid(), SIGUSR1);
                                      dup2(pipes[(i + 2) % NPROC], 1);
                                      write(pipes[(i + 2) % NPROC], &amp;COUNT, sizeof(COUNT));
                                      for (int j = 0; j &lt; NPROC; j++)
                                              close(pipes[j]);
                              }
                      }
                      exit(i);
              }
              printf("Start %d \n", first);
      }
  
      for (int i = 0; i &lt; NPROC; ++i)
      {
              cpid = wait(&amp;status);
  
              if (!WIFEXITED(status))
                      printf("Error in child %d\n", (int)cpid);
              else
                      printf("Finished %d\n", (int)cpid);
      }
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>The idea is, the program runs, installs the signal handler. The signal handler will, when triggered, stop all children processes and allow them to exit.
  Then I fork 4 processes. Each will open and close certain tubes in order to communicate with each other and at the same time, each decrements the value and pass it along. When the value hits 0 a signal will be raised and we will get the process id that sent the signal.
  When I run the program, it starts and then it just waits indefinitely...
  What am I missing? </p>