Correzioni varie
[gapil.git] / signal.tex
index 940b921157b4a58fa89d7b1a09fc2931fc30dccf..09f8325543a3370c5247a3f9877952a6502e02e6 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
@@ -883,11 +872,11 @@ con il precedente prototipo si pu
 \begin{verbatim}
     typedef void (* sighandler_t)(int) 
 \end{verbatim}
-e cioè un puntatore ad una funzione \type{void} (cioè senza valore di ritorno)
-e che prende un argomento di tipo \type{int}.\footnote{si devono usare le
+e cioè un puntatore ad una funzione \ctyp{void} (cioè senza valore di ritorno)
+e che prende un argomento di tipo \ctyp{int}.\footnote{si devono usare le
   parentesi intorno al nome della funzione per via delle precedenze degli
   operatori del C, senza di esse si sarebbe definita una funzione che ritorna
-  un puntatore a \type{void} e non un puntatore ad una funzione \type{void}.}
+  un puntatore a \ctyp{void} e non un puntatore ad una funzione \ctyp{void}.}
 La funzione \func{signal} quindi restituisce e prende come secondo argomento
 un puntatore a una funzione di questo tipo, che è appunto il manipolatore del
 segnale.
@@ -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
@@ -957,6 +946,15 @@ la funzione \func{kill}; il cui prototipo 
   \headdecl{signal.h}
   \funcdecl{int kill(pid\_t pid, int sig)} Invia il segnale \param{sig} al
   processo specificato con \param{pid}.
+  
+  \bodydesc{ La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\macro{EINVAL}] Il segnale specificato non esiste.
+    \item[\macro{ESRCH}] Il processo selezionato non esiste.
+    \item[\macro{EPERM}] Non si hanno privilegi sufficienti ad inviare il
+      segnale.
+    \end{errlist}}
 \end{functions}
 
 Lo standard POSIX prevede che il valore 0 per \param{sig} sia usato per
@@ -992,13 +990,24 @@ riportati in \tabref{tab:sig_kill_values}.
   \label{tab:sig_kill_values}
 \end{table}
 
-
 Si noti pertanto che la funzione \code{raise(sig)} può essere definita in
 termini di \func{kill}, ed è sostanzialmente equivalente ad una
 \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.
 
+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
@@ -1021,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.}
@@ -1035,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
@@ -1055,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}.
@@ -1132,12 +1141,6 @@ struct itimerval
     struct timeval it_interval; /* next value */
     struct timeval it_value;    /* current value */
 };
-
-struct timeval 
-{
-    long tv_sec;                /* seconds */
-    long tv_usec;               /* microseconds */
-};
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
@@ -1242,7 +1245,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)}
@@ -1327,9 +1330,9 @@ Lo standard richiede che la funzione sia implementata in maniera del tutto
 indipendente da \func{alarm}\footnote{nel caso di Linux questo è fatto
   utilizzando direttamente il timer del kernel.} e sia utilizzabile senza
 interferenze con l'uso di \macro{SIGALRM}. La funzione prende come parametri
-delle strutture di tipo \var{timespec}, la cui definizione è riportata in 
-\figref{fig:sig_timespec_def}, che permettono di specificare un tempo con una
-precisione (teorica) fino al nanosecondo. 
+delle strutture di tipo \var{timespec}, la cui definizione è riportata in
+\figref{fig:sys_timeval_struct}, che permettono di specificare un tempo con
+una precisione (teorica) fino al nanosecondo.
 
 La funzione risolve anche il problema di proseguire l'attesa dopo
 l'interruzione dovuta ad un segnale; infatti in tal caso in \param{rem} viene
@@ -1346,21 +1349,6 @@ sia scarico ed il processa venga immediatamente rimesso in esecuzione); per
 questo motivo il valore restituito in \param{rem} è sempre arrotondato al
 multiplo successivo di 1/\macro{HZ}.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct timespec {
-    time_t  tv_sec;         /* seconds */
-    long    tv_nsec;        /* nanoseconds */
-};
-    \end{lstlisting}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \var{timespec} di \func{nanosleep}.} 
-  \label{fig:sig_timespec_def}
-\end{figure}
-
 In realtà è possibile ottenere anche pause più precise del centesimo di
 secondo usando politiche di scheduling real time come \macro{SCHED\_FIFO} o
 \macro{SCHED\_RR}; in tal caso infatti il meccanismo di scheduling ordinario
@@ -1375,7 +1363,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
@@ -1391,7 +1379,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.
 
@@ -1406,7 +1394,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>
@@ -1464,8 +1452,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.
 
@@ -1493,54 +1481,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 
@@ -1553,13 +1542,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}.
@@ -1585,7 +1574,8 @@ unsigned int sleep(unsigned int seconds)
     /* remove alarm, return remaining time */
     return alarm(0);
 }
-void alarm_hand(int sig) {
+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");
@@ -1604,7 +1594,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.
 
@@ -1612,43 +1602,185 @@ 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{Gli \textsl{insiemi di segnali} o \textit{signal set}}
+\label{sec:sig_sigset}
+
+Come evidenziato nel paragrafo precedente, le funzioni di gestione dei segnali
+dei primi Unix, nate con la semantica inaffidabile, hanno dei limiti non
+superabili; in particolare non è prevista nessuna funzione che permetta di
+gestire gestire il blocco dei segnali o di verificare lo stato dei segnali
+pendenti.
+
+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 insieme di segnali
+  vuoto (in cui non c'è nessun segnale).
+  \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} all'insieme di segnali \param{set}.
+
+  \funcdecl{int sigdelset(sigset\_t *set, int signum)} Toglie il segnale
+  \param{signum} dall'insieme di segnali \param{set}.
+  
+  \funcdecl{int sigismember(const sigset\_t *set, int signum)} Controlla se il
+  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
+    altrimenti. In caso di errore tutte ritornano -1, con \var{errno} settata a
+    \macro{EINVAL} (il solo errore possibile è che \param{signum} non sia un
+    segnale valido).}
+\end{functions}
+
+Dato che in generale non si può fare conto sulle caratteristiche di una
+implementazione (non è detto che si disponga di un numero di bit sufficienti
+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 insieme di segnali per specificare quali segnali si vuole
+bloccare, o per riottenere dalle varie funzioni di gestione la maschera dei
+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}
 
-Per i limiti che hanno le funzioni originarie dei primi Unix nella gestione
-dei segnali, evidenziati al paragrafo precedente, lo standard POSIX ha
-introdotto una interfaccia di gestione completamente diversa, che prevede
-tutta una serie di nuove funzioni la principale delle quali è
-\func{sigaction}, che lo standard raccomanda come sostituta di \func{signal}
-(che da essa infatti può essere ottenuta); il suo prototipo è:
-
+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:
   \begin{errlist}
   \item[\macro{EINVAL}] Si è specificato un numero di segnale invalido o si è
-  cercato di installare il manipolatore per \macro{SIGKILL} o \macro{SIGSTOP}.
-\item[\macro{EFAULT}] Si sono specificati indirizzi non validi.
+    cercato di installare il manipolatore per \macro{SIGKILL} o
+    \macro{SIGSTOP}.
+  \item[\macro{EFAULT}] Si sono specificati indirizzi non validi.
   \end{errlist}}
 \end{prototype}
 
-La struttura \var{sigaction} è anch'essa definita dallo standard POSIX, che
-prevede abbia la forma: 
+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
+corrente viene restituito indietro.  Questo permette (specificando \param{act}
+nullo e \param{oldact} non nullo) di superare uno dei limiti di \func{signal},
+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.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.
+
 \begin{figure}[!htb]
   \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;
@@ -1662,21 +1794,508 @@ struct sigaction {
   \label{fig:sig_sigaction}
 \end{figure}
 
+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}
 
-\subsection{Le funzioni \func{sigprocmask} e \func{sigpending}}
-\label{sec:sig_sigpending}
+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 attraverso \func{sigaction}; la funzione è \code{Signal}, e si
+trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti
+allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso
+in seguito. 
 
+\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 della \textsl{maschera dei segnali} o 
+  \textit{signal mask}}
+\label{sec:sig_sigmask}
+
+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.
 
+\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}
 
-\subsection{Funzioni rientranti e default dei segnali}
-\label{sec:sig_reentrant}
+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à.
 
-, affrontando inoltre le varie problematiche di programmazione che si devono
-tenere presenti quando si ha a che fare con essi.
+\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}
+
+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.
+
+Abbiamo visto in \secref{fig:sig_sleep_incomplete} come si possa usare
+\func{longjmp} per uscire da un manipolatore rientrando direttamente nel corpo
+del programma; sappiamo però che nell'esecuzione di un manipolatore il segnale
+che l'ha invocato viene bloccato, e abbiamo detto che possiamo ulteriormente
+modificarlo con \func{sigprocmask}. 
+
+Resta quindi il problema di cosa succede alla maschera dei segnali quando si
+esce da un manipolatore usando questa funzione. Il comportamento dipende
+dall'implementazione; in particolare BSD ripristina la maschera dei segnali
+precedente l'invocazione, come per un normale ritorno, mentre System V no. Lo
+standard POSIX.1 non specifica questo comportamento per \func{setjmp} e
+\func{longjmp}, ed il comportamento delle \acr{glibc} dipende da quale delle
+caratteristiche si sono abilitate con le macro viste in
+\secref{sec:intro_gcc_glibc_std}.
+
+Lo standard POSIX però prevede anche la presenza di altre due funzioni
+\func{sigsetjmp} e \func{siglongjmp}, che permettono di decidere quale dei due
+comportamenti il programma deve assumere; i loro prototipi sono:
+\begin{functions}
+  \headdecl{setjmp.h} 
+  
+  \funcdecl{int sigsetjmp(sigjmp\_buf env, int savesigs)} Salva il contesto
+  dello stack per un salto non locale.
+  \funcdecl{void siglongjmp(sigjmp\_buf env, int val)} Esegue un salto non
+  locale su un precedente contesto.
+
+  \bodydesc{Le due funzioni sono identiche alle analoghe \func{setjmp} e
+    \func{longjmp} di \secref{sec:proc_longjmp}, ma consentono di specificare
+    il comportamento sul ripristino o meno della maschera dei segnali.}
+\end{functions}
+
+Le due funzioni prendono come primo argomento la variabile su cui viene
+salvato il contesto dello stack per permettere il salto non locale; nel caso
+specifico essa è di tipo \type{sigjmp\_buf}, e non \type{jmp\_buf} come per le
+analoghe di \secref{sec:proc_longjmp} in quanto in questo caso viene salvata
+anche la maschera dei segnali.
+
+Nel caso di \func{sigsetjmp} se si specifica un valore di \param{savesigs}
+diverso da zero la maschera dei valori sarà salvata in \param{env} e
+ripristinata in un successivo \func{siglongjmp}; quest'ultima funzione, a
+parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
+\func{longjmp}.
+
+\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}