+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/siginfo_t.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{siginfo\_t}.}
+ \label{fig:sig_siginfo_t}
+\end{figure}
+
+Installando un gestore di tipo \var{sa\_sigaction} diventa allora possibile
+accedere alle informazioni restituite attraverso il puntatore a questa
+struttura. Tutti i segnali impostano i campi \var{si\_signo}, che riporta il
+numero del segnale ricevuto, \var{si\_errno}, che riporta, quando diverso da
+zero, il codice dell'errore associato al segnale, e \var{si\_code}, che viene
+usato dal kernel per specificare maggiori dettagli riguardo l'evento che ha
+causato l'emissione del segnale.
+
+In generale \var{si\_code} contiene, per i segnali generici, per quelli
+real-time e per tutti quelli inviati tramite \func{kill}, informazioni circa
+l'origine del segnale (se generato dal kernel, da un timer, da \func{kill},
+ecc.). Alcuni segnali però usano \var{si\_code} per fornire una informazione
+specifica: ad esempio i vari segnali di errore (\const{SIGFPE},
+\const{SIGILL}, \const{SIGBUS} e \const{SIGSEGV}) lo usano per fornire
+maggiori dettagli riguardo l'errore (come il tipo di errore aritmetico, di
+istruzione illecita o di violazione di memoria) mentre alcuni segnali di
+controllo (\const{SIGCHLD}, \const{SIGTRAP} e \const{SIGPOLL}) forniscono
+altre informazioni specifiche. In tutti i casi il valore del campo è
+riportato attraverso delle costanti (le cui definizioni si trovano
+\file{bits/siginfo.h}) il cui elenco dettagliato è disponibile nella pagina di
+manuale di \func{sigaction}.
+
+Il resto della struttura è definito come \ctyp{union} ed i valori
+eventualmente presenti dipendono dal segnale, così \const{SIGCHLD} ed i
+segnali real-time (vedi sez.~\ref{sec:sig_real_time}) inviati tramite
+\func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi valori corrispondenti
+al processo che ha emesso il segnale, \const{SIGILL}, \const{SIGFPE},
+\const{SIGSEGV} e \const{SIGBUS} avvalorano \var{si\_addr} con l'indirizzo in
+cui è avvenuto l'errore, \const{SIGIO} (vedi
+sez.~\ref{sec:file_asyncronous_io}) avvalora \var{si\_fd} con il numero del
+file descriptor e \var{si\_band} per i dati urgenti su un
+socket\index{socket}.
+
+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
+\struct{sigaction} contiene un maggior numero di informazioni rispetto al
+semplice indirizzo del gestore restituito da \func{signal}. Per questo motivo
+se si usa quest'ultima per installare un gestore 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 gestore 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 definitiva dunque, a
+meno che non si sia vincolati all'aderenza stretta allo standard ISO C, è
+sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/Signal.c}
+ \end{minipage}
+ \normalsize
+ \caption{La funzione \func{Signal}, equivalente a \func{signal}, definita
+ attraverso \func{sigaction}.}
+ \label{fig:sig_Signal_code}
+\end{figure}
+
+Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata
+che abbia le stesse caratteristiche di \func{signal}, a definire attraverso
+\func{sigaction} una funzione equivalente, il cui codice è riportato in
+fig.~\ref{fig:sig_Signal_code} (il codice completo si trova nel file
+\file{SigHand.c} nei sorgenti allegati). Si noti come, essendo la funzione
+estremamente semplice, è definita come \direct{inline}.\footnote{la direttiva
+ \direct{inline} viene usata per dire al compilatore di trattare la funzione
+ cui essa fa riferimento in maniera speciale inserendo il codice direttamente
+ nel testo del programma. Anche se i compilatori più moderni sono in grado
+ di effettuare da soli queste manipolazioni (impostando le opportune
+ ottimizzazioni) questa è una tecnica usata per migliorare le prestazioni per
+ le funzioni piccole ed usate di frequente (in particolare nel kernel, dove
+ in certi casi le ottimizzazioni dal compilatore, tarate per l'uso in user
+ space, non sono sempre adatte). In tal caso infatti le istruzioni per creare
+ un nuovo frame nello stack per chiamare la funzione costituirebbero una
+ parte rilevante del codice, appesantendo inutilmente il programma.
+ Originariamente questo comportamento veniva ottenuto con delle macro, ma
+ queste hanno tutta una serie di problemi di sintassi nel passaggio degli
+ argomenti (si veda ad esempio \cite{PratC}) che in questo modo possono
+ essere evitati.}
+
+
+
+\subsection{La gestione della \textsl{maschera dei segnali} o
+ \textit{signal mask}}
+\label{sec:sig_sigmask}
+
+\index{\textit{signal mask}|(}
+Come spiegato in sez.~\ref{sec:sig_semantics} tutti i moderni sistemi unix-like
+permettono di bloccare temporaneamente (o di eliminare completamente,
+impostando \const{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 \struct{task\_struct} del
+ processo.} cioè l'insieme dei segnali la cui consegna è bloccata. Abbiamo
+accennato in sez.~\ref{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 gestore, attraverso l'uso dal campo \var{sa\_mask} di \struct{sigaction}.
+
+Uno dei problemi evidenziatisi con l'esempio di fig.~\ref{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 eseguite 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 \funcd{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[\errcode{EINVAL}] Si è specificato un numero di segnale invalido.
+ \item[\errcode{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 tab.~\ref{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
+ \const{SIG\_BLOCK} & L'insieme dei segnali bloccati è l'unione fra
+ quello specificato e quello corrente.\\
+ \const{SIG\_UNBLOCK} & I segnali specificati in \param{set} sono rimossi
+ dalla maschera dei segnali, specificare la
+ cancellazione di un segnale non bloccato è legale.\\
+ \const{SIG\_SETMASK} & La maschera dei segnali è impostata 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
+fig.~\ref{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 gestore, 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\index{\textit{race~condition}} restano aperte
+alcune possibilità legate all'uso di \func{pause}; il caso è simile a quello
+del problema illustrato nell'esempio di fig.~\ref{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
+\funcd{sigsuspend}, il cui prototipo è:
+\begin{prototype}{signal.h}
+{int sigsuspend(const sigset\_t *mask)}
+
+ Imposta 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[\errcode{EINVAL}] Si è specificato un numero di segnale invalido.
+ \item[\errcode{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
+sez.~\ref{sec:sig_sigaction} come con \func{sigaction} sia possibile bloccare
+\const{SIGALRM} nell'installazione dei gestori degli altri segnali, per poter
+usare l'implementazione vista in fig.~\ref{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 fig.~\ref{fig:sig_sleep_ok} che non
+presenta neanche questa necessità.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/sleep.c}
+ \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 fig.~\ref{fig:sig_sleep_incomplete} evitando
+l'uso di \func{longjmp}. Come in precedenza il gestore (\texttt{\small 27-30})
+non esegue nessuna operazione, limitandosi a ritornare per interrompere il
+programma messo in attesa.
+
+La prima parte della funzione (\texttt{\small 6-10}) provvede ad installare
+l'opportuno gestore per \const{SIGALRM}, salvando quello originario, che
+sarà ripristinato alla conclusione della stessa (\texttt{\small 23}); il passo
+successivo è quello di bloccare \const{SIGALRM} (\texttt{\small 11-14}) per
+evitare che esso possa essere ricevuto dal processo fra l'esecuzione di
+\func{alarm} (\texttt{\small 16}) e la sospensione dello stesso. Nel fare
+questo si salva la maschera corrente dei segnali, che sarà ripristinata alla
+fine (\texttt{\small 22}), e al contempo si prepara la maschera dei segnali
+\var{sleep\_mask} per riattivare \const{SIGALRM} all'esecuzione di
+\func{sigsuspend}.
+
+In questo modo non sono più possibili race
+condition\index{\textit{race~condition}} dato che \const{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\index{\textit{deadlock}} dovuto all'arrivo del segnale prima
+dell'esecuzione di \func{sigsuspend}.
+\index{\textit{signal mask}|)}
+
+
+\subsection{Ulteriori funzioni di gestione}
+\label{sec:sig_specific_features}
+
+In questo ultimo paragrafo esamineremo le rimanenti funzioni di gestione dei
+segnali non descritte finora, relative agli aspetti meno utilizzati e più
+``\textsl{esoterici}'' della interfaccia.
+
+La prima di queste funzioni è \funcd{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 stati 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
+sez.~\ref{sec:proc_mem_layout}) solo durante l'esecuzione di un
+gestore. L'uso di uno stack alternativo è del tutto trasparente ai
+gestori, 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 gestore occorre usare \func{sigaction}
+ specificando il flag \const{SA\_ONSTACK} (vedi tab.~\ref{tab:sig_sa_flag})
+ per dire al sistema di usare lo stack alternativo durante l'esecuzione del
+ gestore.
+\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,
+\const{SIGSTKSZ} e \const{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 gestore e la dimensione di uno stack alternativo deve essere sempre
+maggiore di questo valore. Quando si conosce esattamente quanto è lo spazio
+necessario al gestore 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 \funcd{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: