====== Esercitazione 5 ======
Questa esercitazione e' relativa alle system call per la gestione dei processi.
Per eseguire un comando usare le funzioni della famiglia ''exec'' ed (eventualmente) una ''fork''.
====== Esercizio 0: Sulle volpi ======
Cosa stampa il seguente main?
int main (void) {
printf("The quick brown fox jumped over ");
fork();
printf("the lazy dogs\n");
return 0;
}
e questo?
int main (void) {
printf("The quick brown fox jumped over ");
execl("/bin/echo","echo","the","lazy","dogs.",NULL);
return 0;
}
perche'?
====== Esercizio 1: N-esimo nipote ======
Scrivere un programma C che prenda un numero //N>1// dalla riga di comando e che crei //N// discendenti come segue: prima forka un figlio, il quale a sua volta forka un altro figlio e cosi' via fino ad ottenere //N// processi in tutto. Ogni processo appena attivato stampa il suo PID ed il PID del padre e termina. In che ordine avvengono le stampe?
Modificare il programma in modo che ogni processo, prima di terminare, attenda la terminazione del proprio figlio e stampi (oltre al suo PID e a PPID come prima) il PID del figlio ed il tipo di terminazione avvenuta (exited, killed etc...) ed eventualmente l'exit status o il segnale ricevuto. Cosa viene stampato?
Infine, modificare il programma in modo che ogni figlio, prima di uscire attenda anche la terminazione del proprio padre. Cosa accade?
====== Esercizio 2: Sei piccoli indiani ======
Scrivere un programma C in cui il padre scrive ''Sei piccoli'' sullo stdout e poi forka 6 figli:
* il primo figlio, di identificatore ''pid1'', esegue il comando ''/bin/sleep'', con agomento ''300'' e poi esegue una ''printf'' della stringa ''indiani'';
* il secondo figlio, di identificatore ''pid2'',esegue il comando ''/bin/echo'' con argomento ''indiani'';
* il terzo figlio, di identificatore ''pid3'' esegue il comando ''/bin/kill'', con argomento ''pid1'';
* il quarto figlio, di identificatore ''pid4'', esegue una ''printf'' della stringa ''indiani'' e poi valuta l'espressione (*0);
* il quinto figlio, di identificatore ''pid5'', esegue una ''printf'' della stringa ''indiani'' e poi valuta l'espressione (a=1/2,b=5/a);
* il sesto figlio, di identificatore ''pid6'', esegue una ''printf'' della stringa ''indiani'' ed esegue "exit(12)".
Quanti indiani arrivano sullo stdout? Perche? Cosa e' successo agli altri?
\\
Per eseguire i comandi usare esclusivamente le funzioni della famiglia "exec" ed eventualmente la fork.
====== Esercizio 3: dummyshell ======
Realizzare una shell rudimentale che legge un comando con eventuali parametri dallo standard input e ne invoca l'esecuzione utilizzando una funzione della famiglia //exec()//. La shell deve terminare se viene digitato il comando 'exit' e deve fornire nel prompt il numero progressivo del comando che stiamo per eseguire (dalla attivazione) e lo stato con cui รจ terminato il comando precedente. Ad esempio :
bash:~$ dummyshell
Welcome in dummyshell!!
1@dummy:stato= 0$ llls pippo
Nella execvp: No such file or directory
2@dummy:stato=29$ ls pippo
ls: pippo: No such file or directory
2@dummy:stato= 1$ ls pippo.c
pippo.c
4@dummy:stato= 0$ exit
Leaving dummyshell ...
bash:~$
Il formato dei comandi e' molto semplice e non prevede metacaratteri o forme di ridirezione.
\\
Estensione: Dare piu' informazioni sulla terminazione (Exited, Signaled etc..)
====== Esercizio 4: Esecuzione in background ======
Scrivere un programma C che appena attivato va immediatamente in background, attende per 2 secondi (con sleep) e poi stampa il pid ed il pid del padre.