#include <stdio.h>                // Pour entrees/sorties
#include <stdlib.h>               // Pour exit
#include <sys/types.h>            // Pour pid_t
#include <sys/wait.h>             // Pour wait
#include <unistd.h>               // Pour pipe, fork, write, read, close
#define  LONGUEUR_MESSAGE 21      // 20 lettres + '\0'
#define  NB_MESSAGES      10

int tube[2];                      // Descripteurs du tube (variable globale)

void fils1()                      // Code de fils1
{ int i;
  char message[LONGUEUR_MESSAGE];

  close(tube[0]);                 // On ferme la lecture pour le fils
  srand(getpid());                // Initialisation du generateur aleatoire
  for(i=1; i<=NB_MESSAGES; i++)   // On ecrit les messages
  { sprintf(message, "%03d Message de fils1", i);
    write(tube[1], message, LONGUEUR_MESSAGE);
    sleep(rand()%2+1);            // On s'endort 1 ou 2 secondes
  }
  close(tube[1]);                 // On ferme l'ecriture pour le fils
  exit(0);                        // Fin de fils1
}

void fils2()                      // Code de fils2.
{ int i;
  char message[LONGUEUR_MESSAGE];

  close(tube[0]);                 // On ferme la lecture pour le fils
  srand(getpid());                // Initialisation du generateur aleatoire
  for(i=1; i<=NB_MESSAGES; i++)   // On ecrit les messages
  { sprintf(message, "%03d Message de fils2", i);
    write(tube[1], message, LONGUEUR_MESSAGE);
    sleep(rand()%2+1);            // On s'endort 1 ou 2 secondes
  }
  close(tube[1]);                 // On ferme l'ecriture pour le fils
  exit(0);                        // Fin de fils2
}

int main()
{ int nb_car, etat;
  char buffer[LONGUEUR_MESSAGE];
  pid_t	pid1, pid2, pid_wait;
  
  pipe(tube);                     // Creation du tube par le pere
  pid1 = fork();                  // Creation d'un premier fils
  if (pid1 == 0)
    fils1();
  else                            // Suite du code du pere
  { pid2 = fork();                // Creation d'un second fils
    if (pid2 == 0)
      fils2();
    else                          // Suite du code du pere
    { close(tube[1]);             // On ferme l'ecriture pour le pere

      nb_car = read(tube[0], buffer, LONGUEUR_MESSAGE);
      while (nb_car > 0)          // Lecture messages jusqu'a fin de fichier
      { printf("%s\n",buffer);
        nb_car = read(tube[0], buffer, LONGUEUR_MESSAGE);
      }
      
      pid_wait = wait(&etat);     // Attente de la fin d'un premier fils
      printf("Pere => fin du fils %d.\n", (pid_wait == pid1)?1:2);
      pid_wait = wait(&etat);     // Attente de la fin d'un second fils
      printf("Pere => fin du fils %d.\n", (pid_wait == pid1)?1:2);
    }
  }
  return(0);
}
