#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
#define NP 3
#define VAL 10

main() {
  pid_t proc[NP];
  int fd[NP][2], np, val, i;

  for (np=0; np<NP; np++)
    pipe(fd[np]);

  for (np=0; np<NP; np++) {
    if ((proc[np] = fork()) == 0) {
      // processos filhos fecham extremidades adequadas das pipes
       for (i=0; i<NP; i++) {
        if (i != np) close(fd[i][WRITE]);
        if (i != (np-1+NP)%NP) close(fd[i][READ]);
      }
      // primeiro processo filho começa tudo e envia primeiro valor
       if (np == 0) {
        val = 1;
        printf("Filho 1: 1\n");
        write(fd[np][WRITE], &val, sizeof(int));
      }
      // todos os processos filhos ficam lendo e escrevendo nas
      // extremidades adequadas até que um deles receba o valor 10
      while(read(fd[(np-1+NP)%NP][READ], &val, sizeof(int))) {
        if (val == VAL) break;
        val++;
        printf("Filho %d: %d\n", np + 1, val);
        write(fd[np][WRITE], &val, sizeof(int));
      }
      // filhos terminaram, fecham suas extremidades e saem do programa
      close(fd[np][WRITE]);
      close(fd[(np-1+NP)%NP][READ]);
      exit(0);
    }
  }
}
