Additions:
// se voglio che il gestore porti alla terminazione del processo:
// exit(EXIT_SUCCESS);
// se voglio che il gestore porti alla terminazione del processo:
// exit(EXIT_SUCCESS);
Additions:
// exit fa sempre flush dei buffer
Deletions:
// exit fa sempre flush dei buffer
Additions:
printf("AAAA"); // printf usa gli stream stdio e flush del buffer potrebbe non essere immediato se la stringa non contiene il carattere newline
// fflush(stdout); // provare a decommentare, forza il flushing dei buffer stdio
printf("BBBB"); // printf usa gli stream stdio e flush del buffer potrebbe non essere immediato se la stringa non contiene il carattere newline
exit(EXIT_SUCCESS); // provare a sostituire con _exit: exit fa flush, _exit non lo fa
// exit fa sempre flush dei buffer
Deletions:
printf("AAAA");
// fflush(stdout); // provare a decommentare
printf("BBBB");
exit(EXIT_SUCCESS); // provare a sostituire con _exit
Additions:
return EXIT_SUCCESS; // eseguita indirettamente: exit(EXIT_SUCCESS)
Additions:
if (res != 0) { // man atexit: The atexit() function returns the value 0 if successful; otherwise it returns a nonzero value.
Deletions:
if (res != 0) {
Additions:
int res = atexit(bye); // quando verra' invocata exit
Deletions:
int res = atexit(bye); // quanto verra' invocata exit
Additions:
printf("[genitore] x = %d, &x = %p \n", x, &x);
printf("[figlio] x = %d, &x = %p (prima)\n", x, &x);
printf("[figlio] x = %d, &x = %p (dopo)\n", x, &x);
printf("[genitore] x = %d, &x = %p \n", x, &x);
}%%
Deletions:
printf("[genitore] x = %d\n", x);
printf("[figlio] x = %d (prima)\n", x);
printf("[figlio] x = %d (dopo)\n", x);
printf("[genitore] x = %d\n", x);
Additions:
sa.sa_handler = SIG_IGN; // usare SIG_DFL per ripristinare l'handler di default
Deletions:
sa.sa_handler = SIG_IGN;
Additions:
printf("[figlio] x = %d (dopo)\n", x);
Deletions:
printf("[foglio] x = %d (dopo)\n", x);
Additions:
while(1);
while(1);
while(1);
Deletions:
while(1) sleep(1);
while(1) sleep(1);
while(1) sleep(1);
Additions:
while(1) sleep(1);
while(1) sleep(1);
while(1) sleep(1);
Deletions:
sleep(240);
sleep(240);
sleep(240);
Additions:
printf("figlio e' terminato\n");
_exit(EXIT_SUCCESS);
Deletions:
printf("Child e' terminato\n");
Additions:
printf("Genitore termina: sleep eseguita interamente per %d secondi\n", s);
Deletions:
printf("Genitore termina: sleep eseguita interamente per %d secondi\n", res);
Additions:
printf("Miracolo!\n"); // mai eseguito
=== Esempio: gestore segnale installato con ##sigaction##===
%%(c;sigaction-1.c)
struct sigaction sa = {0};
sa.sa_handler = myhandler;
int res = sigaction(SIGINT, &sa, NULL);
=== Esempio: ignorare un segnale (##sigaction##)===
%%(c;sigaction-2.c)
struct sigaction sa = {0};
sa.sa_handler = SIG_IGN;
int res = sigaction(SIGINT, &sa, NULL);
=== Esempio: gestore SIGCHLD, interruzione system call===
%%(c;sigaction-3.c)
printf("Child e' terminato\n");
struct sigaction sa = {0};
sa.sa_handler = myhandler;
int res = sigaction(SIGCHLD, &sa, NULL);
pid_t pid = fork();
int s = 30;
res = sleep(s); // genitore potrebbe fare qualcosa di piu' utile
// in questo esempio invoca una system call
if (res < s)
printf("Genitore termina: sleep terminata prematuramente dopo %d secondi\n", s - res);
else
printf("Genitore termina: sleep eseguita interamente per %d secondi\n", res);
Deletions:
printf("Miracolo!\n");
Additions:
=== Esempio: gestore segnale installato con ##signal##===
La funzione POSIX ##signal## รจ deprecata e non andrebbe usata.
%%(c;signal.c)
void myhandler(int signo) {
printf("Ricevuto segnale: %d\n", signo);
signal(SIGINT, myhandler);
sleep(240);
Additions:
=== Esempio invio segnale: uso funzione POSIX ##kill## ===
%%(c;kamikaze.c)
#include
#include
printf("kamikaze mode\n");
kill(getpid(), SIGKILL);
printf("Miracolo!\n");
return 0;
Additions:
Modificare la versione 3 implementando il comando interno ##mypwd##. Per ogni comando inserito dall'utente, se viene indicato il comando ##mypwd##, la shell deve eseguire una funzione interna che stampa in standard output il valore della variabile d'ambiente ##PWD##.
Deletions:
Modificare la versione 3 implementando il comando interno ##mypwd##. Per ogni comando inserito dall'utente, se viene indicato il comando ##mypwd## la shell deve eseguire una funzione interna che stampa in standard output il valore della variabile d'ambiente ##PWD##.
Additions:
== Versione 4 (esercizio per casa) ==
Modificare la versione 3 implementando il comando interno ##mypwd##. Per ogni comando inserito dall'utente, se viene indicato il comando ##mypwd## la shell deve eseguire una funzione interna che stampa in standard output il valore della variabile d'ambiente ##PWD##.
Additions:
Modificare la versione 2 in modo da ricevere il comando da eseguire attraverso lo stream di standard input, utilizzando la funzione ##scanf##. Alla terminazione del comando eseguito, la shell deve tornare a richiedere nuovamente un nuovo comando all'utente.
Deletions:
Modificare la versione 2 in modo da ricevere il comando da eseguire da standard input, utilizzando la funzione ##scanf##. Alla terminazione del comando eseguito, la shell deve tornare a richiedere nuovamente un nuovo comando all'utente.