/* Soluzione della parte C del compito dell'8 Giugno 2011 */ #include #include #include #include #include #include #include #include typedef int pipe_t[2]; typedef struct{ char Cx; /* carattere C1 o C2 del testo */ long int pos; /* posizione corrente del carattere nel file */ } s_pos; int main (int argc, char **argv) { int N; /* numero di file */ int pid; /* per fork */ pipe_t *pipes; /* array di pipe usate a per la comunicazione fra nipoti e padre */ pipe_t p; /* pipe usata fra figlio e nipote */ int i,j; /* contatori */ int fd; /* file descriptor */ int status, ritorno; /* per valore di ritorno figli */ char C1,C2, ch; /* caratteri da cercare e carattere letto da linea */ s_pos curF, curN; /* strutture usate dal figlio e dal nipote */ int occ; /* numero di occorrenze usato sia da figli che da nipoti */ int nr; /* variabile per salvare valore di ritorno di read su pipe */ /* controllo sul numero di parametri almeno 2 file (anche se non richiesto) e due caratteri */ if (argc < 5) { printf("Errore numero di parametri\n"); exit(1); } /* controlliamo che il penultimo parametro e l'ultimo parametro siano singoli caratteri */ if (strlen(argv[argc-2]) != 1 || strlen(argv[argc-1]) != 1) { printf("Errore penultimo o ultimo parametro non singolo carattere\n"); exit(2); } /* individuiamo i caratteri da cercare */ C1 = argv[argc-2][0]; C2 = argv[argc-1][0]; /* stampa di debugging */ printf("Caratteri da cercare %c e %c\n", C1, C2); N = argc-3; printf("Numero di processi da creare %d\n", N); /* allocazione pipe */ if ((pipes=(pipe_t *)malloc(N*sizeof(pipe_t))) == NULL) { printf("Errore allocazione pipe\n"); exit(3); } /* creazione pipe */ for (i=0;i= curN.pos) { /* se la posizione e' maggiore o uguale, al padre dobbiamo mandare le informazioni del nipote */ curF.Cx = curN.Cx; curF.pos = curN.pos; } /* si deve mandare l'informazione al padre */ write(pipes[i][1], &curF, sizeof(curF)); /* incrementiamo numero di occorrenze che andra' ritornato al padre */ occ++; } else break; /* decidiamo di uscire dal ciclo while */ } else ; /* non si deve fare nulla */ } /* il figlio deve aspettare il nipote e stampare il suo pid con il valore ritornato (come richiesto dal testo) */ pid = wait(&status); if (pid < 0) { printf("Errore in wait\n"); exit(-1); } if ((status & 0xFF) != 0) { printf("Nipote con pid %d terminato in modo anomalo\n", pid); exit(-1); } else printf("Il nipote con pid=%d ha ritornato %d\n", pid, ritorno=(int)((status >> 8) & 0xFF)); exit(occ); /* torniamo il valore richiesto dal testo che ci indica che sara' minore di 255 */ } } } /* Codice del padre */ /* Il padre chiude i lati delle pipe che non usa */ for (i=0; i < N; i++) { close(pipes[i][1]); } /* Il padre recupera le informazioni dai figli in ordine di indice */ for (i=0; i < N; i++) { /* si devono recuperare tutte le infomazione inviate da ogni figlio */ while (read(pipes[i][0], &curF, sizeof(curF))) { if (curF.Cx == C1) printf("Il figlio di indice %d ha trovato il carattere %c nella posizione %ld nel file %s\n", i, curF.Cx, curF.pos, argv[i+1]); else printf("Il nipote del figlio di indice %d ha trovato il carattere %c nella posizione %ld nel file %s\n", i, curF.Cx, curF.pos, argv[i+1]); } } /* Il padre aspetta i figli */ for (i=0; i < N; i++) { pid = wait(&status); if (pid < 0) { printf("Errore in wait\n"); exit(6); } if ((status & 0xFF) != 0) printf("Figlio con pid %d terminato in modo anomalo\n", pid); else { ritorno=(int)((status >> 8) & 0xFF); if (ritorno==255) printf("Il figlio con pid=%d ha ritornato %d e quindi vuole dire che ci sono stati dei problemi\n", pid, ritorno); else printf("Il figlio con pid=%d ha ritornato %d\n", pid, ritorno); } } exit(0); }