/* Correction du TP de programmation système UNIX

   TP exécution de commandes en parallèle

   Question 2

   -
   Antoine Miné
   24/03/2007
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int n = 0; /* nombre de processus actifs */

void mon_wait()
{
  int status;
  /* boucle jusqu'à ce que wait réussisse */
  while (wait(&status) == -1) { 
    if (errno != EINTR) {
      /* vrai erreur */
      perror("wait"); 
      exit(1); 
    }
  }
  n--;
}

int main(int argc, char* argv[])
{
  int i; 
  int max; /* nom d'arguments maximum */

  if (argc < 4) { fprintf(stderr, "%s prog nb fichiers\n", argv[0]); return 1; }

  max = atoi( argv[2] );
  if ( max <=0 ) { fprintf(stderr, "il faut nb>0\n"); return 1; }

  /* lancement des processus */
  for ( i=3; i<argc; i++ ) {
    pid_t p;

    /* on s'assure qu'il y strictement moins de max fils actifs */
    while (n >= max) mon_wait();
    n++;

    p = fork();

    if ( p < 0 ) { perror("fork"); return 1; } /* erreur */

    if ( !p ) {
      /* fils */
      execlp( argv[1], argv[1], argv[i], NULL);
      
      /* on n'arrive ici que si execlp a échoué */
      fprintf( stderr, "echec de execlp(%s)\n", argv[1] );
      exit(1);
    }

  }

  /* attente de la terminaison des fils restants */
  while (n > 0) mon_wait();
  return 0;
}
