/* Soluzione della Prova d'esame del 10 Giugno 2020 (versione alfabetici e minori uguali a 12) - Parte C */ #include #include #include #include #include #include #include #include #define PERM 0644 typedef int pipe_t[2]; int main(int argc, char **argv) { /* -------- Variabili locali ---------- */ int pid; /* process identifier per le fork() */ int Q; /* numero di file passati sulla riga di comando */ int pidFiglio, status; /* variabili per la wait */ pipe_t *p; /* array dinamico di pipe per la comunicazione fra figli e padre */ char linea[250]; /* array per linea, che come indicato nel testo, si puo' supporre di lunghezza 250 char compreso il terminatore di linea */ int fd; /* file descriptor che serve ai figli */ int fdw; /* file descriptor che serve al padre */ int q, k; /* indici per i cicli */ int ritorno=0; /* variabile che viene ritornata da ogni figlio al padre */ /* ------------------------------------ */ /* controllo parametri: almeno due file */ if (argc < 3) /* Meno di due parametri */ { printf("Errore nel numero dei parametri %d\n", argc); exit(1); } /* Calcoliamo il numero di file passati */ Q=argc-1; printf("Numero processi da creare %d\n", Q); /* allocazione dinamica memoria per pipe */ p=(pipe_t*)malloc(Q*sizeof(pipe_t)); if (p==NULL) { printf("Errore nelle malloc\n"); exit(3); } /* creazione pipe */ for (q=0; q < Q; q++) { if(pipe(p[q])!=0) { printf("Errore creazione delle pipe\n"); exit(4); } } /* creazione file prima di creare i figli */ fdw=creat("Camilla", PERM); if (fdw < 0) { printf("Errore creazione file Camilla\n"); exit(5); } /* creazione figli */ for (q=0; q < Q; q++) { if((pid=fork())<0) { printf("Errore nella fork %d-esima\n", q); exit(5); } if(pid==0) { printf("Figlio con indice %d e pid %d analizza file %s\n",q,getpid(),argv[q+1]); for (k=0; k < Q; k++) { /*chiudo i lati inutilizzati*/ close(p[k][0]); if (k != q) close(p[k][1]); } /* il figlio deve aprire il suo file in lettura */ if((fd=open(argv[q+1],O_RDONLY))<0) { printf("Errore apertura filei %s", argv[q+1]); exit(-1); /* decidiamo di tornare -1 che verra' interpretato dal padre come 255 e quindi un valore non ammissibile! */ } k=0; /* inizializziamo l'indice della linea */ while (read(fd,&(linea[k]),1)) { if (linea[k] == '\n') /* se siamo a fine linea */ { if (isalpha(linea[0]) && (k <= 12)) /* se il primo carattere della linea e' un carattere numerico e se la lunghezza delle linea, compreso il terminatore, e' strettamente minore di 10, dobbiamo mandare al padre */ { write(p[q][1],linea,k+1); ritorno++; /* dobbiamo incrementare il conteggio delle linee inviate al padre */ } k=0; /* dobbiamo resettare l'indice della linea per la lettura della prossima linea */ } else k++; /* se non siamo a fine linea, dobbiamo incrementare l'indice della linea */ } /* ritorno al padre */ exit(ritorno); } } /* codice del padre */ /* chiude lati che non usa */ for(q=0;q < Q; q++) close(p[q][1]); /* si legge dalle pipe tutte le linee per ogni figlio: nota bene che la lettura va fatta carattere per carattere fino allo '\n' pari poi da dispari, come specificato dal testo */ for(q=0; q < Q; q++) { k=0; /* inizializziamo l'indice della linea */ while (read(p[q][0],&(linea[k]),1)) { if (linea[k] == '\n') /* se siamo a fine linea */ { linea[k+1]='\0'; /* inseriamo il terminatore di stringa */ /* stampiamo quanto richiesto dal testo */ printf("Il figlio di indice %d ha trovato nel file %s la linea seguente\n%s che inizia con un carattere numerico e che ha una lunghezza, compreso il terminatore di linea, strettamente minore di 10\n", q, argv[q+1],linea); /* ora dobbiamo scriverla sul file, ma senza il terminatore di stringa */ write(fdw, linea, k+1); k=0; /* dobbiamo resettare l'indice della linea per la lettura della prossima linea */ } else k++; /* se non siamo a fine linea, dobbiamo incrementare l'indice della linea */ } } /* Attesa della terminazione dei figli */ for(q=0; q < Q; q++) { pidFiglio = wait(&status); if (pidFiglio < 0) { printf("Errore wait\n"); exit(6); } if ((status & 0xFF) != 0) printf("Figlio con pid %d terminato in modo anomalo\n", pidFiglio); 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", pidFiglio, ritorno); else printf("Il figlio con pid=%d ha ritornato %d\n", pidFiglio, ritorno); } } exit(0); }/* fine del main */