/* FILE: shellpipe.c */ #include #include #include #include #include int join (char *com1[], char *com2[]) { int status, exit_s; int pid; int piped[2]; /* processo P1 */ /* creazione del figlio per eseguire il comando in pipe */ switch (fork ()) { case -1: /* errore */ return 1; case 0: /* figlio ===> processo P2 */ break; default: /* padre P1: attende il figlio P2 */ if ((pid=wait(&status)) < 0) { printf("Errore in wait\n"); return 2; } printf("Terminato figlio con PID = %d\n", pid); if ((status & 0xFF) != 0) printf("Figlio terminato in modo involontario\n"); else { exit_s = status >> 8; /* selezione degli 8 bit piu' significativi */ exit_s &= 0xFF; printf("Per il figlio %d lo stato di EXIT e` %d\n", pid, exit_s); return exit_s; } } /* il figlio P2 esegue il comando intero: crea la pipe */ if (pipe (piped) < 0 ) { return 3; } /* CREAZIONE di un nuovo FIGLIO: processo P3 */ if ((pid = fork()) < 0) { return 4; } else if (pid != 0) /* processo P2 (padre di P3) */ { close(0); /* input dalla pipe */ dup(piped[0]); close(piped[0]); close(piped[1]); execvp(com2[0], com2); return 5; /* errore in caso si ritorni qui */ } else /* P3: figlio del FIGLIO P2 */ { close(1); /* output sulla pipe */ dup(piped[1]); close(piped[0]); close(piped[1]); execvp(com1[0], com1); return 6; /* errore in caso si ritorni qui */ } } int main (int argc, char **argv) {int integi, j, i; char *temp1[10], *temp2[10]; /* si devono fornire nella linea comandi due comandi distinti, separati dal carattere !. Non si usa direttamente il |, perche` questo viene direttamente interpretato dallo shell come una pipe */ if (argc > 3) { for (i=1; i < argc && strcmp (argv[i], "!"); i++) temp1[i-1] = argv[i]; temp1[i-1] = (char *)0; i++; for (j = 1; i < argc ; i++, j++) temp2[j-1] = argv[i]; temp2[j-1] = (char *)0; /* terminatore */ } else { printf("Errore numero di parametri insufficiente\n"); exit(7); } integi = join(temp1, temp2); exit(integi); }