-Una delle caratteristiche di BSD, disponibile anche in Linux, è la possibilità
-di usare uno \itindex{stack} \textit{stack} alternativo per i segnali; è cioè
-possibile fare usare al sistema un altro \itindex{stack} \textit{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 \textit{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
- \textit{stack} alternativo;
-\item usare la funzione \func{sigaltstack} per rendere noto al sistema
- l'esistenza e la locazione dello \textit{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 \textit{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 \itindex{stack}
-\textit{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 \textit{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 \itindex{stack} \textit{stack} di dimensione sufficiente.
-
-Come accennato, per poter essere usato, lo \itindex{stack} \textit{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 \textit{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[\errcode{ENOMEM}] la dimensione specificata per il nuovo
- \textit{stack} è minore di \const{MINSIGSTKSZ}.
- \item[\errcode{EPERM}] uno degli indirizzi non è valido.
- \item[\errcode{EFAULT}] si è cercato di cambiare lo \textit{stack}
- alternativo mentre questo è attivo (cioè il processo è in esecuzione su di
- esso).
- \item[\errcode{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
- valore diverso da zero che non è \const{SS\_DISABLE}.
- \end{errlist}}
-\end{prototype}
-
-La funzione prende come argomenti puntatori ad una struttura di tipo
-\var{stack\_t}, definita in fig.~\ref{fig:sig_stack_t}. I due valori
-\param{ss} e \param{oss}, se non nulli, indicano rispettivamente il nuovo
-\itindex{stack} \textit{stack} da installare e quello corrente (che viene
-restituito dalla funzione per un successivo ripristino).
-
-\begin{figure}[!htb]
- \footnotesize \centering
- \begin{minipage}[c]{15cm}
- \includestruct{listati/stack_t.h}
- \end{minipage}
- \normalsize
- \caption{La struttura \structd{stack\_t}.}
- \label{fig:sig_stack_t}
-\end{figure}
-
-Il campo \var{ss\_sp} di \struct{stack\_t} indica l'indirizzo base dello
-\itindex{stack} \textit{stack}, mentre \var{ss\_size} ne indica la dimensione;
-il campo \var{ss\_flags} invece indica lo stato dello \textit{stack}.
-Nell'indicare un nuovo \textit{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 \textit{stack} occorre indicare \const{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 \itindex{stack} \textit{stack} corrente nei relativi campi,
-mentre \var{ss\_flags} potrà assumere il valore \const{SS\_ONSTACK} se il
-processo è in esecuzione sullo \textit{stack} alternativo (nel qual caso non è
-possibile cambiarlo) e \const{SS\_DISABLE} se questo non è abilitato.
-
-In genere si installa uno \itindex{stack} \textit{stack} alternativo per i
-segnali quando si teme di avere problemi di esaurimento dello \textit{stack}
-standard o di superamento di un limite (vedi
-sez.~\ref{sec:sys_resource_limit}) imposto con chiamate del tipo
-\code{setrlimit(RLIMIT\_STACK, \&rlim)}. In tal caso infatti si avrebbe un
-segnale di \const{SIGSEGV}, che potrebbe essere gestito soltanto avendo
-abilitato uno \itindex{stack} \textit{stack} alternativo.
-
-Si tenga presente che le funzioni chiamate durante l'esecuzione sullo
-\textit{stack} alternativo continueranno ad usare quest'ultimo, che, al
-contrario di quanto avviene per lo \itindex{stack} \textit{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
-\textit{stack} alternativo.
-
-Abbiamo visto in fig.~\ref{fig:sig_sleep_incomplete} come si possa usare
-\func{longjmp} per uscire da un gestore rientrando direttamente nel corpo
-del programma; sappiamo però che nell'esecuzione di un gestore 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 gestore usando questa funzione. Il comportamento dipende
-dall'implementazione; in particolare la semantica usata da BSD prevede che sia
-ripristinata la maschera dei segnali precedente l'invocazione, come per un
-normale ritorno, mentre quella usata da 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
-sez.~\ref{sec:intro_gcc_glibc_std}.
-
-Lo standard POSIX però prevede anche la presenza di altre due funzioni
-\funcd{sigsetjmp} e \funcd{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 \textit{stack} per un \index{salto~non-locale} 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 sez.~\ref{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 \itindex{stack} \textit{stack} per permettere il
-\index{salto~non-locale} salto non-locale; nel caso specifico essa è di tipo
-\type{sigjmp\_buf}, e non \type{jmp\_buf} come per le analoghe di
-sez.~\ref{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}.
-
-
-\subsection{Criteri di programmazione per i gestori dei segnali}
-\label{sec:sig_signal_handler}
-
-Abbiamo finora parlato dei gestori dei segnali come funzioni chiamate in
-corrispondenza della consegna di un segnale. In realtà un gestore non può
-essere una funzione qualunque, in quanto esso può essere eseguito in
-corrispondenza all'interruzione in un punto qualunque del programma
-principale, cosa che ad esempio può rendere problematico chiamare all'interno
-di un gestore di segnali la stessa funzione che dal segnale è stata
-interrotta.
-
-\index{funzioni!sicure|(}
-
-Il concetto è comunque più generale e porta ad una distinzione fra quelle che
-POSIX chiama \textsl{funzioni insicure} (\textit{signal unsafe function}) e
-\textsl{funzioni sicure} (o più precisamente \textit{signal safe function});
-quando un segnale interrompe una funzione insicura ed il gestore chiama al suo
-interno una funzione insicura il sistema può dare luogo ad un comportamento
-indefinito, la cosa non avviene invece per le funzioni sicure.
-
-Tutto questo significa che la funzione che si usa come gestore di segnale deve
-essere programmata con molta cura per evirare questa evenienza e che non è
-possibile utilizzare al suo interno una qualunque funzione di sistema, se si
-vogliono evitare questi problemi si può ricorrere soltanto all'uso delle
-funzioni considerate sicure.