#include #include #include #include #include #include /* versione con 1 pipe e uso di una struttura */ int main(int argc, char *argv[]) { int pid; /* pid per fork */ int N; /* numero di caratteri e quindi numero di processi */ int fdr; /* per open */ int i; /* indice */ char c; /* per leggere dal file */ int p[2]; /* singola pipe */ int pidFiglio, status, ritorno; /* variabili per wait*/ /* struttura per la comunicazione tra figli e padre */ struct { int n; /* numero di occorrenze del carattere */ char c; /* carattere controllato */ } msg; if (argc < 3) { printf("Errore nel numero dei parametri\n"); exit(1); } /* numero dei caratteri passati sulla linea di comando */ N = argc - 2; /* controllo singoli caratteri */ for (i=0; i < N; i++) if (strlen(argv[i+2]) != 1) { printf("Errore nella stringa %s che non e' un singolo carattere\n", argv[i+2]); exit(1); } /* creo la pipe */ if (pipe(p) < 0) { printf("Errore nella creazione della pipe\n"); exit(1); } printf("Sono il processo padre con pid %d e sto per generare %d figli\n", getpid(), N); for (i=0; i < N; i++) { /* creazione dei figli */ if ((pid = fork()) < 0) { printf ("Errore nella fork\n"); exit(1); } if (pid == 0) /* figlio */ { printf("Figlio %d con pid %d\n", i, getpid()); /* chiude il lato della pipe che non usa */ close(p[0]); /* apre il file */ if ((fdr = open(argv[1], O_RDONLY)) < 0) { printf("Errore nella apertura del file %s\n", argv[1]); exit(-1); } /* inizializza la struttura */ msg.c = argv[i+2][0]; msg.n = 0; /* conta le occorrenze del carattere assegnato */ while(read(fdr, &c, 1) > 0) { if (c == argv[i+2][0]) msg.n++; } /* comunica al padre */ write(p[1], &msg, sizeof(msg)); exit(0); } } /* padre */ /* chiude il lato della pipe che non usa */ close(p[1]); /* legge dalla pipe i messaggi */ while (read(p[0], &msg, sizeof(msg)) > 0) printf("%d occorrenze del carattere %c nel file %s\n", msg.n, msg.c, argv[1]); /* Attesa della terminazione dei figli */ for(i=0;i < N;i++) { pidFiglio = wait(&status); if (pidFiglio < 0) { printf("Errore wait\n"); exit(9); } if ((status & 0xFF) != 0) printf("Figlio con pid %d terminato in modo anomalo\n", pidFiglio); else { ritorno=(int)((status >> 8) & 0xFF); printf("Il figlio con pid=%d ha ritornato %d (se 255 problemi)\n", pidFiglio, ritorno); } } exit(0); }