/* soluzione parte C esame del 19 Giugno 2019: con calcolo del minimo codice ASCII */ #include #include #include #include #include #include #include #include typedef int pipe_t[2]; /* tipo di dato per contenere i file descriptors di una pipe */ /* VARIABILI GLOBALI */ int *finito; /* array dinamico per indicare i figli che sono terminati */ /* la semantica di questo array e' che ogni elemento vale 0 se il corrispondente processo NON e' finito, altrimenti vale 1 */ int N; /* numero di processi figli: deve essere una variabile globale perche' deve essere usata dalla funzione finitof */ int finitof() { /* questa funzione verifica i valori memorizzati nell'array finito: appena trova un elemento uguale a 0 vuole dire che non tutti i processi figli sono finiti e quindi torna 0; tornera' 1 se e solo se tutti gli elementi dell'array sono a 1 e quindi tutti i processi sono finiti */ 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) { int pid; /* variabile per fork */ pipe_t *pipe_fp; /* array di pipe per la comunicazione figli-padre*/ pipe_t *pipe_pf; /* array di pipe per l'indicazione padre-figli */ int fd; /* variabile per open */ char linea[250]; /* variabile per leggere le linee dai file (bastano 250 carattere, vedi testo) */ char ch; /* variabile per leggere i primi caratteri delle linee inviati dai figli */ char chMin; /* variabile per tenere traccia del carattere di codice ASCII minimo */ char chControllo; /* variabile per inviare indicazione ai figli */ int indice; /* usata dal padre per tenere traccia dell'indice del figlio che ha calcolato il minimo */ int stampe; /* numero di stampe fatte dai figli che va ritornato al padre */ int status, pidFiglio, ritorno; /* per wait */ int i, j; /* indici per cicli */ int nr, nw; /* per controlli read e write su/da pipe */ /* Controllo sul numero di parametri */ if (argc < 3) { printf("Errore numero parametri %d\n", argc); exit(1); } N = argc - 1; /* allocazione memoria dinamica per finito */ finito = (int *) malloc(sizeof(int) * N); if(finito == NULL) { printf("Errore nella allocazione della memoria per array finito\n"); exit(2); } /* ... e inizializzazione a 0: all'inizio nessun figlio e' finito */ memset(finito, 0, N*sizeof(int)); /* allocazione memoria dinamica per pipe_fp e pipe_pf */ pipe_fp=malloc(N*sizeof(pipe_t)); pipe_pf=malloc(N*sizeof(pipe_t)); if ((pipe_fp == NULL) || (pipe_pf == NULL)) { printf("Errore nelle malloc\n"); exit(3); } /* creazione delle pipe */ for (i=0; i < N; i++) { if (pipe(pipe_fp[i])!=0) { printf("Errore creazione delle pipe figli-padre\n"); exit(4); } if (pipe(pipe_pf[i])!=0) { printf("Errore creazione delle pipe padre-figli\n"); exit(5); } } /* creazione dei processi figli */ for (i=0; i < N; i++) { pid=fork(); if (pid < 0) /* errore */ { printf("Errore nella fork con indice %d\n", i); exit(6); } if (pid == 0) { /* codice del figlio */ /* stampa di debugging */ printf("Figlio di indice %d e pid %d associato al file %s\n",i,getpid(), argv[i+1]); /* chiudiamo le pipe che non servono */ /* ogni figlio scrive solo su pipe_fp[i] e legge solo da pipe_pf[i] */ for (j=0;j> 8) & 0xFF); printf("Il figlio con pid=%d ha ritornato %d (se 255 problemi)\n", pidFiglio, ritorno); } } exit(0); }/* fine del main */