Talk:Main Page
Jump to navigation
Jump to search
Scrivere un programma che preso come parametro un file contenente un elenco di comandi (con I relativi parametri) li attivi tutti in esecuzione concorrente e rimanga in attesa. Quando il primo termina, vengono terminati (con segnale SIGTERM) tutti gli altri. (consiglio: puo' essere utile usare la mia libreria s2argv-execs) esempio: wta commands il file commands contiene: ./ttest 40 ./ttest 10 ./ttest 20 lo script ./ttest contiene: #!/bin/bash echo waiting for $1 seconds sleep $1 echo done $i l'ouptut sara': waiting for 40 seconds waiting for 10 seconds waiting for 20 seconds done 10 e poi basta perche' gli altri processi verranno terminati.
Possibile soluzione
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <s2argv.h> #include <sys/types.h> #include <signal.h> #define MAX 20 int contaRighe (FILE *A){ char *a; int i=0; a= malloc (MAX*sizeof(char)); if (a==NULL) { perror ("malloc"); return -1; } while (fgets(a, MAX, A)){ if (*a==EOF || *a=='\n') break; i++; } return i; } int main (int argc, char *argv []){ int status; int i=0; int j=0; int z=0; /*indice per ampiezza "pid_t ID" e "char *comando"*/ char *comando[z]; pid_t ID [z]; /* memorizza i pid di tutti i processi attivati */ pid_t terminato; /* memorizza il pid del primo processo che termina*/ FILE *fd = fopen (argv[1], "r"); if( fd==NULL ) { perror("Errore in apertura del file"); return -1; } j=contaRighe (fd); /*ritorna il numero di righe del file dato in input*/ z=j; /* setto gli array con il numero di righe del file contenente i comandi */ rewind(fd); /*ritorno all'inizio del file*/ /* riempie "comando[z]" con tutti i comandi presenti nel file passato, i comando sono contati da 1 a z. */ while (j!=0){ comando [i] = malloc (MAX*sizeof(char)); fgets(comando [i], MAX, fd); i++; j--; } i--; /* diminuisco "i" di uno perchè prima di uscire dall'ultimo ciclo è aumentata di uno, "j" è uguale a 0 */ /*ESEGUE TUTTI I COMANDI */ while (i>=0){ switch (ID[j]=fork()) { case 0: execsp(comando[j]); perror("exec"); case -1: perror ("fork"); return -1; } i--; j++; } i=0; /*setto "i" a 0 per il prossimo while */ terminato=wait(&status); /* TERMINA TUTTI I PROCESSI */ while(i<j){ /* "i" strettamente minore di "j" poichè nell'ultimo ciclo del precedente while viene incrementata di uno */ if (ID[i]!=terminato) { printf ("Termina processo %d\n",ID[i]); kill(ID[i], SIGTERM); /* mando segnale di terminazione a tutti i PID che non sono ancora terminati */ } else printf ("Processo completato %d\n",ID[i]); i++; } fclose (fd); return 0; }