TP #3 de systèmes : utilisation de fork et des tubes

Je vous le concède, ce TP n'a rien d'évident. Toutefois, le code qui suit est suffisament documenté pour que vous puissiez vous repérer sans problème.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


/* Une ligne lue au clavier est transformee en tableaux de chaines elementaires
   pour pouvoir etre utilisee, par exemple, par les commandes execv[pe] */

int ligneCommande(char *ligneLue, char **rep)
{
  int   compteur=0;
  char *retour;
  
  retour=strtok(ligneLue," ");
  rep[0]=(char *)malloc(strlen(retour)+1);
  strcpy(rep[0],retour);

  do
  {
    retour=strtok((char *)0," ");
    if (retour)
    {
      rep[++compteur]=(char *)malloc(strlen(retour)+1);
      strcpy(rep[compteur],retour);
    }
  } while (retour);

  rep[++compteur]=0;

  return compteur;
}

int invocation(char **commandes)
{
  return execvp(commandes[0],commandes);
}

int main(int argc, char *argv[])
{
  int   retour;
  int   longueur;

  char  commande[256];
  int   lePid;
  int   tuyau[2];

  char *com1[25];
  char *com2[25];


	 /* Saisie de la première commande*/
  printf("Tappez la première commande ");
  fgets(commande,255,stdin);
  /* Suppression du caractère saut de ligne à la fin de la ligne */
  longueur=strlen(commande);
  commande[longueur-1]=0;
  /* Decoupage de la ligne de commande */
  ligneCommande(commande,com1);

	 /* Saisie de la première commande*/
  printf("Tappez la seconde commande ");
  fgets(commande,255,stdin);
  /* Suppression du caractère saut de ligne à la fin de la ligne */
  longueur=strlen(commande);
  commande[longueur-1]=0;
  /* Decoupage de la ligne de commande */
  ligneCommande(commande,com2);

  /* Vidage des buffers */
  fflush(stdin);
  fflush(stdout);

  pipe(tuyau);

  switch (lePid=fork())
  {
    case -1:
      puts("Echec de fork, adieu");
      fflush(stdout);
      exit(1);
    case 0:
      /* On est dans le fils : execution de la premiere commande */
      /* Cloture du descripteur associe a la sortie standard */
      close(STDOUT_FILENO); 
      /* Duplication du descripteur tuyau[1] */
      /* Le descripteur disponible est STDOUT_FILENO */
      /* D'ou => STDOUT_FILENO est maintenant associe au tube en ecriture */
      dup(tuyau[1]);
      /* On peut fermer ce descripteur comme l'on va utiliser STDOUT_FILENO */
      close(tuyau[1]);
      /* On n'oublie pas de fermer le tube en lecture pour eviter les DEADLOCK*/
      close(tuyau[0]);
      invocation(com1);
      exit(1);
    default:
      /* On est dans le pere : execution de la deuxieme commande */
      /* Cloture du descripteur associe a l'entree standard */
      close(STDIN_FILENO);
      /* Duplication du descripteur tuyau[0] */
      /* Le descripteur disponible est STDIN_FILENO */
      dup(tuyau[0]);
      /* On peut fermer le descripteur tuyau[0] car l'on va utiliser STDIN_FILENO */
      close(tuyau[0]);
      /* On n'oublie pas de fermer le tube en ecriture pour eviter les DEADLOCK */
      close(tuyau[1]);
      invocation(com2);
      exit(1);
  }
  

  return 0; 
}