%% signal.tex
%%
-%% Copyright (C) 2000-2007 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2009 Simone Piccardi. Permission is granted to
%% copy, distribute and/or modify this document under the terms of the GNU Free
%% Documentation License, Version 1.1 or any later version published by the
%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
I segnali che rappresentano errori del programma (divisione per zero o
violazioni di accesso) hanno anche la caratteristica di scrivere un file di
\itindex{core~dump} \textit{core dump} che registra lo stato del processo (ed
-in particolare della memoria e dello \itindex{stack} stack) prima della
-terminazione. Questo può essere esaminato in seguito con un debugger per
-investigare sulla causa dell'errore. Lo stesso avviene se i suddetti segnali
-vengono generati con una \func{kill}.
+in particolare della memoria e dello \itindex{stack} \textit{stack}) prima
+della terminazione. Questo può essere esaminato in seguito con un debugger
+per investigare sulla causa dell'errore. Lo stesso avviene se i suddetti
+segnali vengono generati con una \func{kill}.
\section{La classificazione dei segnali}
file (posto nella directory corrente del processo e chiamato \file{core}) su
cui viene salvata un'immagine della memoria del processo (il cosiddetto
\itindex{core~dump} \textit{core dump}), che può essere usata da un debugger
-per esaminare lo stato dello \itindex{stack} stack e delle variabili al
-momento della ricezione del segnale.
+per esaminare lo stato dello \itindex{stack} \textit{stack} e delle variabili
+al momento della ricezione del segnale.
\begin{table}[htb]
\footnotesize
file eseguibile è corrotto o si stanno cercando di eseguire dei dati.
Quest'ultimo caso può accadere quando si passa un puntatore sbagliato al
posto di un puntatore a funzione, o si eccede la scrittura di un vettore di
- una variabile locale, andando a corrompere lo \itindex{stack} stack. Lo
- stesso segnale viene generato in caso di overflow dello \itindex{stack}
- stack o di problemi nell'esecuzione di un gestore. Se il gestore ritorna il
- comportamento del processo è indefinito.
-\item[\const{SIGSEGV}] Il nome deriva da \textit{segment violation}, e
- significa che il programma sta cercando di leggere o scrivere in una zona di
- memoria protetta al di fuori di quella che gli è stata riservata dal
- sistema. In genere è il meccanismo della protezione della memoria che si
- accorge dell'errore ed il kernel genera il segnale. Se il gestore
- ritorna il comportamento del processo è indefinito.
+ una variabile locale, andando a corrompere lo \itindex{stack}
+ \textit{stack}. Lo stesso segnale viene generato in caso di overflow dello
+ \itindex{stack} \textit{stack} o di problemi nell'esecuzione di un gestore.
+ Se il gestore ritorna il comportamento del processo è indefinito.
+\item[\const{SIGSEGV}] Il nome deriva da \itindex{segment~violation}
+ \textit{segment violation}, e significa che il programma sta cercando di
+ leggere o scrivere in una zona di memoria protetta al di fuori di quella che
+ gli è stata riservata dal sistema. In genere è il meccanismo della
+ protezione della memoria che si accorge dell'errore ed il kernel genera il
+ segnale. Se il gestore ritorna il comportamento del processo è indefinito.
È tipico ottenere questo segnale dereferenziando un puntatore nullo o non
inizializzato leggendo al di là della fine di un vettore.
\const{SIGSEGV} questo è un segnale che viene generato di solito quando si
dereferenzia un puntatore non inizializzato, la differenza è che
\const{SIGSEGV} indica un accesso non permesso su un indirizzo esistente
- (tipo fuori dallo heap o dallo \itindex{stack} stack), mentre \const{SIGBUS}
- indica l'accesso ad un indirizzo non valido, come nel caso di un puntatore
- non allineato.
+ (tipo fuori dallo heap o dallo \itindex{stack} \textit{stack}), mentre
+ \const{SIGBUS} indica l'accesso ad un indirizzo non valido, come nel caso di
+ un puntatore non allineato.
\item[\const{SIGABRT}] Il nome deriva da \textit{abort}. Il segnale indica che
il programma stesso ha rilevato un errore che viene riportato chiamando la
funzione \func{abort} che genera questo segnale.
per i motivi visti in sez.~\ref{sec:sig_semantics}, può essere ottenuto
chiamando \func{sysv\_signal}, una volta che si sia definita la macro
\macro{\_XOPEN\_SOURCE}. In generale, per evitare questi problemi, l'uso di
-\func{signal} (ed ogni eventuale ridefinizione della stessa) è da evitare;
-tutti i nuovi programmi dovrebbero usare \func{sigaction}.
+\func{signal}, che tra l'altro ha un comportamento indefinito in caso di
+processo \itindex{thread} multi-\textit{thread}, è da evitare; 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 \const{SIGFPE}, \const{SIGILL}, o
suo prototipo è:
\begin{prototype}{signal.h}{int raise(int sig)}
Invia il segnale \param{sig} al processo corrente.
-
+
\bodydesc{La funzione restituisce zero in caso di successo e $-1$ per un
errore, il solo errore restituito è \errval{EINVAL} qualora si sia
specificato un numero di segnale invalido.}
mai generato prima della scadenza programmata (l'arrotondamento cioè è sempre
effettuato per eccesso).
-% TODO: verificare cose è successo con l'introduzione nel kernel degli htrimer
+% TODO: verificare cose è successo con l'introduzione nel kernel con i timer
+% ad alta risoluzione
Una seconda causa di potenziali ritardi è che il segnale viene generato alla
scadenza del timer, ma poi deve essere consegnato al processo; se quest'ultimo
utilizzando direttamente il timer del kernel.} e sia utilizzabile senza
interferenze con l'uso di \const{SIGALRM}. La funzione prende come argomenti
delle strutture di tipo \struct{timespec}, la cui definizione è riportata in
-fig.~\ref{fig:sys_timeval_struct}, che permettono di specificare un tempo con
-una precisione (teorica) fino al nanosecondo.
+fig.~\ref{fig:sys_timespec_struct}, che permette di specificare un tempo con
+una precisione 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
semantica inaffidabile.\\
\const{SA\_ONESHOT} & Nome obsoleto, sinonimo non standard di
\const{SA\_RESETHAND}; da evitare.\\
- \const{SA\_ONSTACK} & Stabilisce l'uso di uno \itindex{stack} stack
- alternativo per l'esecuzione del gestore (vedi
- sez.~\ref{sec:sig_specific_features}).\\
+ \const{SA\_ONSTACK} & Stabilisce l'uso di uno \itindex{stack}
+ \textit{stack} alternativo per l'esecuzione del
+ gestore (vedi
+ sez.~\ref{sec:sig_specific_features}).\\
\const{SA\_RESTART} & Riavvia automaticamente le \textit{slow system
call} quando vengono interrotte dal suddetto
segnale; riproduce cioè il comportamento standard
gestore in forma estesa usando
\var{sa\_sigaction} al posto di
\var{sa\_handler}.\\
- \const{SA\_NOCLDWAIT}& Se il segnale è \const{SIGCHLD} allora o processi
- figli non divenire \textit{zombie} quando
+ \const{SA\_NOCLDWAIT}& Se il segnale è \const{SIGCHLD} allora i processi
+ figli non diventano \textit{zombie} quando
terminano.\footnotemark \\
\hline
\end{tabular}
\footnotetext{questa funzionalità è stata introdotta nel kernel 2.6 e va a
modificare il comportamento di \func{waitpid}.}
-% TODO con il 2.6 sono stati aggiunti SA_NOCLDWAIT e altro, documentare
-
Come si può notare in fig.~\ref{fig:sig_sigaction} \func{sigaction} permette
di utilizzare due forme diverse di gestore,\footnote{la possibilità è prevista
dallo standard POSIX.1b, ed è stata aggiunta nei kernel della serie 2.1.x
addizionale di tipo \var{sigcontext}, che adesso è deprecato.} da
specificare, a seconda dell'uso o meno del flag \const{SA\_SIGINFO},
rispettivamente attraverso i campi \var{sa\_sigaction} o
-\var{sa\_handler},\footnote{i due tipi devono essere usati in maniera
+\var{sa\_handler},\footnote{i due campi devono essere usati in maniera
alternativa, in certe implementazioni questi campi vengono addirittura
definiti come \ctyp{union}.} Quest'ultima è quella classica usata anche con
\func{signal}, mentre la prima permette di usare un gestore più complesso, in
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
+real-time e per tutti quelli inviati tramite da un processo con \func{kill} o
+affini, le informazioni circa l'origine del segnale stesso, ad esempio se
+generato dal kernel, da un timer, da \func{kill}, ecc. Il valore viene sempre
+espresso come una costante,\footnote{le definizioni di tutti i valori
+ possibili si trovano in \file{bits/siginfo.h}.} ed i valori possibili in
+questo caso sono riportati in tab.~\ref{tab:sig_sa_code_generic}.
+
+\begin{table}[!htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{SI\_USER} & generato da \func{kill} o \func{raise}.\\
+ \const{SI\_KERNEL} & inviato dal kernel.\\
+ \const{SI\_QUEUE} & inviato con \func{sigqueue} (vedi
+ sez.~\ref{sec:sig_real_time}).\\
+ \const{SI\_TIMER} & scadenza di un POSIX timer
+ (vedi sez.~\ref{sec:sig_timer_adv}).\\
+ \const{SI\_MESGQ} & inviato al cambiamento di stato di una coda di
+ messaggi POSIX (vedi
+ sez.~\ref{sec:ipc_posix_mq}).\footnotemark\\
+ \const{SI\_ASYNCIO}& una operazione di I/O asincrono (vedi
+ sez.~\ref{sec:file_asyncronous_access}) è stata
+ completata.\\
+ \const{SI\_SIGIO} & segnale di \const{SIGIO} da una coda (vedi
+ sez.~\ref{sec:file_asyncronous_operation}).\\
+ \const{SI\_TKILL} & inviato da \func{tkill} o \func{tgkill} (vedi
+ sez.~\ref{cha:threads_xxx}).\footnotemark\\
+ \hline
+ \end{tabular}
+ \caption{Valori del campo \var{sa\_code} della struttura \struct{sigaction}
+ per i segnali generici.}
+ \label{tab:sig_sa_code_generic}
+\end{table}
+
+\footnotetext[17]{introdotto con il kernel 2.6.6.}
+\footnotetext{introdotto con il kernel 2.4.19.}
+
+Nel caso di alcuni segnali però il valore di \var{si\_code} viene usato per
+fornire una informazione specifica relativa alle motivazioni della ricezione
+dello stesso; ad esempio i vari segnali di errore (\const{SIGILL},
+\const{SIGFPE}, \const{SIGSEGV} e \const{SIGBUS}) 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}.
+altre informazioni specifiche.
+
+In questo caso il valore del campo \var{si\_code} deve essere verificato nei
+confronti delle diverse costanti previste per ciascuno di detti
+segnali;\footnote{dato che si tratta di una costante, e non di una maschera
+ binaria, i valori numerici vengono riutilizzati e ciascuno di essi avrà un
+ significato diverso a seconda del segnale a cui è associato.} l'elenco
+dettagliato dei nomi di queste costanti è riportato nelle diverse sezioni di
+tab.~\ref{tab:sig_sa_code_special} che sono state ordinate nella sequenza in
+cui si sono appena citati i rispettivi segnali.\footnote{il prefisso del nome
+ indica comunque in maniera diretta il segnale a cui le costanti fanno
+ riferimento.}
+
+\begin{table}[!htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{ILL\_ILLOPC} & codice di operazione illegale.\\
+ \const{ILL\_ILLOPN} & operando illegale.\\
+ \const{ILL\_ILLADR} & modo di indirizzamento illegale.\\
+ \const{ILL\_ILLTRP} & trappola di processore illegale.\\
+ \const{ILL\_PRVOPC} & codice di operazione privilegiato.\\
+ \const{ILL\_PRVREG} & registro privilegiato.\\
+ \const{ILL\_COPROC} & errore del coprocessore.\\
+ \const{ILL\_BADSTK} & errore nello stack interno.\\
+ \hline
+ \const{FPE\_INTDIV} & divisione per zero intera.\\
+ \const{FPE\_INTOVF} & overflow intero.\\
+ \const{FPE\_FLTDIV} & divisione per zero in virgola mobile.\\
+ \const{FPE\_FLTOVF} & overflow in virgola mobile.\\
+ \const{FPE\_FLTUND} & underflow in virgola mobile.\\
+ \const{FPE\_FLTRES} & risultato in virgola mobile non esatto.\\
+ \const{FPE\_FLTINV} & operazione in virgola mobile non valida.\\
+ \const{FPE\_FLTSUB} & mantissa? fuori intervallo.\\
+ \hline
+ \const{SEGV\_MAPERR} & indirizzo non mappato.\\
+ \const{SEGV\_ACCERR} & permessi non validi per l'indirizzo.\\
+ \hline
+ \const{BUS\_ADRALN} & allineamento dell'indirizzo non valido.\\
+ \const{BUS\_ADRERR} & indirizzo fisico inesistente.\\
+ \const{BUS\_OBJERR} & errore hardware sull'indirizzo.\\
+ \hline
+ \const{TRAP\_BRKPT} & breakpoint sul processo.\\
+ \const{TRAP\_TRACE} & trappola di tracciamento del processo.\\
+ \hline
+ \const{CLD\_EXITED} & il figlio è uscito.\\
+ \const{CLD\_KILLED} & il figlio è stato terminato.\\
+ \const{CLD\_DUMPED} & il figlio è terminato in modo anormale.\\
+ \const{CLD\_TRAPPED} & un figlio tracciato ha raggiunto una trappola.\\
+ \const{CLD\_STOPPED} & il figlio è stato fermato.\\
+ \const{CLD\_CONTINUED}& il figlio è ripartito.\\
+ \hline
+ \const{POLL\_IN} & disponibili dati in ingresso.\\
+ \const{POLL\_OUT} & spazio disponibile sul buffer di uscita.\\
+ \const{POLL\_MSG} & disponibili messaggi in ingresso.\\
+ \const{POLL\_ERR} & errore di I/O.\\
+ \const{POLL\_PRI} & disponibili dati di alta priorità in ingresso.\\
+ \const{POLL\_HUP} & il dispositivo è stato disconnesso.\\
+ \hline
+ \end{tabular}
+ \caption{Valori del campo \var{sa\_code} della struttura \struct{sigaction}
+ impostati rispettivamente dai segnali \const{SIGILL}, \const{SIGFPE},
+ \const{SIGSEGV}, \const{SIGBUS}, \const{SIGCHLD}, \const{SIGTRAP} e
+ \const{SIGPOLL}.}
+ \label{tab:sig_sa_code_special}
+\end{table}
-Il resto della struttura è definito come \ctyp{union} ed i valori
-eventualmente presenti dipendono dal segnale, così \const{SIGCHLD} ed i
+Il resto della struttura \struct{siginfo\_t} è 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
+al processo che ha emesso il segnale, \const{SIGCHLD} avvalora anche i campi
+\const{si\_status}, \const{si\_utime} and \const{si\_stime} che indicano
+rispettivamente lo stato di uscita, l'\textit{user time} e il \textit{system
+ time} (vedi sez.~\ref{sec:sys_cpu_times}) usati dal processo;
+\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 \itindex{out-of-band} dati urgenti (vedi
-sez.~\ref{sec:TCP_urgent_data}) su un socket.
+file descriptor e \var{si\_band} per i \itindex{out-of-band} dati urgenti
+(vedi sez.~\ref{sec:TCP_urgent_data}) su un socket.
Benché sia possibile usare nello stesso programma sia \func{sigaction} che
\func{signal} occorre molta attenzione, in quanto le due funzioni possono
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 \itindex{stack} 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.}
+\func{sigaction} una funzione equivalente \func{Signal}, 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, essa è 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
+ \itindex{stack} \textit{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.} per semplificare ulteriormente la definizione si è poi
+definito un apposito tipo \texttt{SigFunc}.
rispetto a quanto potrebbe essere in un qualunque momento successivo.
Una delle caratteristiche di BSD, disponibile anche in Linux, è la possibilità
-di usare uno \itindex{stack} stack alternativo per i segnali; è cioè possibile
-fare usare al sistema un altro \itindex{stack} 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:
+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
- stack alternativo;
+ \textit{stack} alternativo;
\item Usare la funzione \func{sigaltstack} per rendere noto al sistema
- l'esistenza e la locazione dello stack alternativo;
+ 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 stack alternativo durante l'esecuzione del
- gestore.
+ 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} stack di
-segnali e di norma è sufficiente per tutti gli usi normali.
+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 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} stack di dimensione sufficiente.
-
-Come accennato, per poter essere usato, lo \itindex{stack} stack per i segnali
-deve essere indicato al sistema attraverso la funzione \funcd{sigaltstack}; il
-suo prototipo è:
+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 stack per i segnali.
+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 stack è minore
- di \const{MINSIGSTKSZ}.
+ \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 stack alternativo mentre
- questo è attivo (cioè il processo è in esecuzione su di esso).
+ \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}}
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} stack da installare e quello corrente (che viene restituito
-dalla funzione per un successivo ripristino).
+\itindex{stack} \textit{stack} da installare e quello corrente (che viene
+restituito dalla funzione per un successivo ripristino).
\begin{figure}[!htb]
\footnotesize \centering
\end{figure}
Il campo \var{ss\_sp} di \struct{stack\_t} indica l'indirizzo base dello
-\itindex{stack} 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
-\const{SS\_DISABLE} come valore di \var{ss\_flags} e gli altri valori saranno
-ignorati.
+\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} stack corrente nei relativi campi, mentre
-\var{ss\_flags} potrà assumere il valore \const{SS\_ONSTACK} se il processo è
-in esecuzione sullo stack alternativo (nel qual caso non è possibile
-cambiarlo) e \const{SS\_DISABLE} se questo non è abilitato.
-
-In genere si installa uno \itindex{stack} stack alternativo per i segnali
-quando si teme di avere problemi di esaurimento dello 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} 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 \itindex{stack} 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.
+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
\headdecl{setjmp.h}
\funcdecl{int sigsetjmp(sigjmp\_buf env, int savesigs)} Salva il contesto
- dello stack per un \index{salto~non-locale} salto non-locale.
+ 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.
\end{functions}
Le due funzioni prendono come primo argomento la variabile su cui viene
-salvato il contesto dello \itindex{stack} stack per permettere il
+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
ed ad esempio può essere problematico chiamare all'interno di un gestore di
segnali la stessa funzione che dal segnale è stata interrotta.
-\index{funzioni~sicure|(}
+\index{funzioni!sicure|(}
Il concetto è comunque più generale e porta ad una distinzione fra quelle che
che POSIX chiama \textsl{funzioni insicure} (\textit{n'Usane function}) e
\label{fig:sig_safe_functions}
\end{figure}
-\index{funzioni~sicure|)}
+\index{funzioni!sicure|)}
Per questo motivo è opportuno mantenere al minimo indispensabile le operazioni
effettuate all'interno di un gestore di segnali, qualora si debbano compiere
\section{Funzionalità avanzate}
-\label{sec:sig_real_time}
+\label{sec:sig_advanced_signal}
Tratteremo in questa ultima sezione alcune funzionalità avanzate relativa ai
certi segnali ha la precedenza rispetto ad altri.
\end{basedescript}
-
Per poter superare queste limitazioni lo standard ha introdotto delle nuove
caratteristiche, che sono state associate ad una nuova classe di segnali, che
vengono chiamati \textsl{segnali real-time}, in particolare le funzionalità
Lo standard POSIX.1b definisce inoltre delle nuove funzioni che permettono di
gestire l'attesa di segnali specifici su una coda, esse servono in particolar
-modo nel caso dei thread, in cui si possono usare i segnali real-time come
-meccanismi di comunicazione elementare; la prima di queste funzioni è
-\funcd{sigwait}, il cui prototipo è:
+modo nel caso dei \itindex{thread} \textit{thread}, in cui si possono usare i
+segnali real-time come meccanismi di comunicazione elementare; la prima di
+queste funzioni è \funcd{sigwait}, il cui prototipo è:
\begin{prototype}{signal.h}
{int sigwait(const sigset\_t *set, int *sig)}
prevedibile.
Lo standard POSIX.1b definisce altre due funzioni, anch'esse usate
-prevalentemente con i thread; \funcd{sigwaitinfo} e \funcd{sigtimedwait}, i
-relativi prototipi sono:
+prevalentemente con i \itindex{thread} \textit{thread}; \funcd{sigwaitinfo} e
+\funcd{sigtimedwait}, i relativi prototipi sono:
\begin{functions}
\headdecl{signal.h}
immediatamente; in questo modo si può eliminare un segnale dalla coda senza
dover essere bloccati qualora esso non sia presente.
+\itindbeg{thread}
+
L'uso di queste funzioni è principalmente associato alla gestione dei segnali
-con i thread. In genere esse vengono chiamate dal thread incaricato della
-gestione, che al ritorno della funzione esegue il codice che usualmente
-sarebbe messo nel gestore, per poi ripetere la chiamata per mettersi in attesa
-del segnale successivo. Questo ovviamente comporta che non devono essere
-installati gestori, che solo il thread di gestione deve usare \func{sigwait} e
-che, per evitare che venga eseguita l'azione predefinita, i segnali gestiti in
-questa maniera devono essere mascherati per tutti i thread, compreso quello
-dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive.
+con i \textit{thread}. In genere esse vengono chiamate dal \textit{thread}
+incaricato della gestione, che al ritorno della funzione esegue il codice che
+usualmente sarebbe messo nel gestore, per poi ripetere la chiamata per
+mettersi in attesa del segnale successivo. Questo ovviamente comporta che non
+devono essere installati gestori, che solo il \textit{thread} di gestione deve
+usare \func{sigwait} e che, per evitare che venga eseguita l'azione
+predefinita, i segnali gestiti in questa maniera devono essere mascherati per
+tutti i \textit{thread}, compreso quello dedicato alla gestione, che potrebbe
+riceverlo fra due chiamate successive.
+
+\itindend{thread}
\subsection{La gestione avanzata delle temporizzazioni}
% LocalWords: setsockopt setuid shutdown sigpause socketpair stat symlink page
% LocalWords: sysconf tcdrain tcflow tcflush tcgetattr tcgetgrp tcsendbreak
% LocalWords: tcsetattr tcsetpgrp getoverrun times umask uname unlink utime
-% LocalWords: write sival SIVGTALRM NOCLDWAIT
+% LocalWords: write sival SIVGTALRM NOCLDWAIT MESGQ ASYNCIO TKILL tkill tgkill
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+% LocalWords: ILL ILLOPC ILLOPN ILLADR ILLTRP PRVOPC PRVREG COPROC BADSTK FPE
+% LocalWords: INTDIV INTOVF FLTDIV FLTOVF FLTUND underflow FLTRES FLTINV SEGV
+% LocalWords: FLTSUB MAPERR ACCERR ADRALN ADRERR OBJERR BRKPT CLD EXITED MSG
+% LocalWords: KILLED DUMPED TRAPPED STOPPED CONTINUED PRI HUP SigFunc