/* Soluzione della Prova d'esame del 28 Marzo 2008 - Parte C - soluzione con pipe e segnali */ #include #include #include #include #include #include #include #include typedef int pipe_t[2]; /* -------- Variabili globali ---------- */ int continua; /* variabile flag che dice se continuare a scrivere o no */ int *finito; /* array dinamico per indicare i figli che sono terminati */ int N; /* numero di file passati sulla riga di comando */ void continuaRicerca(int sig) { if(sig == SIGUSR1) continua = 1; else continua = 0; } int finitof() { int i; for (i=0; i < N; i++) if (!finito[i]) /* appena ne trova uno che non ha finito */ return 0; /* ritorna falso */ return 1; } int main(int argc, char **argv) { /* -------- Variabili locali ---------- */ int *pid; /* array dinamico di process identifier per le fork() */ char CZ; /* carattere passato sulla riga di comando */ int fdr; /* file descriptor per ciascun file */ int Y; /* numero intero passato sulla riga di comando */ int pidFiglio, status, ritorno; /* variabili per la wait */ pipe_t *piped; /* array dinamico di pipe descriptors */ int i, j; /* indici per i cicli */ int occ; /* numero di occorrenze del carattere CZ nei vari file*/ long int pos; /* posizione del carattere CZ in ogni file */ char ch; /* variabile per leggere i caratteri */ /* ------------------------------------ */ /* Controllo sul numero di parametri */ if(argc < 4) { printf("Errore nel numero dei parametri: almeno 3!\n"); exit(1); } /* Anche se non richiesti, facciamo il controllo sugli altri due parametri */ /* Controlliamo se il pienultimo parametro e' un singolo carattere */ if (strlen(argv[argc-2]) != 1) { printf("Errore primo parametro non singolo carattere %s\n", argv[1]); exit(2); } /* ricaviamo il carattere CZ */ CZ = argv[argc-2][0]; /* ricaviamo il numero Y */ Y = atoi(argv[argc-1]); /* Controlliamo il numero (deve essere strettamente positivo) */ if (Y <= 0) { printf("Y non valido\n"); exit(3); } N = argc - 3; /* allocazione dell'array dei flag finito[i] */ finito = (int *) malloc(sizeof(int) * N); if(finito == NULL) { printf("Errore nella allocazione della memoria\n"); exit(4); } /* ... e inizializzazione a 0 */ memset(finito, 0, N*sizeof(int)); /* Allocazione dell'array dei pid */ pid = (int *) malloc(sizeof(int) * N); if(pid == NULL) { printf("Errore nella allocazione della memoria\n"); exit(5); } /* Allocazione dell'array di N pipe descriptors*/ piped = (pipe_t *) malloc (N*sizeof(pipe_t)); if(piped == NULL) { printf("Errore nella allocazione della memoria\n"); exit(6); } /* installazione del gestore di segnali: lo fa il padre per i figli! */ signal(SIGUSR1, continuaRicerca); signal(SIGUSR2, continuaRicerca); /* Creazione delle N pipe padre-figli */ for(i=0; i0) { if(ch == CZ) /* occorrenza trovata */ { occ++; /* Ricaviamo la posizione corrente con lseek */ pos = lseek(fdr, 0L, SEEK_CUR); /* La read ha spostato l'IO pointer in avanti per la prossima lettura: decrementiamolo di 1, perche' consideriamo la posizione relativa allo 0 */ pos--; printf("Figlio %d: trovata occorrenza alla posizione %ld. Aspetto autorizzazione...\n", getpid(), pos); /* Comunica la posizione al padre */ write(piped[i][1], &pos, sizeof(long int)); /* Aspetta il segnale dal padre per poter continuare */ pause(); if (!continua) /* Il padre ha detto basta leggere.. interrompo il ciclo*/ { printf("Figlio %d: padre mi ha detto di interrompere\n", getpid()); break; } else printf("Figlio %d: padre mi ha detto di continuare \n", getpid()); } } /* Il figlio ritorna il numero di occorrenze trovate */ exit(occ-1); } } /* Codice del padre */ /* Chiusura lati pipes */ for(j=0; j> 8) & 0xFF); printf("Il figlio con pid=%d ha ritornato %d\n", pidFiglio, ritorno); } } exit(0); }