informatica:sol:laboratorio15:esercitazionia:scexamples
Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
| Prossima revisione | Revisione precedente | ||
| informatica:sol:laboratorio15:esercitazionia:scexamples [26/04/2015 alle 09:21 (11 anni fa)] – creata Massimo Torquati | informatica:sol:laboratorio15:esercitazionia:scexamples [26/04/2015 alle 13:34 (11 anni fa)] (versione attuale) – [command.c (chiamate: fork, wait, getpid, execvp)] Massimo Torquati | ||
|---|---|---|---|
| Linea 1: | Linea 1: | ||
| ===== Alcuni esempi di semplici programmi C con processi e pipe ===== | ===== Alcuni esempi di semplici programmi C con processi e pipe ===== | ||
| - | ==== nproc.c ==== | + | ==== nproc.c |
| - | Si creano | + | Si creano |
| < | < | ||
| Linea 70: | Linea 70: | ||
| sleep(1); | sleep(1); | ||
| } | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== command.c (chiamate: fork, wait, getpid, execvp) ==== | ||
| + | |||
| + | Programma che prende come argomento un programma eseguibile ed i suoi eventuali argomenti e lancia il programma attendendone la terminazione. | ||
| + | < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // utility macro | ||
| + | #define SYSCALL(r, | ||
| + | if((r=c)==-1) { perror(e); | ||
| + | |||
| + | int main(int argc, char *argv[]) { | ||
| + | if (argc == 1) { | ||
| + | fprintf(stderr, | ||
| + | return EXIT_FAILURE; | ||
| + | } | ||
| + | | ||
| + | int pid; | ||
| + | SYSCALL(pid, | ||
| + | | ||
| + | if(pid == 0) { // figlio | ||
| + | int r; | ||
| + | execvp(argv[1],& | ||
| + | perror(" | ||
| + | return errno; | ||
| + | } | ||
| + | int status; | ||
| + | SYSCALL(pid, | ||
| + | printf(" | ||
| + | if(WIFEXITED(status)) | ||
| + | else printf(" | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== zombie.c (chiamate: fork, waitpid, getpid, execlp) ==== | ||
| + | |||
| + | Il seguente programma crea un numero di processi '' | ||
| + | |||
| + | < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // utility macro | ||
| + | #define SYSCALL(r, | ||
| + | if((r=c)==-1) { perror(e); | ||
| + | |||
| + | int main(int argc, char * argv[]) { | ||
| + | const int SEC=2; | ||
| + | |||
| + | if (argc != 2) { | ||
| + | fprintf(stderr, | ||
| + | return EXIT_FAILURE; | ||
| + | } | ||
| + | | ||
| + | int nproc = atoi(argv[1]); | ||
| + | int pid; | ||
| + | for(int i=0; | ||
| + | SYSCALL(pid, | ||
| + | if(pid==0) { // figlio | ||
| + | sleep(SEC); | ||
| + | exit(0); // esco con successo | ||
| + | } else | ||
| + | printf(" | ||
| + | } | ||
| + | | ||
| + | // solo il processo padre arriva qui | ||
| + | |||
| + | // aspettiamo un po' in modo da essere " | ||
| + | // che i processi figli siano terminati | ||
| + | sleep(2*SEC); | ||
| + | |||
| + | printf(" | ||
| + | SYSCALL(pid, | ||
| + | if(pid==0) { | ||
| + | execlp(" | ||
| + | perror(" | ||
| + | exit(errno); | ||
| + | } else { | ||
| + | int stato; | ||
| + | printf(" | ||
| + | SYSCALL(pid, | ||
| + | printf(" | ||
| + | } | ||
| + | |||
| + | // adesso attendiamo la terminazione dei processi | ||
| + | for(int i=0; | ||
| + | int stato; | ||
| + | SYSCALL(pid, | ||
| + | if(WIFEXITED(stato)) | ||
| + | printf(" | ||
| + | | ||
| + | } | ||
| + | printf(" | ||
| + | SYSCALL(pid, | ||
| + | if(pid==0) { | ||
| + | execlp(" | ||
| + | perror(" | ||
| + | exit(0); | ||
| + | } else { | ||
| + | int stato; | ||
| + | SYSCALL(pid, | ||
| + | " | ||
| + | } | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== pipe2proc.c (chiamate: fork, wait, getpid, write, pipe, dup, execve) ==== | ||
| + | |||
| + | Il programma crea un processo figlio che esegue il comando '' | ||
| + | Il programma produce in output l' | ||
| + | < | ||
| + | echo "Ciao mondo ! Passo e chiudo ..." | tr ' ' ' | ||
| + | </ | ||
| + | |||
| + | |||
| + | < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // utility macro | ||
| + | #define SYSCALL(r, | ||
| + | if((r=c)==-1) { perror(e); | ||
| + | |||
| + | |||
| + | int main(int argc, char *argv[]) { | ||
| + | int canale[2]; | ||
| + | |||
| + | int r; | ||
| + | SYSCALL(r, pipe(canale), | ||
| + | |||
| + | if (fork() != 0) { // padre | ||
| + | close(1); | ||
| + | SYSCALL(r, | ||
| + | |||
| + | // chiudo tutti i descrittori che non uso | ||
| + | close(canale[1]); | ||
| + | close(canale[0]); | ||
| + | } else { // figlio | ||
| + | close(0); | ||
| + | SYSCALL(r, dup(canale[0]), | ||
| + | |||
| + | // chiudo tutti i descrittori che non uso prima di chiamare la exec | ||
| + | close(canale[1]); | ||
| + | close(canale[0]); | ||
| + | |||
| + | // utilizzo la chiamata di sistema execve specificando le | ||
| + | // variabili di ambente del processo sort | ||
| + | char *path = getenv(" | ||
| + | char envpath[strlen(" | ||
| + | char envlcall[] = " | ||
| + | snprintf(envpath, | ||
| + | char *envp[] = { envpath, envlcall, NULL}; | ||
| + | char *cmd[] | ||
| + | |||
| + | execve(cmd[0], | ||
| + | perror(" | ||
| + | exit(errno); | ||
| + | } | ||
| + | |||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | SYSCALL(r, write(1, " | ||
| + | | ||
| + | // chiudo l' | ||
| + | close(1); | ||
| + | |||
| + | // attendo la terminazione del processo figlio | ||
| + | int status; | ||
| + | SYSCALL(r, wait(& | ||
| + | return 0; | ||
| } | } | ||
| </ | </ | ||
informatica/sol/laboratorio15/esercitazionia/scexamples.1430040068.txt.gz · Ultima modifica: 26/04/2015 alle 09:21 (11 anni fa) da Massimo Torquati
