// Le script de l'exécutable INIT qui prend en argument le nombre d'ouvriers
//inclusion du fichier de mes fonctions
#include "fichier_entete.h"

int main(int argc, char* argv[]){
  int nbre_fils,pid,tube[2];
  char *vo[2]={"ouvrier",(char *)NULL}; //pour le recouvrement des fils par l'exécutable ouvrier
  char *vp[3]={"maitre",argv[1],(char *)NULL}; //pour le recouvrement du père par l'exécutable maitre
   
  if (argc!=2){ // Vérification du nombre d'arguments de INIT
    perror("INIT requiert un argument : le nombre de fils (de 1 a 10).\n");
    exit(1);
  }
    nbre_fils=atoi(argv[1]);// conversion du nombre de fils : (de char* en int)
  // vérification du nombre de fils rentré
  if(nbre_fils>10 || nbre_fils<1){
    cout<<argv[1];
    perror("Le nombre de fils doit être compris entre 1 et 10\n");
    exit(2);
  }
 
  
  // Création des processus ouvriers
  for(int i=0; i<nbre_fils; ++i){
    if(pipe(tube)<0){
      perror("Erreur de création du tube ordinaire pour les ouvriers");
      exit(3);
    }
    pid = (int)fork();  //le pid du processus fils
    switch (pid){
    case -1 : // Section critique en cas d'erreur de la création du fils
      perror("Erreur de création du fils, erreur fork()\n");
      exit(4);

    case 0 : // Section fils
      if (close(tube[1])<0){ //on ferme l'entrée en écriture du tube ordinaire
	perror("Erreur de fermeture de l'entrée en écriture du tube ordinaire");
	exit(5);
      }
      //redirection de l'entrée standard du fils sur l'entrée en lecture du fils
      if (dup2(tube[0],STDIN_FILENO)<0){ // En cas d'erreur de dup2
	perror("Erreur de dup2");
	exit(6);
      }
      if (close(tube[0])<0){ //fermeture de l'entrée en lecture du tube ordinaire
	perror("Erreur de fermeture de l'entrée en lecture du tube ordinaire");
	exit(7);
      }
      execv("ouvrier",vo); //on recouvre le processus fils par l'exécutable ouvrier
      perror("Erreur de recouvrement du fils par ouvrier\n"); // Si le processus ne se recouvre pas
      exit(8);
      
    default : // Section père
      if(close(tube[0])<0){ //fermeture de l'entrée en lecture du tube ordinaire 
	perror("Erreur de fermeture de l'entrée en lecture du tube ordinaire");
	exit(9);
      }
      // redirection du descripteur i+3 du père vers l'entrée en écriture du tube ordinaire
      if(dup2(tube[1],i+3)<0){
	perror("Erreur de redirection du descripteur du père");
	exit(10);
      }
      if (close(tube[1])<0){
	perror("Erreur de fermeture du tube ordinaire");
	exit(11);
      }
    }
  }
  execv("maitre",vp); //recouvrement du processus père par l'exécutable maitre
  perror("Erreur de recouvrement du processus père par l'exécutable maitre");
  exit(12);
}












