/* versione con N pipe di comunicazione/sincronizzazione fra padre e figli e altre N di comunicazione fra figli e padre; inoltre uso del segnale SIGKILL e del segnale SIGUSR1 */ #include #include #include #include #include #include #include #include typedef int pipe_t[2]; /* MESSO GLOBALE IN MODO DA POTERLO USARE NELLA FUNZIONE HANDLER, anche se la stampa e' solo di debugging */ int i; void handler(int signo) { printf("DEBUG: Sono il figlio %d di indice %d e ho finito di leggere il mio file\n", getpid(), i); exit(0); } int main (int argc, char **argv) { int N; /* numero di file */ int *pid; /* array di pid per fork: N.B. in questo caso serve un array di pid perche' il padre deve inviare il segnale SIGKILL per terminare forzatamente i figli per i quali il confronto non abbia avuto successo */ int *confronto; /* array dinamico di interi per sapere se si deve ancora mandare l'indicazione di leggere al figlio corrispondente */ pipe_t *pipeFiglioPadre; /* array di pipe di comunicazione fra figli e padre */ pipe_t *pipePadreFiglio; /* array di pipe di comunicazione/sincronizzazione fra padre e figlio. NOTA BENE: questa sincronizzazione potrebbe esser e fatta tramite l'invio di segnali da parte del padre ai figli */ int j; /* contatori */ int fd; /* file descriptor */ int pidFiglio, status, ritorno; /* per valore di ritorno figli */ char c,ch; /* carattere per leggere dal file da parte dei figli e dalle pipe da parte del padre*/ char token='v'; /* carattere che serve per sincronizzare i figli: IN QUESTA SOLUZIONE NON IMPORTA IL VALORE */ /* ci vogliono almeno due file per i figli che insieme con AF fa un totale di almeno 3 parametri */ if (argc < 4) { printf("Errore numero di parametri\n"); exit(1); } N = argc-2; /* calcoliamo il numero di file passati, a parte AF, e quindi il numero di figli da creare */ printf("DEBUG-Sono il padre %d e il numero di processi da creare sono %d\n", getpid(), N); /* allocazione pid */ if ((pid=(int *)malloc(N*sizeof(int))) == NULL) { printf("Errore allocazione pid\n"); exit(2); } /* allocazione confronto */ if ((confronto=(int *)malloc(N*sizeof(int))) == NULL) { printf("Errore allocazione confronto\n"); exit(3); } /* inizializzazione di confronto: tutti i valori a 1 perche' all'inizio si deve mandare l'indicazione al figlio di leggere! */ for (i=0;i> 8) & 0xFF); printf("Il figlio con pid=%d ha ritornato il valore %d (se 255 problemi)\n", pidFiglio, ritorno); for (j=0; j < N; j++) if (pid[j] == pidFiglio) /* se un figlio termina normalmente vuol dire che non e' stato ucciso dal SIGKILL */ printf("Questo significa che il figlio di indice %d ha verificato che il file %s e' uguale al file %s\n", j, argv[j+1], argv[argc-1]); } } exit(0); }