Rimaneggiamenti generali
[gapil.git] / signal.tex
index 95974f3b9577ab899c08bee02ffc1b160e498fa8..1375a973649190628d95fe6a4cce2d8f48c9e411 100644 (file)
@@ -22,9 +22,10 @@ gestione.
 \section{Introduzione}
 \label{sec:sig_intro}
 
-In questa sezione esamineremo i concetti base dei segnali, introducendo le
-caratteristiche essenziali con cui il sistema interagisce con i processi
-attraverso di essi.
+In questa sezione esamineremo i concetti generali relativi ai segnali, vedremo
+le loro caratteristiche di base, introdurremo le nozioni di fondo relative
+all'architettura del funzionamento dei segnali e alle modalità con cui il
+sistema gestisce l'interazione fra di essi ed i processi.
 
 
 \subsection{I concetti base}
@@ -80,7 +81,7 @@ gestione, in tutti i casi in cui si vuole che il manipolatore esterno resti
 attivo.
 
 In questo caso è possibile una situazione in cui i segnali possono essere
-perduti; si consideri il seguente segmento di codice in cui la prima
+perduti. Si consideri il seguente segmento di codice, in cui la prima
 operazione del manipolatore è quella di reinstallare se stesso: 
 
 \footnotesize
@@ -103,7 +104,7 @@ causare il comportamento originale assegnato al segnale (in genere la
 terminazione del processo).
 
 Questa è la ragione per cui l'implementazione dei segnali secondo questa
-semantica viene chiamata \textsl{inaffidabile}, in quanto la ricezione del
+semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
 segnale e la reinstallazione del suo manipolatore non sono operazioni
 atomiche, e sono sempre possibili delle race condition (sull'argomento vedi
 quanto detto in \secref{sec:proc_multi_prog}).
@@ -113,54 +114,54 @@ segnali quando non si vuole che arrivino; i processi possono ignorare il
 segnale, ma non è possibile istruire il sistema a non fare nulla in occasione
 di un segnale, pur mantenendo memoria del fatto che è avvenuto.
 
-Un caso classico in cui si incontra questo problema, è quello in cui si usa il
-manipolatore per settare un flag che riporta al processo l'occorrenza del
-segnale, così che questo possa prendere provvedimenti al di fuori del
-manipolatore. Si consideri il seguente segmento di codice il cui scopo sarebbe
-quello di fermare il processo fino all'occorrenza di un opportuno segnale:
-
-\footnotesize
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-int signal_flag = 0;
-main()
-{
-    int sig_handler();            /* handler function */
-    ...
-    signal(SIGINT, sig_handler);  /* establish handler */
-    ...
-    while(signal_flag == 0) {     /* while flag is zero */
-        pause();                  /* go to sleep */
-    }
-    ... 
-}
-int sig_handler() 
-{
-    signal(SIGINT, sig_handler);  /* restablish handler */
-    signal_flag = 1;              /* set flag */
-}
-\end{lstlisting}
-\normalsize
-l'idea è che quando il processo trova il flag a zero viene messo in sleep e
-verrà risvegliato solo dalla ricezione di un segnale. Il manipolatore si
-limita in questo caso a settare il flag a uno; all'uscita dal manipolatore la
-chiamata a \func{pause} è interrotta ed il processo viene risvegliato e
-riprende l'esecuzione all'istruzione successiva, ma essendo cambiato il flag
-la condizione non è più soddisfatta e il programma prosegue.
-
-Il problema con l'implementazione inaffidabile è che niente ci garantisce che
-il segnale arrivi fra la valutazione della condizione del \code{while} e la
-chiamata a \func{pause}, nel qual caso, se il segnale non viene più generato,
-il processo resterà in sleep permanentemente.
-
-% Un'altra caratteristica della implementazione inaffidabile è che le chiamate
-% di sistema non sono fatte ripartire automaticamente quando sono interrotte da
-% un segnale, per questo un programma deve controllare lo stato di uscita della
-% chiamata al sistema e ripeterla nel caso l'errore riportato da \texttt{errno}
-% sia \texttt{EINTR}.
-
-Questo ci mostra ad esempio come con la semantica inaffidabile non esista una
-modalità semplice per ottenere una operazione di pausa (cioè mandare in sleep
-un processo fino all'arrivo di un segnale).
+Un caso classico in cui si incontra questo problema, è quello in cui si usa il
+manipolatore per settare un flag che riporta al processo l'occorrenza del
+segnale, così che questo possa prendere provvedimenti al di fuori del
+manipolatore. Si consideri il seguente segmento di codice il cui scopo sarebbe
+quello di fermare il processo fino all'occorrenza di un opportuno segnale:
+
+\footnotesize
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+int signal_flag = 0;
+main()
+{
+    int sig_handler();            /* handler function */
+    ...
+    signal(SIGINT, sig_handler);  /* establish handler */
+    ...
+    while(signal_flag == 0) {     /* while flag is zero */
+        pause();                  /* go to sleep */
+    }
+    ... 
+}
+int sig_handler() 
+{
+    signal(SIGINT, sig_handler);  /* restablish handler */
+    signal_flag = 1;              /* set flag */
+}
+\end{lstlisting}
+\normalsize
+l'idea è che quando il processo trova il flag a zero viene messo in sleep e
+verrà risvegliato solo dalla ricezione di un segnale. Il manipolatore si
+limita in questo caso a settare il flag a uno; all'uscita dal manipolatore la
+chiamata a \func{pause} è interrotta ed il processo viene risvegliato e
+riprende l'esecuzione all'istruzione successiva, ma essendo cambiato il flag
+la condizione non è più soddisfatta e il programma prosegue.
+
+Il problema con l'implementazione inaffidabile è che niente ci garantisce che
+il segnale arrivi fra la valutazione della condizione del \code{while} e la
+chiamata a \func{pause}, nel qual caso, se il segnale non viene più generato,
+il processo resterà in sleep permanentemente.
+
+% Un'altra caratteristica della implementazione inaffidabile è che le chiamate
+% di sistema non sono fatte ripartire automaticamente quando sono interrotte da
+% un segnale, per questo un programma deve controllare lo stato di uscita della
+% chiamata al sistema e ripeterla nel caso l'errore riportato da \texttt{errno}
+% sia \texttt{EINTR}.
+
+Questo ci mostra ad esempio come con la semantica inaffidabile non esista una
+% modalità semplice per ottenere una operazione di attesa mandando in stato di
+% sleep (vedi \ref{sec:proc_sched}) un processo fino all'arrivo di un segnale.
 
 Nella semantica \textsl{affidabile} (quella utilizzata da Linux e da ogni Unix
 moderno) il manipolatore una volta installato resta attivo e non si hanno
@@ -274,9 +275,9 @@ una  delle tre possibilit
 
 Un programma può specificare queste scelte usando le due funzioni
 \func{signal} e \func{sigaction} (vedi \secref{sec:sig_signal} e
-\secref{sec:sig_sigaction}); se si è installato un manipolatore sarà
+\secref{sec:sig_sigaction}). Se si è installato un manipolatore sarà
 quest'ultimo ad essere eseguito alla notifica del segnale.  Inoltre il sistema
-fa si che mentre viene eseguito il manipolatore di un segnale, questo ultimo
+farà si che mentre viene eseguito il manipolatore di un segnale, quest'ultimo
 venga automaticamente bloccato (così si possono evitare race condition).
 
 Nel caso non sia stata specificata un'azione, viene utilizzata l'azione
@@ -298,7 +299,6 @@ in seguito con un debugger per investigare sulla causa dell'errore.  Lo stesso
 avviene se i suddetti segnale vengono generati con una \func{kill}.
 
 
-
 \section{La classificazione dei segnali}
 \label{sec:sig_classification}
 
@@ -314,62 +314,6 @@ Ciascun segnale 
 diretto di questo numero da parte dei programmi è da evitare, in quanto esso
 può variare a seconda dell'implementazione del sistema, e nel caso si Linux,
 anche a seconda dell'architettura hardware. 
-
-\begin{table}[htb]
-  \footnotesize
-  \centering
-  \begin{tabular}[c]{|l|c|c|p{8cm}|}
-    \hline
-    \textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\
-    \hline
-    \hline
-    \macro{SIGHUP}   &PL & A & Hangup o fine del processo di controllo      \\
-    \macro{SIGINT}   &PL & A & Interrupt da tastiera (\cmd{C-c})            \\
-    \macro{SIGQUIT}  &PL & C & Quit da tastiera (\cmd{C-y})                 \\
-    \macro{SIGILL}   &PL & C & Istruzione illegale                          \\
-    \macro{SIGABRT}  &PL & C & Segnale di abort da \func{abort}             \\
-    \macro{SIGFPE}   &PL & C & Errore aritmetico                            \\
-    \macro{SIGKILL}  &PL &AEF& Segnale di terminazione forzata              \\
-    \macro{SIGSEGV}  &PL & C & Errore di accesso in memoria                 \\
-    \macro{SIGPIPE}  &PL & A & Pipe spezzata                                \\
-    \macro{SIGALRM}  &PL & A & Segnale del timer da \func{alarm}             \\
-    \macro{SIGTERM}  &PL & A & Segnale di terminazione \verb|C-\|            \\
-    \macro{SIGUSR1}  &PL & A & Segnale utente numero 1                       \\
-    \macro{SIGUSR2}  &PL & A & Segnale utente numero 2                       \\
-    \macro{SIGCHLD}  &PL & B & Figlio terminato o fermato                    \\
-    \macro{SIGCONT}  &PL &   & Continua se fermato                           \\
-    \macro{SIGSTOP}  &PL &DEF& Ferma il processo                             \\
-    \macro{SIGTSTP}  &PL & D & Stop typed at tty                             \\
-    \macro{SIGTTIN}  &PL & D & Input sul terminale per un processo 
-                               in background                                 \\
-    \macro{SIGTTOU}  &PL & D & Output sul terminale per un processo          
-                               in background                                 \\
-    \macro{SIGBUS}   &SL & C & Errore sul bus (bad memory access)            \\
-    \macro{SIGPOLL}  &SL & A & Pollable event (Sys V).                      
-                               Sinonimo di \macro{SIGIO}                     \\
-    \macro{SIGPROF}  &SL & A & Timer del profiling scaduto                   \\
-    \macro{SIGSYS}   &SL & C & Bad argument to routine (SVID)                \\
-    \macro{SIGTRAP}  &SL & C & Trace/breakpoint trap                         \\
-    \macro{SIGURG}   &SLB& B & Urgent condition on socket                    \\
-    \macro{SIGVTALRM}&SLB& A & Virtual alarm clock                           \\
-    \macro{SIGXCPU}  &SLB& C & Ecceduto il limite sul CPU time               \\
-    \macro{SIGXFSZ}  &SLB& C & Ecceduto il limite sulla dimensione dei file  \\
-    \macro{SIGIOT}   &L  & C & IOT trap. A synonym for \macro{SIGABRT}       \\
-    \macro{SIGEMT}   &L  &   &                                               \\
-    \macro{SIGSTKFLT}&L  & A & Stack fault on coprocessor                    \\
-    \macro{SIGIO}    &LB & A & I/O now possible (4.2 BSD)                    \\
-    \macro{SIGCLD}   &L  &   & A synonym for \macro{SIGCHLD}                 \\
-    \macro{SIGPWR}   &L  & A & Fallimento dell'alimentazione                 \\
-    \macro{SIGINFO}  &L  &   & A synonym for \macro{SIGPWR}                  \\
-    \macro{SIGLOST}  &L  & A & Perso un lock sul file (per NFS)              \\
-    \macro{SIGWINCH} &LB & B & Window resize signal (4.3 BSD, Sun)           \\
-    \macro{SIGUNUSED}&L  & A & Unused signal (will be SIGSYS)                \\
-    \hline
-  \end{tabular}
-  \caption{Lista dei segnali in Linux.}
-  \label{tab:sig_signal_list}
-\end{table}
-
 Per questo motivo ad ogni segnale viene associato un nome, definendo con una
 macro di preprocessore una costante uguale al suddetto numero. Sono questi
 nomi, che sono standardizzati e sostanzialmente uniformi rispetto alle varie
@@ -383,12 +327,6 @@ In \tabref{tab:sig_signal_list} si 
 definiti in Linux (estratto dalle man page), comparati con quelli definiti in
 vari standard.
 
-In \tabref{tab:sig_signal_list} si sono anche riportate le azioni di default
-di ciascun segnale (riassunte con delle lettere, la cui legenda completa è in
-\tabref{tab:sig_action_leg}), quando nessun manipolatore è installato un
-segnale può essere ignorato o causare la terminazione del processo. Nella
-colonna standard sono stati indicati anche gli standard in cui ciascun segnale
-è definito, secondo lo schema di \tabref{tab:sig_standard_leg}.
 
 \begin{table}[htb]
   \footnotesize
@@ -412,11 +350,13 @@ colonna standard sono stati indicati anche gli standard in cui ciascun segnale
   \label{tab:sig_action_leg}
 \end{table}
 
-In alcuni casi alla terminazione del processo è associata la creazione di un
-file (posto nella directory corrente del processo e chiamato \file{core}) su
-cui viene salvata un'immagine della memoria del processo (il cosiddetto
-\textit{core dump}), che può essere usata da un debugger per esaminare lo
-stato dello stack e delle variabili al momento della ricezione del segnale.
+In \tabref{tab:sig_signal_list} si sono anche riportate le azioni di default
+di ciascun segnale (riassunte con delle lettere, la cui legenda completa è in
+\tabref{tab:sig_action_leg}), quando nessun manipolatore è installato un
+segnale può essere ignorato o causare la terminazione del processo. Nella
+colonna standard sono stati indicati anche gli standard in cui ciascun segnale
+è definito, secondo lo schema di \tabref{tab:sig_standard_leg}.
+
 
 \begin{table}[htb]
   \footnotesize
@@ -437,6 +377,67 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
   \label{tab:sig_standard_leg}
 \end{table}
 
+In alcuni casi alla terminazione del processo è associata la creazione di un
+file (posto nella directory corrente del processo e chiamato \file{core}) su
+cui viene salvata un'immagine della memoria del processo (il cosiddetto
+\textit{core dump}), che può essere usata da un debugger per esaminare lo
+stato dello stack e delle variabili al momento della ricezione del segnale.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|c|c|p{8cm}|}
+    \hline
+    \textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\
+    \hline
+    \hline
+    \macro{SIGHUP}   &PL & A & Hangup o fine del processo di controllo      \\
+    \macro{SIGINT}   &PL & A & Interrupt da tastiera (\cmd{C-c})            \\
+    \macro{SIGQUIT}  &PL & C & Quit da tastiera (\cmd{C-y})                 \\
+    \macro{SIGILL}   &PL & C & Istruzione illegale                          \\
+    \macro{SIGABRT}  &PL & C & Segnale di abort da \func{abort}             \\
+    \macro{SIGFPE}   &PL & C & Errore aritmetico                            \\
+    \macro{SIGKILL}  &PL &AEF& Segnale di terminazione forzata              \\
+    \macro{SIGSEGV}  &PL & C & Errore di accesso in memoria                 \\
+    \macro{SIGPIPE}  &PL & A & Pipe spezzata                                \\
+    \macro{SIGALRM}  &PL & A & Segnale del timer da \func{alarm}             \\
+    \macro{SIGTERM}  &PL & A & Segnale di terminazione \verb|C-\|            \\
+    \macro{SIGUSR1}  &PL & A & Segnale utente numero 1                       \\
+    \macro{SIGUSR2}  &PL & A & Segnale utente numero 2                       \\
+    \macro{SIGCHLD}  &PL & B & Figlio terminato o fermato                    \\
+    \macro{SIGCONT}  &PL &   & Continua se fermato                           \\
+    \macro{SIGSTOP}  &PL &DEF& Ferma il processo                             \\
+    \macro{SIGTSTP}  &PL & D & Stop typed at tty                             \\
+    \macro{SIGTTIN}  &PL & D & Input sul terminale per un processo 
+                               in background                                 \\
+    \macro{SIGTTOU}  &PL & D & Output sul terminale per un processo          
+                               in background                                 \\
+    \macro{SIGBUS}   &SL & C & Errore sul bus (bad memory access)            \\
+    \macro{SIGPOLL}  &SL & A & Pollable event (Sys V).                      
+                               Sinonimo di \macro{SIGIO}                     \\
+    \macro{SIGPROF}  &SL & A & Timer del profiling scaduto                   \\
+    \macro{SIGSYS}   &SL & C & Bad argument to routine (SVID)                \\
+    \macro{SIGTRAP}  &SL & C & Trace/breakpoint trap                         \\
+    \macro{SIGURG}   &SLB& B & Urgent condition on socket                    \\
+    \macro{SIGVTALRM}&SLB& A & Virtual alarm clock                           \\
+    \macro{SIGXCPU}  &SLB& C & Ecceduto il limite sul CPU time               \\
+    \macro{SIGXFSZ}  &SLB& C & Ecceduto il limite sulla dimensione dei file  \\
+    \macro{SIGIOT}   &L  & C & IOT trap. A synonym for \macro{SIGABRT}       \\
+    \macro{SIGEMT}   &L  &   &                                               \\
+    \macro{SIGSTKFLT}&L  & A & Stack fault on coprocessor                    \\
+    \macro{SIGIO}    &LB & A & I/O now possible (4.2 BSD)                    \\
+    \macro{SIGCLD}   &L  &   & A synonym for \macro{SIGCHLD}                 \\
+    \macro{SIGPWR}   &L  & A & Fallimento dell'alimentazione                 \\
+    \macro{SIGINFO}  &L  &   & A synonym for \macro{SIGPWR}                  \\
+    \macro{SIGLOST}  &L  & A & Perso un lock sul file (per NFS)              \\
+    \macro{SIGWINCH} &LB & B & Window resize signal (4.3 BSD, Sun)           \\
+    \macro{SIGUNUSED}&L  & A & Unused signal (will be SIGSYS)                \\
+    \hline
+  \end{tabular}
+  \caption{Lista dei segnali in Linux.}
+  \label{tab:sig_signal_list}
+\end{table}
+
 La descrizione dettagliata del significato dei vari segnali, raggruppati per
 tipologia, verrà affrontate nel seguito.
 
@@ -778,7 +779,7 @@ processo alla loro occorrenza.
 
 
 \subsection{Il comportamento generale del sistema.}
-\label{sec:sig_gen_beha}
+  \label{sec:sig_gen_beha}
 
 Abbiamo già trattato in \secref{sec:sig_intro} le modalità con cui il sistema
 gestisce l'interazione fra segnali e processi, ci resta da esaminare però il
@@ -795,10 +796,10 @@ recapitati solo al padre, al figlio dovranno arrivare solo i segnali dovuti
 alle sue azioni.
 
 Quando si mette in esecuzione un nuovo programma con \func{exec} (si ricordi
-quanto detto in \secref{sec:prog_exec}) tutti i segnali per i quali è stato
+quanto detto in \secref{sec:proc_exec}) tutti i segnali per i quali è stato
 installato un manipolatore vengono resettati a \macro{SIG\_DFL}. Non ha più
 senso infatti fare riferimento a funzioni definite nel programma originario,
-che non sono nemmeno presenti nello spazio di indirizzi del nuovo programma.
+che non sono presenti nello spazio di indirizzi del nuovo programma.
 
 Si noti che questo vale solo per le azioni per le quali è stato installato un
 manipolatore; viene mantenuto invece ogni eventuale settaggio dell'azione a
@@ -819,8 +820,8 @@ eseguire un manipolatore non comporta nessun inconveniente.
 Esistono però dei casi in cui questo non è possibile perché renderebbe
 impossibile una risposta pronta al segnale. In generale questo avviene tutte
 le volte che si ha a che fare con system call che possono bloccarsi
-indefinitamente, che per questo vengono chiamate \textsl{lente}. Un elenco
-dei casi in cui si presenta questa situazione è il seguente:
+indefinitamente, (quelle che, per questo, vengono chiamate \textsl{lente}). Un
+elenco dei casi in cui si presenta questa situazione è il seguente:
 \begin{itemize*}
 \item lettura da file che possono bloccarsi in attesa di dati non ancora
   presenti (come per certi file di dispositivo, la rete o le pipe).
@@ -924,7 +925,7 @@ tutti i segnali pendenti saranno scartati, e non verranno mai notificati.
 L'uso di \func{signal} è soggetto a problemi di compatibilità, dato che essa
 si comporta in maniera diversa per sistemi derivati da BSD o da System V. In
 questi ultimi infatti la funzione è conforme al comportamento originale dei
-primi Unix in cui il manipolatore viene disinstallato alla sua chiamata
+primi Unix in cui il manipolatore viene disinstallato alla sua chiamata,
 secondo la semantica inaffidabile; Linux seguiva questa convenzione fino alle
 \acr{libc5}. Al contrario BSD segue la semantica affidabile, non resettando il
 manipolatore e bloccando il segnale durante l'esecuzione dello stesso. Con
@@ -985,9 +986,9 @@ la funzione \func{kill}; il suo prototipo 
 \end{functions}
 
 La funzione \code{raise(sig)} è sostanzialmente equivalente ad una
-\code{kill(getpid(), sig)}. Siccome \func{raise} è definita nello standard ISO
-C non esiste in alcune vecchie versioni di Unix, per cui in generale l'uso di
-\func{kill} è più portabile.
+\code{kill(getpid(), sig)}. Siccome \func{raise}, che è definita nello
+standard ISO C, non esiste in alcune vecchie versioni di Unix, in generale
+l'uso di \func{kill} finisce per essere più portabile.
 
 Lo standard POSIX poi prevede che il valore 0 sia usato per specificare il
 segnale nullo.  Se le funzioni vengono chiamate con questo valore non viene
@@ -998,18 +999,29 @@ conto per
 \secref{sec:proc_pid}) per cui l'esistenza di un processo non significa che
 esso sia realmente quello a cui si intendeva mandare il segnale.
 
-Il valore dell'argomento \param{pid} specifica la destinazione a cui inviare
-il segnale e può assumere i seguenti significati:
-\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
-\item[$\texttt{pid}>0$] il segnale è mandato al processo con il \acr{pid}
-  indicato.
-\item[$\texttt{pid}=0$] il segnale è mandato ad ogni processo del
-  \textit{process group} del chiamante.
-\item[$\texttt{pid}=-1$] il segnale è mandato ad ogni processo (eccetto
-  \cmd{init}).
-\item[$\texttt{pid}<-1$] il segnale è mandato ad ogni processo del process
-  group $|\code{pid}|$.
-\end{basedescript}
+Il valore dell'argomento \param{pid} specifica il processo (o i processi) di
+destinazione a cui il segnale deve essere inviato e può assumere i valori
+riportati in \tabref{tab:sig_kill_values}.
+\begin{table}[htb]
+  \centering
+  \begin{tabular}[c]{|r|l|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    $>0$ & il segnale è mandato al processo con il \acr{pid} indicato.\\
+    0    & il segnale è mandato ad ogni processo del \textit{process group}
+    del chiamante.\\ 
+    $-1$ & il segnale è mandato ad ogni processo (eccetto \cmd{init}).\\
+    $<-1$ & il segnale è mandato ad ogni processo del process group 
+    $|\code{pid}|$.\\
+    \hline
+  \end{tabular}
+  \caption{Valori dell'argomento \param{pid} per la funzione
+    \func{kill}.}
+  \label{tab:sig_kill_values}
+\end{table}
+
 
 Solo l'amministratore può inviare un segnale ad un processo qualunque, in
 tutti gli altri casi il \textit{real user id} o l'\textit{effective user id}
@@ -1033,7 +1045,7 @@ segnale al processo che ha effettuato la chiamata.
 \label{sec:sig_alarm_abort}
 
 Un caso particolare di segnali generati a richiesta è quello che riguarda i
-segnali di temporizzazione e \macro{SIGABORT}, per i quali sono previste
+segnali di temporizzazione e \macro{SIGABORT}, per i quali sono previste
 funzioni specifiche che ne effettuino l'invio. La prima di queste è
 \func{alarm} il cui prototipo è:
 \begin{prototype}{unistd.h}{unsigned int alarm(unsigned int seconds)}
@@ -1045,8 +1057,9 @@ funzioni specifiche che ne effettuino l'invio. La prima di queste 
 
 La funzione provvede un meccanismo che consente ad un processo di predisporre
 un'interruzione nel futuro, (ad esempio per effettuare una qualche operazione
-dopo un certo periodo di tempo), programmando l'emissione si un segnale di
-\macro{SIGALARM} dopo il numero di secondi specificato da \param{seconds}.
+dopo un certo periodo di tempo), programmando l'emissione di un segnale (in
+genere \macro{SIGALARM}) dopo il numero di secondi specificato da
+\param{seconds}.
 
 Se si specifica per \param{seconds} un valore nullo non verrà inviato nessun
 segnale; siccome alla chiamata viene cancellato ogni precedente allarme,
@@ -1057,8 +1070,8 @@ effettuare delle scelte in caso di necessit
 
 In \secref{sec:sys_unix_time} abbiamo visto che ad ogni processo sono
 associati tre tempi diversi: \textit{clock time}, \textit{user time} e
-\textit{system time}.  Per poterli calcolare il kernel mantiene tre diversi
-timer per ciascun processo:
+\textit{system time}.  Per poterli calcolare il kernel mantiene per ciascun
+processo tre diversi timer:
 \begin{itemize}
 \item un \textit{real-time timer} che calcola il tempo reale trascorso (che
   corrisponde al \textit{clock time}). La scadenza di questo timer provoca
@@ -1074,9 +1087,10 @@ timer per ciascun processo:
 \end{itemize}
 
 Il timer usato da \func{alarm} è il \textit{clock time}, e corrisponde cioè al
-tempo reale. La funzione, pur essendo molto semplice, presenta numerosi
-limiti: non consente di usare gli altri timer, non può specificare intervalli
-con precisione maggiore del secondo e genera il segnale una sola volta.
+tempo reale. La funzione come abbiamo visto è molto semplice, ma proprio per
+questo presenta numerosi limiti: non consente di usare gli altri timer, non
+può specificare intervalli di tempo con precisione maggiore del secondo e
+genera il segnale una sola volta.
 
 Per ovviare a questi limiti Linux deriva da BSD la funzione \func{setitimer}
 che permette di usare un timer qualunque e l'invio di segnali periodici, al
@@ -1151,7 +1165,7 @@ L'uso di \func{setitimer} consente dunque un controllo completo di tutte le
 caratteristiche dei timer, ed in effetti la stessa \func{alarm}, benché
 definita direttamente nello standard POSIX.1, può a sua volta essere espressa
 in termini di \func{setitimer}, come evidenziato dal manuale delle \acr{glibc}
-\cite[glibc] che ne riporta la definizione in \figref{fig:sig_alarm_def}.
+\cite{glibc} che ne riporta la definizione in \figref{fig:sig_alarm_def}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1355,11 +1369,11 @@ viene evitato, e si raggiungono pause fino ai 2~ms con precisioni del $\mu$s.
 
 
 
-\subsection{La gestione di \macro{SIGCHLD}}
+\subsection{Un esempio elementare}
 \label{sec:sig_sigchld}
 
 Un semplice esempio per illustrare il funzionamento di un manipolatore di
-segnale è quello della gestione di \macro{SIGCHLD}.  Abbiamo visto in
+segnale è quello della gestione di \macro{SIGCHLD}. Abbiamo visto in
 \secref{sec:proc_termination} che una delle azioni eseguite dal kernel alla
 conclusione di un processo è quella di inviare questo segnale al
 padre;\footnote{in realtà in SRV4 eredita la semantica di System V, in cui il
@@ -1369,10 +1383,58 @@ padre;\footnote{in realt
   terminazione viene scartato senza dover chiamare una \func{wait}). L'azione
   di default è sempre quella di ignorare il segnale, ma non attiva questo
   comportamento. Linux, come BSD e POSIX, non supporta questa semantica ed usa
-  il nome di \macro{SIGCLD} come sinonimo di \macro{SIGCHLD}.} è pertanto
-naturale completare qui la trattazione della terminazione dei processi
-illustrando le modalità per gestire questo segnale.
+  il nome di \macro{SIGCLD} come sinonimo di \macro{SIGCHLD}.} in questo caso
+tutto quello che dovrà fare il manipolatore è ricevere lo stato di
+terminazione in modo da evitare la formazione di zombie.
+
+%  è pertanto
+% naturale usare un esempio che ci permette di concludere la trattazione della
+% terminazione dei processi.
+% In questo caso si è tratterà di illustrare un esempio relativo ad un
+% manipolatore per che è previsto ritornare,
+
+In realtà nel caso di \macro{SIGCHLD} occorre tenere conto anche di un altro
+aspetto del comportamento dei segnali e cioè del fatto 
+
+
+
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+#include <errno.h>       /* error simbol definitions */
+#include <signal.h>      /* signal handling declarations */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "macro.h"
 
+void Hand_CHLD(int sig)
+{
+    int errno_save;
+    int status;
+    pid_t pid;
+    /* save errno current value */
+    errno_save = errno;
+    /* loop until no */
+    do {
+        errno = 0;
+        pid = waitpid(WAIT_ANY, &status, WNOHANG);
+        if (pid > 0) {
+            debug("child %d terminated with status %x\n", pid, status);
+        }
+    } while ((pid > 0) && (errno == EINTR));
+    /* restore errno value*/
+    errno = errno_save;
+    /* return */
+    return;
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Una implementazione sbagliata di \func{sleep}.} 
+  \label{fig:sig_timespec_def}
+\end{figure}