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.
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'?
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?
Scrivere un programma C in cui il padre scrive Sei piccoli sullo stdout e poi forka 6 figli:
pid1, esegue il comando /bin/sleep, con agomento 300 e poi esegue una printf della stringa indiani;pid2,esegue il comando /bin/echo con argomento indiani;pid3 esegue il comando /bin/kill, con argomento pid1;pid4, esegue una printf della stringa indiani e poi valuta l'espressione (*0);pid5, esegue una printf della stringa indiani e poi valuta l'espressione (a=1/2,b=5/a);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.
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..)
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.