Aggiunta implementazione di Signal e riferimenti nel capitolo relativo
[gapil.git] / signal.tex
index 58454408615332f9a7bc5d78e41a8c6de8f8e3f1..703d876a06bade859600496f050995c23e7f36ff 100644 (file)
@@ -19,7 +19,6 @@ di generazione fino ad esaminare in dettaglio funzioni e le metodologie di
 gestione.
 
 
-
 \section{Introduzione}
 \label{sec:sig_intro}
 
@@ -64,17 +63,17 @@ stata specificata dall'utente (nel qual caso si dice che si
 \textsl{intercetta} il segnale).
 
 
-\subsection{Le modalità di funzionamento}
+\subsection{Le \textsl{semantiche} del funzionamento dei segnali}
 \label{sec:sig_semantics}
 
 Negli anni il comportamento del sistema in risposta ai segnali è stato
 modificato in vari modi nelle differenti implementazioni di Unix.  Si possono
 individuare due tipologie fondamentali di comportamento dei segnali (dette
-semantiche) che vengono chiamate rispettivamente semantica \textsl{affidabile}
-(o \textit{reliable}) e semantica \textsl{inaffidabile} (o
+\textsl{semantiche}) che vengono chiamate rispettivamente \textsl{semantica
+  affidabile} (o \textit{reliable}) e \textsl{semantica inaffidabile} (o
 \textit{unreliable}).
 
-Nella semantica \textsl{inaffidabile} (quella implementata dalle prime
+Nella \textsl{semantica inaffidabile} (quella implementata dalle prime
 versioni di Unix) la routine di gestione del segnale specificata dall'utente
 non resta attiva una volta che è stata eseguita; è perciò compito dell'utente
 stesso ripetere l'installazione della stessa all'interno della routine di
@@ -82,13 +81,41 @@ 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
-operazione del manipolatore è quella di reinstallare se stesso: 
-s
-e un secondo segnale arriva prima che il manipolatore invocato dal primo
-abbia eseguito la reinstallazione di se stesso il segnale può essere perso o
-causare il comportamento originale assegnato al segnale (in genere la
-terminazione del processo).
+perduti. Si consideri il segmento di codice riportato in
+\secref{fig:sig_old_handler}, nel programma principale viene installato un
+manipolatore (\texttt{\small 5}), ed in quest'ultimo la prima operazione
+(\texttt{\small 11}) è quella di reinstallare se stesso. Se nell'esecuzione
+del manipolatore un secondo segnale arriva prima che esso abbia potuto
+eseguire la reinstallazione, verrà eseguito il comportamento di default
+assegnato al segnale stesso, il che può comportare, a seconda dei casi, che il
+segnale viene perso (se il default era quello di ignorarlo) o la terminazione
+immediata del processo; in entrambi i casi l'azione prevista non verrà
+eseguita.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+int sig_handler();            /* handler function */
+int main()
+{
+    ...
+    signal(SIGINT, sig_handler);  /* establish handler */
+    ...
+}
+
+int sig_handler() 
+{
+    signal(SIGINT, sig_handler);  /* restablish handler */
+    ...                           /* process signal */
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Esempio di codice di un manipolatore di segnale per la semantica
+    inaffidabile.} 
+  \label{fig:sig_old_handler}
+\end{figure}
 
 Questa è la ragione per cui l'implementazione dei segnali secondo questa
 semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
@@ -101,49 +128,6 @@ 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.
-
-% 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
 tutti i problemi precedenti. In questa semantica i segnali vengono
@@ -169,9 +153,8 @@ ignorarlo.
 Si tenga presente che il kernel stabilisce cosa fare con un segnale che è
 stato bloccato al momento della consegna, non quando viene generato; questo
 consente di cambiare l'azione per il segnale prima che esso venga consegnato,
-e si può usare la funzione \func{sigpending} (vedi
-\secref{sec:sig_sigpending}) per determinare quali segnali sono bloccati e
-quali sono pendenti.
+e si può usare la funzione \func{sigpending} (vedi \secref{sec:sig_sigmask})
+per determinare quali segnali sono bloccati e quali sono pendenti.
 
 
 \subsection{Tipi di segnali}
@@ -368,18 +351,19 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
   \centering
   \begin{tabular}[c]{|l|c|c|p{8cm}|}
     \hline
-    \textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\
+    \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{SIGHUP}   &PL & A & Hangup o terminazione 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                       \\
@@ -387,31 +371,32 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
     \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{SIGTSTP}  &PL & D & Pressione del tasto di stop sul terminale     \\
     \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).                      
+    \macro{SIGPOLL}  &SL & A & \textit{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{SIGSYS}   &SL & C & Argomento sbagliato per una subroutine (SVID) \\
+    \macro{SIGTRAP}  &SL & C & Trappole per un Trace/breakpoint              \\
+    \macro{SIGURG}   &SLB& B & Ricezione di una urgent condition su un 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{SIGIOT}   &L  & C & IOT trap. Sinonimo di \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{SIGSTKFLT}&L  & A & Errore sullo stack del coprocessore           \\
+    \macro{SIGIO}    &LB & A & L'I/O è possibile (4.2 BSD)                   \\
+    \macro{SIGCLD}   &L  &   & Sinonimo di \macro{SIGCHLD}                   \\
     \macro{SIGPWR}   &L  & A & Fallimento dell'alimentazione                 \\
-    \macro{SIGINFO}  &L  &   & A synonym for \macro{SIGPWR}                  \\
+    \macro{SIGINFO}  &L  &   & Sinonimo di \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)                \\
+    \macro{SIGWINCH} &LB & B & Finestra ridimensionata (4.3 BSD, Sun)        \\
+    \macro{SIGUNUSED}&L  & A & Segnale inutilizzato (diventerà 
+                               \macro{SIGSYS})                               \\
     \hline
   \end{tabular}
   \caption{Lista dei segnali in Linux.}
@@ -419,7 +404,7 @@ stato dello stack e delle variabili al momento della ricezione del segnale.
 \end{table}
 
 La descrizione dettagliata del significato dei vari segnali, raggruppati per
-tipologia, verrà affrontate nel seguito.
+tipologia, verrà affrontate nei paragrafi successivi.
 
 
 \subsection{Segnali di errore di programma}
@@ -454,7 +439,7 @@ Questi segnali sono:
   aritmetici compresa la divisione per zero e l'overflow. 
   
   Se il manipolatore ritorna il comportamento del processo è indefinito, ed
-  ignorare questo segnale può condurre ad un loop infinito.
+  ignorare questo segnale può condurre ad un ciclo infinito.
 
 %   Per questo segnale le cose sono complicate dal fatto che possono esserci
 %   molte diverse eccezioni che \texttt{SIGFPE} non distingue, mentre lo
@@ -580,8 +565,8 @@ sempre la necessit
 \item[\macro{SIGPROF}] Il nome sta per \textit{profiling}. Indica la scadenza
   di un timer che misura sia il tempo di CPU speso direttamente dal processo
   che quello che il sistema ha speso per conto di quest'ultimo. In genere
-  viene usato dai tool che servono a fare il profilo d'uso della CPU da parte
-  del processo.
+  viene usato dagli strumenti che servono a fare la profilazione dell'utilizzo
+  del tempo di CPU da parte del processo.
 \end{basedescript}
 
 
@@ -691,13 +676,14 @@ segnali sono:
 Raccogliamo qui infine usa serie di segnali che hanno scopi differenti non
 classificabili in maniera omogenea. Questi segnali sono:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\macro{SIGUSR1} e \macro{SIGUSR2}] Sono due segnali a disposizione
+\item[\macro{SIGUSR1}] Vedi \macro{SIGUSR2}.
+\item[\macro{SIGUSR2}] Insieme a \macro{SIGUSR1} è un segnale a disposizione
   dell'utente che li può usare per quello che vuole. Possono essere utili per
   implementare una comunicazione elementare fra processi diversi, o per
   eseguire a richiesta una operazione utilizzando un manipolatore. L'azione di
   default è terminare il processo.
-\item[\macro{SIGWINCH}] Il nome sta per \textit{window (size) change} ed è
-  generato da molti sistemi (GNU/Linux compreso) quando le dimensioni (in
+\item[\macro{SIGWINCH}] Il nome sta per \textit{window (size) change} e viene
+  generato in molti sistemi (GNU/Linux compreso) quando le dimensioni (in
   righe e colonne) di un terminale vengono cambiate. Viene usato da alcuni
   programmi testuali per riformattare l'uscita su schermo quando si cambia
   dimensione a quest'ultimo. L'azione di default è di essere ignorato.
@@ -773,12 +759,11 @@ comportamento delle system call; in particolare due di esse, \func{fork} ed
 loro stretta relazione con la creazione di nuovi processi.
 
 Come accennato in \secref{sec:proc_fork} quando viene creato un nuovo processo
-con \func{fork} esso eredita dal padre sia le azioni che sono state settate
-per i singoli segnali, che la maschera dei segnali bloccati (tratteremo
-quest'ultimo argomento in \ref{sec:sig_sigpending}). Invece tutti i segnali
-pendenti e gli allarmi vengono cancellati; essi infatti devono essere
-recapitati solo al padre, al figlio dovranno arrivare solo i segnali dovuti
-alle sue azioni.
+esso eredita dal padre sia le azioni che sono state settate per i singoli
+segnali, che la maschera dei segnali bloccati (vedi \secref{sec:sig_sigmask}).
+Invece tutti i segnali pendenti e gli allarmi vengono cancellati; essi infatti
+devono essere 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:proc_exec}) tutti i segnali per i quali è stato
@@ -807,7 +792,7 @@ 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, (quelle che, per questo, vengono chiamate \textsl{lente}). Un
 elenco dei casi in cui si presenta questa situazione è il seguente:
-\begin{itemize*}
+\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).
 \item scrittura sugli stessi file, nel caso in cui dati non possano essere
@@ -818,10 +803,10 @@ elenco dei casi in cui si presenta questa situazione 
   eseguite immediatamente.
 \item le funzioni di intercomunicazione che si bloccano in attesa di risposte
   da altri processi.
-\item la funzione \func{pause} (usata appunto per attendere l'-arrivo di un
+\item la funzione \func{pause} (usata appunto per attendere l'arrivo di un
   segnale).
 \item la funzione \func{wait} (se nessun processo figlio è ancora terminato).
-\end{itemize*}
+\end{itemize}
 
 In questo caso si pone il problema di cosa fare una volta che il manipolatore
 sia ritornato. La scelta originaria dei primi Unix era quella di far ritornare
@@ -857,9 +842,11 @@ funzione \func{signal} che 
 però non considera sistemi multitasking, per cui la definizione è tanto vaga
 da essere del tutto inutile in un sistema Unix; è questo il motivo per cui
 ogni implementazione successiva ne ha modificato e ridefinito il
-comportamento, pur mantenendone immutato il prototipo\footnote{in realtà
-  alcune vecchie implementazioni (SVR4 e 4.3+BSD) usano parametri aggiuntivi
-  per definire il comportamento della funzione.} che è:
+comportamento, pur mantenendone immutato il prototipo\footnote{in realtà in
+  alcune vecchie implementazioni (SVr4 e 4.3+BSD in particolare) vengono usati
+  alcuni parametri aggiuntivi per definire il comportamento della funzione,
+  vedremo in \secref{sec:sig_sigaction} che questo è possibile usando la
+  funzione \func{sigaction}.}  che è:
 \begin{prototype}{signal.h}
   {sighandler\_t signal(int signum, sighandler\_t handler)} 
   
@@ -870,11 +857,13 @@ comportamento, pur mantenendone immutato il prototipo\footnote{in realt
     o \macro{SIG\_ERR} in caso di errore.}
 \end{prototype}
 
-In questa definizione si è usato il tipo \type{sighandler\_t} che è una
-estensione GNU, definita dalle \acr{glibc}, che permette di riscrivere il
-prototipo in una forma più leggibile dell'originario:
+In questa definizione si è usato un tipo di dato, \type{sighandler\_t}, che è
+una estensione GNU, definita dalle \acr{glibc}, esso permette di riscrivere il
+prototipo di \func{signal} nella forma appena vista, che risulta molto più
+leggibile di quanto non sia la versione originaria che di norma è definita
+come:
 \begin{verbatim}
-void (*signal(int signum, void (*handler)(int)))int)
+    void (*signal(int signum, void (*handler)(int)))int)
 \end{verbatim}
 questa infatti, per la poca chiarezza della sintassi del C quando si vanno a
 trattare puntatori a funzioni, è molto meno comprensibile.  Da un confronto
@@ -914,11 +903,11 @@ 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
-l'utilizzo delle \acr{glibc2} anche Linux è passato a questo comportamento;
-quello della versione originale della funzione, il cui uso è deprecato per i
-motivi visti in \secref{sec:sig_semantics}, può essere ottenuto chiamando
-\func{sysv\_signal}.  In generale, per evitare questi problemi, tutti i nuovi
-programmi dovrebbero usare \func{sigaction}.
+l'utilizzo delle \acr{glibc} dalla versione 2 anche Linux è passato a questo
+comportamento; quello della versione originale della funzione, il cui uso è
+deprecato per i motivi visti in \secref{sec:sig_semantics}, può essere
+ottenuto chiamando \func{sysv\_signal}.  In generale, per evitare questi
+problemi, tutti i nuovi programmi dovrebbero usare \func{sigaction}.
 
 È da tenere presente che, seguendo lo standard POSIX, il comportamento di un
 processo che ignora i segnali \macro{SIGFPE}, \macro{SIGILL}, o
@@ -1007,6 +996,18 @@ termini di \func{kill}, ed 
 standard ISO C, non esiste in alcune vecchie versioni di Unix, in generale
 l'uso di \func{kill} finisce per essere più portabile.
 
+Una seconda funzione che può essere definita in termini di \func{kill} è
+\func{killpg}, che è sostanzialmente equivalente a
+\code{kill(-pidgrp, signal)}; il suo prototipo è:
+\begin{prototype}{signal.h}{int killpg(pid\_t pidgrp, int signal)} 
+  
+  Invia il segnale \param{signal} al process group \param{pidgrp}.
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, gli errori sono gli stessi di \func{kill}.}
+\end{prototype}
+e che permette di inviare un segnale a tutto un \textit{process group} (vedi
+\secref{sec:sess_xxx}).
+
 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}
 del processo chiamante devono corrispondere al \textit{real user id} o al
@@ -1029,12 +1030,12 @@ 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
-vari segnali di temporizzazione e \macro{SIGABORT}, per ciascuno di questi
+vari segnali di temporizzazione e \macro{SIGABRT}, per ciascuno di questi
 segnali sono previste funzioni specifiche che ne effettuino l'invio. La più
 comune delle funzioni usate per la temporizzazione è \func{alarm} il cui
 prototipo è:
 \begin{prototype}{unistd.h}{unsigned int alarm(unsigned int seconds)}
-  Predispone l'invio di \macro{SIGALARM} dopo \param{seconds} secondi.
+  Predispone l'invio di \macro{SIGALRM} dopo \param{seconds} secondi.
   
   \bodydesc{La funzione restituisce il numero di secondi rimanenti ad un
     precedente allarme, o zero se non c'erano allarmi pendenti.}
@@ -1043,7 +1044,7 @@ prototipo 
 La funzione fornisce 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 di un segnale (nel
-caso in questione \macro{SIGALARM}) dopo il numero di secondi specificato da
+caso in questione \macro{SIGALRM}) dopo il numero di secondi specificato da
 \param{seconds}.
 
 Se si specifica per \param{seconds} un valore nullo non verrà inviato nessun
@@ -1063,7 +1064,7 @@ 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
-  l'emissione di \macro{SIGALARM}.
+  l'emissione di \macro{SIGALRM}.
 \item un \textit{virtual timer} che calcola il tempo di processore usato dal
   processo in user space (che corrisponde all'\textit{user time}). La scadenza
   di questo timer provoca l'emissione di \macro{SIGVTALRM}.
@@ -1250,7 +1251,7 @@ eventuali funzioni registrate con \func{at\_exit} e \func{on\_exit}.
 \label{sec:sig_pause_sleep}
 
 Il metodo tradizionale per fare attendere\footnote{cioè di porre
-  temporanemente il processo in stato di \textit{sleep}, vedi
+  temporaneamente il processo in stato di \textit{sleep}, vedi
   \ref{sec:proc_sched}.}  ad un processo fino all'arrivo di un segnale è
 quello di usare la funzione \func{pause}, il cui prototipo è:
 \begin{prototype}{unistd.h}{int pause(void)}
@@ -1383,7 +1384,7 @@ Un semplice esempio per illustrare il funzionamento di un manipolatore di
 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
+padre.\footnote{in realtà in SVr4 eredita la semantica di System V, in cui il
   segnale si chiama \macro{SIGCLD} e viene trattato in maniera speciale; in
   System V infatti se si setta esplicitamente l'azione a \macro{SIG\_IGN} il
   segnale non viene generato ed il sistema non genera zombie (lo stato di
@@ -1399,7 +1400,7 @@ zombie.
 
 In \figref{fig:sig_sigchld_handl} è mostrato il codice della nostra
 implementazione del manipolatore; se aggiungiamo al codice di
-\file{ForkTest.c} l'intallazione di questo manipolatore potremo verificare che
+\file{ForkTest.c} l'installazione di questo manipolatore potremo verificare che
 ripetendo l'esempio visto in \secref{sec:proc_termination} che non si ha più
 la creazione di zombie.
 
@@ -1414,7 +1415,7 @@ la creazione di zombie.
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
-#include <errno.h>       /* error simbol definitions */
+#include <errno.h>       /* error symbol definitions */
 #include <signal.h>      /* signal handling declarations */
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1472,8 +1473,8 @@ presenta tutte le volte che un segnale viene bloccato: per quanti siano i
 segnali emessi durante il periodo di blocco, una volta che quest'ultimo sarà
 rimosso sarà recapitato un solo segnale.
 
-Allora nel caso della terminazione dei processi figli, se si chiamasse
-\func{waitpid} una sola volta, essa leggerebbe lo stato di teminazione per un
+Allora, nel caso della terminazione dei processi figli, se si chiamasse
+\func{waitpid} una sola volta, essa leggerebbe lo stato di terminazione per un
 solo processo, anche se i processi terminati sono più di uno, e gli altri
 resterebbero in stato di zombie per un tempo indefinito.
 
@@ -1501,55 +1502,55 @@ fino a trattare le caratteristiche generali della gestione dei medesimi nella
 casistica ordinaria.
 
 
-\subsection{Un esempio di problema}
+\subsection{Alcune problematiche aperte}
 \label{sec:sig_example}
 
 Come accennato in \secref{sec:sig_pause_sleep} è possibile implementare
-\func{sleep} a partire da dall'uso di \func{pause} e \func{alarm}. A prima
-vista questo può sembrare di implementazione immediata; ad esempio una
-semplice versione di \func{sleep} potrebbe essere quella illustrata in
+\func{sleep} a partire dall'uso di \func{pause} e \func{alarm}. A prima vista
+questo può sembrare di implementazione immediata; ad esempio una semplice
+versione di \func{sleep} potrebbe essere quella illustrata in
 \figref{fig:sig_sleep_wrong}.
 
-
-Dato che è nostra intenzione utilizzare \macro{SIGALARM} il primo passo della
+Dato che è nostra intenzione utilizzare \macro{SIGALRM} il primo passo della
 nostra implementazione di sarà quello di installare il relativo manipolatore
-salvando il precedente (\texttt{\small 4-7}).  Si effettuerà poi una chiamata
-ad \func{alarm} per specificare il tempo d'attesa per l'invio del segnale a
-cui segue la chiamata a \func{pause} per fermare il programma (\texttt{\small
-  8-9}) fino alla sua ricezione.  Al ritorno di \func{pause}, causato dal
-ritorno del manipolatore (\texttt{\small 15-23}), si ripristina il
-manipolatore originario (\texttt{\small 10-11}) restituendo l'eventuale tempo
-rimanente (\texttt{\small 12-13}) che potrà essere diverso da zero qualora
+salvando il precedente (\texttt{\small 14-17}).  Si effettuerà poi una
+chiamata ad \func{alarm} per specificare il tempo d'attesa per l'invio del
+segnale a cui segue la chiamata a \func{pause} per fermare il programma
+(\texttt{\small 17-19}) fino alla sua ricezione.  Al ritorno di \func{pause},
+causato dal ritorno del manipolatore (\texttt{\small 1-9}), si ripristina il
+manipolatore originario (\texttt{\small 20-21}) restituendo l'eventuale tempo
+rimanente (\texttt{\small 22-23}) che potrà essere diverso da zero qualora
 l'interruzione di \func{pause} venisse causata da un altro segnale.
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
+void alarm_hand(int sig) {
+    /* check if the signal is the right one */
+    if (sig != SIGALRM) { /* if not exit with error */
+        printf("Something wrong, handler for SIGALRM\n");
+        exit(1);
+    } else {    /* do nothing, just interrupt pause */
+        return;
+    }
+}
 unsigned int sleep(unsigned int seconds)
 {
-    signandler_t prev_handler;
+    sighandler_t prev_handler;
+    /* install and check new handler */
     if ((prev_handler = signal(SIGALRM, alarm_hand)) == SIG_ERR) {
-        printf("Cannot set handler for alarm\n");
-        exit(1);
+        printf("Cannot set handler for alarm\n"); 
+        exit(-1);
     }
-    alarm(second);
+    /* set alarm and go to sleep */
+    alarm(seconds); 
     pause(); 
     /* restore previous signal handler */
     signal(SIGALRM, prev_handler);
-    /* remove alarm, return remaining time */
+    /* return remaining time */
     return alarm(0);
 }
-void alarm_hand(int sig) 
-{
-    /* check if the signal is the right one */
-    if (sig != SIGALRM) { /* if not exit with error */
-        printf("Something wrong, handler for SIGALRM\n");
-        exit(1);
-    } else {    /* do nothing, just interrupt pause */
-        return;
-    }
-}      
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
@@ -1562,13 +1563,13 @@ precedente chiamata a \func{alarm} (che si 
 presenta una pericolosa race condition.  Infatti se il processo viene
 interrotto fra la chiamata di \func{alarm} e \func{pause} può capitare (ad
 esempio se il sistema è molto carico) che il tempo di attesa scada prima
-dell'esecuzione quest'ultima, cosicchè essa sarebbe eseguita dopo l'arrivo di
+dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo l'arrivo di
 \macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un deadlock, in
 quanto \func{pause} non verrebbe mai più interrotta (se non in caso di un
 altro segnale).
 
 Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
-SVr2) usando la funzione \func{longjump} (vedi \secref{sec:proc_longjmp}) per
+SVr2) usando la funzione \func{longjmp} (vedi \secref{sec:proc_longjmp}) per
 uscire dal manipolatore; in questo modo, con una condizione sullo stato di
 uscita di quest'ultima, si può evitare la chiamata a \func{pause}, usando un
 codice del tipo di quello riportato in \figref{fig:sig_sleep_incomplete}.
@@ -1614,7 +1615,7 @@ void alarm_hand(int sig)
 In questo caso il manipolatore (\texttt{\small 18-26}) non ritorna come in
 \figref{fig:sig_sleep_wrong}, ma usa \func{longjmp} (\texttt{\small 24}) per
 rientrare nel corpo principale del programma; dato che in questo caso il
-valore di uscita di \func{setjmp} è 1 grazie alla condizione in
+valore di uscita di \func{setjmp} è 1, grazie alla condizione in
 (\texttt{\small 9-12}) si evita comunque che \func{pause} sia chiamata a
 vuoto.
 
@@ -1622,12 +1623,67 @@ Ma anche questa implementazione comporta dei problemi; in questo caso infatti
 non viene gestita correttamente l'interazione con gli altri segnali; se
 infatti il segnale di allarme interrompe un altro manipolatore, in questo caso
 l'esecuzione non riprenderà nel manipolatore in questione, ma nel ciclo
-principale, interrompendone inopportunamente l'esecuzione.  È per questo
-motivo che occorrono funzioni più sofisticate della semplice \func{signal} che
-permettano di gestire i segnali in maniera più completa.
+principale, interrompendone inopportunamente l'esecuzione.  Lo stesso tipo di
+problemi si presenterebbero se si volesse usare \func{alarm} per stabilire un
+timeout su una qualunque system call bloccante.
+
+Un secondo esempio è quello in cui si usa il segnale per notificare una
+qualche forma di evento; in genere quello che si fa in questo caso è settare
+nel manipolatore un opportuno flag da controllare nel corpo principale del
+programma (con un codice del tipo di quello riportato in
+\figref{fig:sig_event_wrong}).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+sig_atomic_t flag;
+int main()
+{
+    flag = 0;
+    ...
+    if (flag) {         /* test if signal occurred */
+        flag = 0;       /* reset flag */ 
+        do_response();  /* do things */
+    } else {
+        do_other();     /* do other things */
+    }
+    ...
+}
+void alarm_hand(int sig) 
+{
+    /* set the flag 
+    flag = 1;
+    return;
+}      
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Un esempio non funzionante del codice per il controllo di un
+    evento generato da un segnale.}
+  \label{fig:sig_event_wrong}
+\end{figure}
+
+La logica è quella di far settare al manipolatore (\texttt{\small 14-19}) una
+variabile globale preventivamente inizializzata nel programma principale, il
+quale potrà determinare, osservandone il contenuto, l'occorrenza o meno del
+segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
+
+Questo è il tipico esempio di caso, già citato in \secref{sec:proc_race_cond},
+in cui si genera una race condition; se infatti il segnale arriva
+immediatamente dopo l'esecuzione del controllo (\texttt{\small 6}) ma prima
+della cancellazione del flag (\texttt{\small 7}), la sua occorrenza sarà
+perduta.
 
+Questi esempi ci mostrano che per una gestione effettiva dei segnali occorrono
+funzioni più sofisticate di quelle illustrate finora, che hanno origine dalla
+interfaccia semplice, ma poco sofisticata, dei primi sistemi Unix, in modo da
+consentire la gestione di tutti i possibili aspetti con cui un processo deve
+reagire alla ricezione di un segnale.
 
-\subsection{I \textit{signal set}}
+
+
+\subsection{Gli \textsl{insiemi di segnali} o \textit{signal set}}
 \label{sec:sig_sigset}
 
 Come evidenziato nel paragrafo precedente, le funzioni di gestione dei segnali
@@ -1636,41 +1692,41 @@ superabili; in particolare non 
 gestire gestire il blocco dei segnali o di verificare lo stato dei segnali
 pendenti.
 
-Per questo motivo lo standard POSIX, insieme alla nuova semantica dei segnali
-ha introdotto una interfaccia di gestione completamente nuova, che permette di
-ottenete un controllo molto più dettagliato. In particolare lo standard ha
-introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
-rappresentare un insieme di segnali (un \textit{signal set}, come viene
-usualmente chiamato), che è il tipo di dato che viene usato per gestire il
-blocco dei segnali.
-
-In genere un \textit{signal set} è rappresentato da un intero di dimensione
-opportuna, di solito si pari al numero di bit dell'architettura della
-macchina\footnote{nel caso dei PC questo comporta un massimo di 32 segnali
-  distinti, dato che in Linux questi sono sufficienti non c'è necessità di
-  nessuna struttura più complicata.}, ciascun bit del quale è associato ad uno
-specifico segnale; in questo modo è di solito possibile implementare le
-operazioni direttamente con istruzioni elementari del processore; lo standard
-POSIX definisce cinque funzioni per la manipolazione dei \textit{signal set},
-\func{sigemptyset}, \func{sigfillset}, \func{sigaddset}, \func{sigdelset} e
-\func{sigismember}, i cui prototipi sono:
+Per questo motivo lo standard POSIX.1, insieme alla nuova semantica dei
+segnali ha introdotto una interfaccia di gestione completamente nuova, che
+permette di ottenete un controllo molto più dettagliato. In particolare lo
+standard ha introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
+rappresentare un \textsl{insieme di segnali} (un \textit{signal set}, come
+viene usualmente chiamato), che è il tipo di dato che viene usato per gestire
+il blocco dei segnali.
+
+In genere un \textsl{insieme di segnali} è rappresentato da un intero di
+dimensione opportuna, di solito si pari al numero di bit dell'architettura
+della macchina\footnote{nel caso dei PC questo comporta un massimo di 32
+  segnali distinti, dato che in Linux questi sono sufficienti non c'è
+  necessità di nessuna struttura più complicata.}, ciascun bit del quale è
+associato ad uno specifico segnale; in questo modo è di solito possibile
+implementare le operazioni direttamente con istruzioni elementari del
+processore; lo standard POSIX.1 definisce cinque funzioni per la manipolazione
+degli insiemi di segnali: \func{sigemptyset}, \func{sigfillset},
+\func{sigaddset}, \func{sigdelset} e \func{sigismember}, i cui prototipi sono:
 \begin{functions}
   \headdecl{signal.h} 
-
-  \funcdecl{int sigemptyset(sigset\_t *set)} Inizializza un \textit{signal set}
-  vuoto.
+  
+  \funcdecl{int sigemptyset(sigset\_t *set)} Inizializza un insieme di segnali
+  vuoto (in cui non c'è nessun segnale).
  
-  \funcdecl{int sigfillset(sigset\_t *set)} Inizializza un \textit{signal set}
-  pieno (con tutti i segnali).
+  \funcdecl{int sigfillset(sigset\_t *set)} Inizializza un insieme di segnali
+  pieno (in cui ci sono tutti i segnali).
   
   \funcdecl{int sigaddset(sigset\_t *set, int signum)} Aggiunge il segnale
-  \param{signum} al  \textit{signal set} \param{set}.
+  \param{signum} all'insieme di segnali \param{set}.
 
   \funcdecl{int sigdelset(sigset\_t *set, int signum)} Toglie il segnale
-  \param{signum} dal \textit{signal set} \param{set}.
+  \param{signum} dall'insieme di segnali \param{set}.
   
   \funcdecl{int sigismember(const sigset\_t *set, int signum)} Controlla se il
-  segnale \param{signum} è nel \textit{signal set} \param{set}
+  segnale \param{signum} è nell'insieme di segnali \param{set}.
   
   \bodydesc{Le prime quattro funzioni ritornano 0 in caso di successo, mentre
     \func{sigismember} ritorna 1 se \param{signum} è in \param{set} e 0
@@ -1685,27 +1741,27 @@ per mettere tutti i segnali in un intero, o in \type{sigset\_t} possono essere
 immagazzinate ulteriori informazioni) tutte le operazioni devono essere
 comunque eseguite attraverso queste funzioni.
 
-In genere si usa un \textit{signal set} per specificare quali segnali si vuole
+In genere si usa un insieme di segnali per specificare quali segnali si vuole
 bloccare, o per riottenere dalle varie funzioni di gestione la maschera dei
-segnali attivi. Essi possono essere definiti in due diverse maniere,
-aggiungendo i segnali voluti ad un insieme vuoto ottenuto con
-\func{sigemptyset} o togliendo quelli che non servono da un insieme completo
-ottenuto con \func{sigfillset}. Infine \func{sigismember} permette di vericare
-la presenza di uno specifico segnale in un \textit{signal set}.
+segnali attivi (vedi \secref{sec:sig_sigmask}). Essi possono essere definiti
+in due diverse maniere, aggiungendo i segnali voluti ad un insieme vuoto
+ottenuto con \func{sigemptyset} o togliendo quelli che non servono da un
+insieme completo ottenuto con \func{sigfillset}. Infine \func{sigismember}
+permette di verificare la presenza di uno specifico segnale in un
+insieme.
 
 
 \subsection{La funzione \func{sigaction}}
 \label{sec:sig_sigaction}
 
-La funzione principale dell'interfaccia standard POSIX per i segnali è
-\func{sigaction}, essa ha sostanzialemente le stesse funzioni di
-\func{signal}, permette cioè di specificare come un segnale può essere gestito
+La funzione principale dell'interfaccia standard POSIX.1 per i segnali è
+\func{sigaction}, essa ha sostanzialemente lo stesso uso di \func{signal},
+permette cioè di specificare le modalità con cui un segnale può essere gestito
 da un processo. Il suo prototipo è:
-
 \begin{prototype}{signal.h}{int sigaction(int signum, const struct sigaction
     *act, struct sigaction *oldact)} 
   
-  Installa un nuovo manipolatore per il segnale \param{signum}.
+  Installa una nuova azione per il segnale \param{signum}.
   
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
     errore, nel qual caso \var{errno} assumerà i valori:
@@ -1717,14 +1773,15 @@ da un processo. Il suo prototipo 
   \end{errlist}}
 \end{prototype}
 
-La funzione serve ad installare una nuova azione per il segnale
-\param{signum}; si parla di azione e non di manipolatore come nel caso di
-\func{signal}, in quanto la funzione consente di specificare le varie
-caratteristiche della risposta al segnale, non solo la funzione del
-manipolatore.  Lo standard POSIX raccomanda di usare sempre questa funzione al
-posto di \func{signal} (che in genere viene definita tramite essa), in quanto
-offre un controllo completo su tutti gli aspetti della gestione di un segnale,
-sia pure al prezzo di una maggiore complessità d'uso.
+La funzione serve ad installare una nuova \textsl{azione} per il segnale
+\param{signum}; si parla di \textsl{azione} e non di \textsl{manipolatore}
+come nel caso di \func{signal}, in quanto la funzione consente di specificare
+le varie caratteristiche della risposta al segnale, non solo la funzione che
+verrà eseguita alla sua occorrenza.  Per questo lo standard raccomanda di
+usare sempre questa funzione al posto di \func{signal} (che in genere viene
+definita tramite essa), in quanto permette un controllo completo su tutti gli
+aspetti della gestione di un segnale, sia pure al prezzo di una maggiore
+complessità d'uso.
 
 Se il puntatore \param{act} non è nullo, la funzione installa la nuova azione
 da esso specificata, se \param{oldact} non è nullo il valore dell'azione
@@ -1734,7 +1791,7 @@ che non consente di ottenere l'azione corrente senza installarne una nuova.
 
 Entrambi i puntatori fanno riferimento alla struttura \var{sigaction}, tramite
 la quale si specificano tutte le caratteristiche dell'azione associata ad un
-segnale.  Anch'essa è descritta dallo standard POSIX ed in Linux è definita
+segnale.  Anch'essa è descritta dallo standard POSIX.1 ed in Linux è definita
 secondo quanto riportato in \figref{fig:sig_sigaction}. Il campo
 \var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere
 più usato.
@@ -1743,7 +1800,8 @@ pi
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct sigaction {
+struct sigaction 
+{
     void (*sa_handler)(int);
     void (*sa_sigaction)(int, siginfo_t *, void *);
     sigset_t sa_mask;
@@ -1757,38 +1815,444 @@ struct sigaction {
   \label{fig:sig_sigaction}
 \end{figure}
 
-Come riportato in \figref{fig:sig_sigaction} in Linux \func{sigaction} permette
-di specificare il manipolatore in due forme diverse, indicate dai campi
-\var{sa\_handler} e \var{sa\_sigaction}; esse devono essere usate in maniera
-alternativa (in certe implementazioni questi vengono specificati come
-\ctyp{union}); la prima è quella classica usata anche con \func{signal}, la
-seconda permette invece di usare un manipolatore in grado di ricevere
-informazioni più dettagliate dal sistema (ad esempio il tipo di errore in caso
-di \macro{SIGFPE}).
-
+Come si può notare da quanto riportato in \figref{fig:sig_sigaction} in Linux
+\func{sigaction} permette di specificare il manipolatore in due forme diverse,
+indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere
+usate in maniera alternativa (in certe implementazioni questi vengono
+specificati come \ctyp{union}): la prima è quella classica usata anche con
+\func{signal}, la seconda permette invece di usare un manipolatore in grado di
+ricevere informazioni più dettagliate dal sistema (ad esempio il tipo di
+errore in caso di \macro{SIGFPE}), attraverso dei parametri aggiuntivi; per i
+dettagli si consulti la man page di \func{sigaction}).
+
+Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
+essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque
+sempre aggiunto il segnale che ne ha causato la chiamata, a meno che non si
+sia specificato con \var{sa\_flag} un comportamento diverso. Quando il
+manipolatore ritorna comunque la maschera dei segnali bloccati (vedi
+\secref{sec:sig_sigmask}) viene ripristinata al valore precedente
+l'invocazione.
+
+L'uso di questo campo permette ad esempio di risolvere il problema residuo
+dell'implementazione di \code{sleep} mostrata in
+\secref{fig:sig_sleep_incomplete}. In quel caso infatti se il segnale di
+allarme avesse interrotto un altro manipolatore questo non sarebbe stato
+eseguito correttamente; la cosa poteva essere prevenuta installando gli altri
+manipolatori usando \var{sa\_mask} per bloccare \macro{SIGALRM} durante la
+loro esecuzione. 
+Il valore di \var{sa\_flag} permette di specificare vari aspetti del
+comportamento di \func{sigaction}, e della reazione del processo ai vari
+segnali; i valori possibili ed il relativo significato sono riportati in
+\tabref{tab:sig_sa_flag}. 
 
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{SA\_NOCLDSTOP}& Se il segnale è \macro{SIGCHLD} allora non deve
+                           essere notificato quando il processo figlio viene
+                           fermato da uno dei segnali \macro{SIGSTOP},
+                           \macro{SIGTSTP}, \macro{SIGTTIN} o 
+                           \macro{SIGTTOU}.\\
+    \macro{SA\_ONESHOT}  & Ristabilisce l'azione per il segnale al valore di
+                           default una volta che il manipolatore è stato
+                           lanciato, riproduce cioè il comportamento della
+                           semantica inaffidabile.\\  
+    \macro{SA\_RESETHAND}& Sinonimo di \macro{SA\_ONESHOT}. \\
+    \macro{SA\_RESTART}  & Riavvia automaticamente le \textit{slow system
+                           call} quando vengono interrotte dal suddetto
+                           segnale; riproduce cioè il comportamento standard
+                           di BSD.\\ 
+    \macro{SA\_NOMASK}   & Evita che il segnale corrente sia bloccato durante
+                           l'esecuzione del manipolatore.\\
+    \macro{SA\_NODEFER}  & Sinonimo di \macro{SA\_NOMASK}.\\
+    \macro{SA\_SIGINFO}  & Deve essere specificato quando si vuole usare un
+                           manipolatore in forma estesa usando
+                           \var{sa\_sigaction} al posto di \var{sa\_handler}.\\
+    \macro{SA\_ONSTACK}  & Stabilisce l'uso di uno stack alternativo per
+                           l'esecuzione del manipolatore (vedi
+                           \secref{sec:sig_specific_features}).\\ 
+    \hline
+  \end{tabular}
+  \caption{Valori del campo \var{sa\_flag} della struttura \var{sigaction}.}
+  \label{tab:sig_sa_flag}
+\end{table}
 
+Benché sia possibile usare nello stesso programma sia \func{sigaction} che
+\func{signal} occorre molta attenzione, in quanto le due funzioni possono
+interagire in maniera anomala. Infatti l'azione specificata con
+\var{sigaction} contiene un maggior numero di informazioni rispetto al
+semplice indirizzo del manipolatore restituito da \func{signal}.  Per questo
+motivo se si usa quest'ultima per installare un manipolatore sostituendone uno
+precedentemente installato con \func{sigaction}, non sarà possibile effettuare
+un ripristino corretto dello stesso.
+
+Per questo è sempre opportuno usare \func{sigaction}, che è in grado di
+ripristinare correttamente un manipolatore precedente, anche se questo è stato
+installato con \func{signal}. In generale poi non è il caso di usare il valore
+di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato
+che in certi sistemi questi possono essere diversi. In generale dunque, a meno
+che non si sia vincolati allo standard ISO C, è sempre il caso di evitare
+l'uso di \func{signal} a favore di \func{sigaction}.
+
+Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
+che abbia le stesse caratteristiche di \func{signal} a definire una funzione
+equivalente (che si trova come \code{inline} nel file \file{wrapper.h} dei
+sorgenti allegati) \code{Signal}, riportata in \figref{fig:sig_Signal_code}.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+typedef void SigFunc(int);
+inline SigFunc * Signal(int signo, SigFunc *func) 
+{
+    struct sigaction new_handl, old_handl;
+    new_handl.sa_handler=func;
+    /* clear signal mask: no signal blocked during execution of func */
+    if (sigemptyset(&new_handl.sa_mask)!=0){  /* initialize signal set */
+        perror("cannot initializes the signal set to empty"); /* see mess. */
+        exit(1);
+    }
+    new_handl.sa_flags=0;                  /* init to 0 all flags */
+    /* change action for signo signal */
+    if (sigaction(signo,&new_handl,&old_handl)){ 
+        perror("sigaction failed on signal action setting");
+        exit(1);
+    }
+    return (old_handl.sa_handler);
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Una funzione equivalente a \func{signal} definita attraverso
+    \func{sigaction}.} 
+  \label{fig:sig_Signal_code}
+\end{figure}
 
-\subsection{La gestione del blocco dei segnali}
+\subsection{La gestione della \textsl{maschera dei segnali} o 
+  \textit{signal mask}}
 \label{sec:sig_sigmask}
 
-Una delle informazioni che ciascun processo porta con se è l'insieme
-(anch'esso un signal set) dei segnali bloccati (la cosiddetta \textit{signal
-  mask}, mantenuta nel campo \var{blocked} di \var{task\_struct}); abbiamo
-accennato in \secref{sec:proc_fork} che essa viene ereditata da un processo 
+Come spiegato in \secref{sec:sig_semantics} tutti i moderni sistemi unix-like
+permettono si bloccare temporaneamente (o di eliminare completamente, settando
+\macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è
+fatto specificando la cosiddetta \textsl{maschera dei segnali} (o
+\textit{signal mask}) del processo\footnote{nel caso di Linux essa è mantenuta
+  dal campo \var{blocked} della \var{task\_struct} del processo.} cioè
+l'insieme dei segnali la cui consegna è bloccata. Abbiamo accennato in
+\secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre
+alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente
+che essa può essere modificata, durante l'esecuzione di un manipolatore,
+attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}.
+
+Uno dei problemi evidenziatisi con l'esempio di \secref{fig:sig_event_wrong} è
+che in molti casi è necessario proteggere delle sezioni di codice (nel caso in
+questione la sezione fra il controllo e la eventuale cancellazione del flag
+che testimoniava l'avvenuta occorrenza del segnale) in modo da essere sicuri
+che essi siano eseguiti senza interruzioni.
+
+Le operazioni più semplici, come l'assegnazione o il controllo di una
+variabile (per essere sicuri si può usare il tipo \type{sig\_atomic\_t}) di
+norma sono atomiche, quando occorrono operazioni più complesse si può invece
+usare la funzione \func{sigprocmask} che permette di bloccare uno o più
+segnali; il suo prototipo è:
+\begin{prototype}{signal.h}
+{int sigprocmask(int how, const sigset\_t *set, sigset\_t *oldset)} 
+  
+  Cambia la \textsl{maschera dei segnali} del processo corrente.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, nel qual caso \var{errno} assumerà i valori:
+  \begin{errlist}
+  \item[\macro{EINVAL}] Si è specificato un numero di segnale invalido.
+  \item[\macro{EFAULT}] Si sono specificati indirizzi non validi.
+  \end{errlist}}
+\end{prototype}
 
+La funzione usa l'insieme di segnali dato all'indirizzo \param{set} per
+modificare la maschera dei segnali del processo corrente. La modifica viene
+effettuata a seconda del valore dell'argomento \param{how}, secondo le modalità
+specificate in \tabref{tab:sig_procmask_how}. Qualora si specifichi un valore
+non nullo per \param{oldset} la maschera dei segnali corrente viene salvata a
+quell'indirizzo.
 
-\subsection{Le funzioni \func{sigpending} e \func{sigsuspend}}
-\label{sec:sig_sigpending}
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{SIG\_BLOCK}   & L'insieme dei segnali bloccati è l'unione fra
+                           quello specificato e quello corrente.\\
+    \macro{SIG\_UNBLOCK} & I segnali specificati in \param{set} sono rimossi
+                           dalla maschera dei segnali, specificare la
+                           cancellazione di un segnale non bloccato è legale.\\
+    \macro{SIG\_SETMASK} & La maschera dei segnali è settata al valore
+                           specificato da \param{set}.\\
+    \hline
+  \end{tabular}
+  \caption{Valori e significato dell'argomento \param{how} della funzione
+    \func{sigprocmask}.}
+  \label{tab:sig_procmask_how}
+\end{table}
 
+In questo modo diventa possibile proteggere delle sezioni di codice bloccando
+l'insieme di segnali voluto per poi riabilitarli alla fine della sezione
+critica. La funzione permette di risolvere problemi come quelli mostrati in
+\secref{fig:sig_event_wrong}, proteggendo la sezione fra il controllo del flag
+e la sua cancellazione. 
+
+La funzione può essere usata anche all'interno di un manipolatore, ad esempio
+per riabilitare la consegna del segnale che l'ha invocato, in questo caso però
+occorre ricordare che qualunque modifica alla maschera dei segnali viene
+perduta alla conclusione del terminatore. 
+
+Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte
+dei casi di race condition restano aperte alcune possibilità legate all'uso di
+\func{pause}; il caso è simile a quello del problema illustrato nell'esempio
+di \secref{fig:sig_sleep_incomplete}, e cioè la possibilità che il processo
+riceva il segnale che si intende usare per uscire dallo stato di attesa
+invocato con \func{pause} immediatamente prima dell'esecuzione di
+quest'ultima. Per poter effettuare atomicamente la modifica della maschera dei
+segnali (di solito attivandone uno specifico) insieme alla sospensione del
+processo lo standard POSIX ha previsto la funzione \func{sigsuspend}, il cui
+prototipo è:
+\begin{prototype}{signal.h}
+{int sigsuspend(const sigset\_t *mask)} 
+  
+  Setta la \textit{signal mask} specificata, mettendo in attesa il processo.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, nel qual caso \var{errno} assumerà i valori:
+  \begin{errlist}
+  \item[\macro{EINVAL}] Si è specificato un numero di segnale invalido.
+  \item[\macro{EFAULT}] Si sono specificati indirizzi non validi.
+  \end{errlist}}
+\end{prototype}
 
+Come esempio dell'uso di queste funzioni proviamo a riscrivere un'altra volta
+l'esempio di implementazione di \code{sleep}. Abbiamo accennato in
+\secref{sec:sig_sigaction} come con \func{sigaction} sia possibile bloccare
+\macro{SIGALRM} nell'installazione dei manipolatori degli altri segnali, per
+poter usare l'implementazione vista in \secref{fig:sig_sleep_incomplete} senza
+interferenze.  Questo però comporta una precauzione ulteriore al semplice uso
+della funzione, vediamo allora come usando la nuova interfaccia è possibile
+ottenere un'implementazione, riportata in \figref{fig:sig_sleep_ok} che non
+presenta neanche questa necessità.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+#include <unistd.h>      /* unix standard library */
+#include <signal.h>      /* POSIX signal library */
+void alarm_hand(int);
+unsigned int sleep(unsigned int seconds)
+{
+/* 
+ * Variables definition  
+ */
+    struct sigaction new_action, old_action;
+    sigset_t old_mask, stop_mask, sleep_mask;
+    /* set the signal handler */
+    sigemptyset(&new_action.sa_mask);              /* no signal blocked */
+    new_action.sa_handler = alarm_hand;            /* set handler */
+    new_action.sa_flags = 0;                       /* no flags */
+    sigaction(SIGALRM, &new_action, &old_action);  /* install action */
+    /* block SIGALRM to avoid race conditions */
+    sigemptyset(&stop_mask);                       /* init mask to empty */
+    sigaddset(&stop_mask, SIGALRM);                /* add SIGALRM */
+    sigprocmask(SIG_BLOCK, &stop_mask, &old_mask); /* add SIGALRM to blocked */
+    /* send the alarm */
+    alarm(seconds); 
+    /* going to sleep enabling SIGALRM */
+    sleep_mask = old_mask;                         /* take mask */
+    sigdelset(&sleep_mask, SIGALRM);               /* remove SIGALRM */
+    sigsuspend(&sleep_mask);                       /* go to sleep */
+    /* restore previous settings */
+    sigprocmask(SIG_SETMASK, &old_mask, NULL);     /* reset signal mask */    
+    sigaction(SIGALRM, &old_action, NULL);         /* reset signal action */
+    /* return remaining time */
+    return alarm(0);
+}
+/*
+ * Signal Handler for SIGALRM
+ */
+void alarm_hand(int sig) 
+{
+    return;     /* just return to interrupt sigsuspend */
+}
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Una implementazione completa di \func{sleep}.} 
+  \label{fig:sig_sleep_ok}
+\end{figure}
 
+Per evitare i problemi di interferenza con gli altri segnali in questo caso
+non si è usato l'approccio di \figref{fig:sig_sleep_incomplete} evitando l'uso
+di \func{longjmp}. Come in precedenza il manipolatore (\texttt{\small 35-37})
+non esegue nessuna operazione, limitandosi a ritornare per interrompere il
+programma messo in attesa.
+
+La prima parte della funzione (\texttt{\small 11-15}) provvede ad installare
+l'opportuno manipolatore per \macro{SIGALRM}, salvando quello originario, che
+sarà ripristinato alla conclusione della stessa (\texttt{\small 28}); il passo
+successivo è quello di bloccare \macro{SIGALRM} (\texttt{\small 17-19}) per
+evitare che esso possa essere ricevuto dal processo fra l'esecuzione di
+\func{alarm} (\texttt{\small 21}) e la sospensione dello stesso. Nel fare
+questo si salva la maschera corrente dei segnali, che sarà ripristinata alla
+fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali
+\var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
+\func{sigsuspend}.  
+
+In questo modo non sono più possibili race condition dato che \macro{SIGALRM}
+viene disabilitato con \func{sigprocmask} fino alla chiamata di
+\func{sigsuspend}. Questo metodo è assolutamente generale e può essere
+applicato a qualunque altra situazione in cui si deve attendere per un
+segnale, i passi sono sempre i seguenti:
+\begin{enumerate}
+\item Leggere la maschera dei segnali corrente e bloccare il segnale voluto
+  con \func{sigprocmask}. 
+\item Mandare il processo in attesa con \func{sigsuspend} abilitando la
+  ricezione del segnale voluto.
+\item Ripristinare la maschera dei segnali originaria.
+\end{enumerate}
+Per quanto possa sembrare strano bloccare la ricezione di un segnale per poi
+riabilitarla immediatamente dopo, in questo modo si evita il deadlock dovuto
+all'arrivo del segnale prima dell'esecuzione di \func{sigsuspend}.
+
+
+\subsection{Ulteriori funzioni di gestione}
+\label{sec:sig_specific_features}
+
+In questa ultimo paragrafo esamineremo varie funzioni di gestione dei segnali
+non descritte finora, relative agli aspetti meno utilizzati. La prima di esse
+è \func{sigpending},  anch'essa introdotta dallo standard POSIX.1; il suo
+prototipo è:
+\begin{prototype}{signal.h}
+{int sigpending(sigset\_t *set)} 
+  
+Scrive in \param{set} l'insieme dei segnali pendenti.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore.}
+\end{prototype}
 
-\subsection{Funzioni rientranti e default dei segnali}
-\label{sec:sig_reentrant}
+La funzione permette di ricavare quali sono i segnali pendenti per il processo
+in corso, cioè i segnali che sono stato inviati dal kernel ma non sono stati
+ancora ricevuti dal processo in quanto bloccati. Non esiste una funzione
+equivalente nella vecchia interfaccia, ma essa è tutto sommato poco utile,
+dato che essa può solo assicurare che un segnale è stato inviato, dato che
+escluderne l'avvenuto invio al momento della chiamata non significa nulla
+rispetto a quanto potrebbe essere in un qualunque momento successivo.
+
+Una delle caratteristiche di BSD, disponibile anche in Linux, è la possibilità
+di usare uno stack alternativo per i segnali; è cioè possibile fare usare al
+sistema un altro stack (invece di quello relativo al processo, vedi
+\secref{sec:proc_mem_layout}) solo durante l'esecuzione di un
+manipolatore. L'uso di uno stack alternativo è del tutto trasparente ai
+manipolatori, occorre però seguire una certa procedura:
+\begin{enumerate}
+\item Allocare un'area di memoria di dimensione sufficiente da usare come
+  stack alternativo.
+\item Usare la funzione \func{sigaltstack} per rendere noto al sistema
+  l'esistenza e la locazione dello stack alternativo.
+\item Quando si installa un manipolatore occorre usare \func{sigaction}
+  specificando il flag \macro{SA\_ONSTACK} (vedi \tabref{tab:sig_sa_flag}) per
+  dire al sistema di usare lo stack alternativo durante l'esecuzione del
+  manipolatore. 
+\end{enumerate}
+
+In genere il primo passo viene effettuato allocando un'opportuna area di
+memoria con \code{malloc}; in \file{signal.h} sono definite due costanti,
+\macro{SIGSTKSZ} e \macro{MINSIGSTKSZ}, che possono essere utilizzate per
+allocare una quantità di spazio opportuna, in modo da evitare overflow. La
+prima delle due è la dimensione canonica per uno stack di segnali e di norma è
+sufficiente per tutti gli usi normali. La seconda è lo spazio che occorre al
+sistema per essere in grado di lanciare il manipolatore e la dimensione di uno
+stack alternativo deve essere sempre maggiore di questo valore. Quando si
+conosce esattamente quanto è lo spazio necessario al manipolatore gli si può
+aggiungere questo valore per allocare uno stack di dimensione sufficiente.
+
+Come accennato per poter essere usato lo stack per i segnali deve essere
+indicato al sistema attraverso la funzione \func{sigaltstack}; il suo
+prototipo è:
+\begin{prototype}{signal.h}
+{int sigaltstack(const stack\_t *ss, stack\_t *oss)}
+  
+Installa un nuovo stack per i segnali.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, nel qual caso \var{errno} assumerà i valori:
+
+  \begin{errlist}
+  \item[\macro{ENOMEM}] La dimensione specificata per il nuovo stack è minore
+  di \macro{MINSIGSTKSZ}.
+  \item[\macro{EPERM}] Uno degli indirizzi non è valido.
+  \item[\macro{EFAULT}] Si è cercato di cambiare lo stack alternativo mentre
+  questo è attivo (cioè il processo è in esecuzione su di esso).
+  \item[\macro{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
+  valore diverso da zero che non è \macro{SS\_DISABLE}.
+  \end{errlist}}
+\end{prototype}
+
+La funzione prende come argomenti puntatori ad una struttura di tipo
+\var{stack\_t}, definita in \figref{fig:sig_stack_t}. I due valori \param{ss}
+e \param{oss}, se non nulli, indicano rispettivamente il nuovo stack da
+installare e quello corrente (che viene restituito dalla funzione per un
+successivo ripristino).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+typedef struct {
+    void  *ss_sp;     /* Base address of stack */
+    int    ss_flags;  /* Flags */
+    size_t ss_size;   /* Number of bytes in stack */
+} stack_t;
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \var{stack\_t}.} 
+  \label{fig:sig_stack_t}
+\end{figure}
 
+Il campo \var{ss\_sp} di \var{stack\_t} indica l'indirizzo base dello stack,
+mentre \var{ss\_size} ne indica la dimensione; il campo \var{ss\_flags} invece
+indica lo stato dello stack. Nell'indicare un nuovo stack occorre
+inizializzare \var{ss\_sp} e \var{ss\_size} rispettivamente al puntatore e
+alla dimensione della memoria allocata, mentre \var{ss\_flags} deve essere
+nullo.  Se invece si vuole disabilitare uno stack occorre indicare
+\macro{SS\_DISABLE} come valore di \var{ss\_flags} e gli altri valori saranno
+ignorati.
+
+Se \param{oss} non è nullo verrà restituito dalla funzione indirizzo e
+dimensione dello stack corrente nei relativi campi, mentre \var{ss\_flags}
+potrà assumere il valore \macro{SS\_ONSTACK} se il processo è in esecuzione
+sullo stack alternativo (nel qual caso non è possibile cambiarlo) e
+\macro{SS\_DISABLE} se questo non è abilitato.
+
+In genere si installa uno stack alternativo per i segnali quando si teme di
+avere problemi di esaurimento dello stack standard o di superamento di un
+limite imposto con chiamata de tipo \code{setrlimit(RLIMIT\_STACK, \&rlim)}.
+In tal caso infatti si avrebbe un segnale di \macro{SIGSEGV}, che potrebbe
+essere gestito soltanto avendo abilitato uno stack alternativo. 
+
+Si tenga presente che le funzioni chiamate durante l'esecuzione sullo stack
+alternativo continueranno ad usare quest'ultimo, che, al contrario di quanto
+avviene per lo stack ordinario dei processi, non si accresce automaticamente
+(ed infatti eccederne le dimensioni può portare a conseguenze imprevedibili).
+Si ricordi infine che una chiamata ad una funzione della famiglia
+\func{exec} cancella ogni stack alternativo.