+
+\item[\macro{SIGILL}] Il nome deriva da \textit{illegal instruction},
+ significa che il programma sta cercando di eseguire una istruzione
+ privilegiata o inesistente, in generale del codice illegale. Poiché il
+ compilatore del C genera del codice valido si ottiene questo segnale se il
+ 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 stack. Lo stesso segnale viene
+ generato in caso di overflow dello stack o di problemi nell'esecuzione di un
+ manipolatore.
+\item[\macro{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.
+
+ È tipico ottenere questo segnale dereferenziando un puntatore nullo o non
+ inizializzato leggendo al di la della fine di un vettore.
+\item[\macro{SIGBUS}] Il nome deriva da \textit{bus error}. Come
+ \macro{SIGSEGV} questo è un segnale che viene generato di solito quando si
+ dereferenzia un puntatore non inizializzato, la differenza è che
+ \macro{SIGSEGV} indica un accesso non permesso su un indirizzo esistente
+ (tipo fuori dallo heap o dallo stack), mentre \macro{SIGBUS} indica
+ l'accesso ad un indirizzo non valido, come nel caso di un puntatore non
+ allineato.
+\item[\macro{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.
+\item[\macro{SIGTRAP}] È il segnale generato da un'istruzione di breakpoint o
+ dall'attivazione del tracciamento per il processo. È usato dai programmi per
+ il debugging e se un programma normale non dovrebbe ricevere questo segnale.
+\item[\macro{SIGSYS}] Sta ad indicare che si è eseguita una istruzione che
+ richiede l'esecuzione di una system call, ma si è fornito un codice
+ sbagliato per quest'ultima.
+\end{basedescript}
+
+
+\subsection{I segnali di terminazione}
+\label{sec:sig_termination}
+
+Questo tipo di segnali sono usati per terminare un processo; hanno vari nomi a
+causa del differente uso che se ne può fare, ed i programmi possono
+trattarli in maniera differente.
+
+La ragione per cui può essere necessario trattare questi segnali è che il
+programma può dover eseguire una serie di azioni di pulizia prima di
+terminare, come salvare informazioni sullo stato in cui si trova, cancellare
+file temporanei, o ripristinare delle condizioni alterate durante il
+funzionamento (come il modo del terminale o i settaggi di una qualche
+periferica).
+
+L'azione di default di questi segnali è di terminare il processo, questi
+segnali sono:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{SIGTERM}] Il nome sta per \textit{terminate}. È un segnale
+ generico usato per causare la conclusione di un programma. Al contrario di
+ \macro{SIGKILL} può essere intercettato, ignorato, bloccato. In genere lo si
+ usa per chiedere in maniera ``educata'' ad un processo di concludersi.
+\item[\macro{SIGINT}] Il nome sta per \textit{interrupt}. È il segnale di
+ interruzione per il programma. È quello che viene generato di default dal
+ comando \cmd{kill} o dall'invio sul terminale del carattere di controllo
+ INTR (interrupt, generato dalla sequenza \macro{C-c}).
+\item[\macro{SIGQUIT}] È analogo a \macro{SIGINT} con la differenze che è
+ controllato da un'altro carattere di controllo, QUIT, corrispondente alla
+ sequenza \verb|C-\|. A differenza del precedente l'azione di default,
+ oltre alla terminazione del processo, comporta anche la creazione di un core
+ dump.
+
+ In genere lo si può pensare come corrispondente ad una condizione di
+ errore del programma rilevata dall'utente. Per questo motivo non è opportuno
+ fare eseguire al manipolatore di questo segnale le operazioni di pulizia
+ normalmente previste (tipo la cancellazione di file temporanei), dato che in
+ certi casi esse possono eliminare informazioni utili nell'esame dei core
+ dump.
+\item[\macro{SIGKILL}] Il nome è utilizzato per terminare in maniera immediata
+ qualunque programma. Questo segnale non può essere né intercettato, né
+ ignorato, né bloccato, per cui causa comunque la terminazione del processo.
+ In genere esso viene generato solo per richiesta esplicita dell'utente dal
+ comando (o tramite la funzione) \cmd{kill}. Dato che non lo si può
+ intercettare è sempre meglio usarlo come ultima risorsa quando metodi meno
+ brutali, come \macro{SIGTERM} o \macro{C-c} non funzionano.
+
+ Se un processo non risponde a nessun altro segnale \macro{SIGKILL} ne causa
+ sempre la terminazione (in effetti il fallimento della terminazione di un
+ processo da parte di \macro{SIGKILL} costituirebbe un malfunzionamento del
+ kernel). Talvolta è il sistema stesso che può generare questo segnale quando
+ per condizioni particolari il processo non può più essere eseguito neanche
+ per eseguire un manipolatore.
+\item[\macro{SIGHUP}] Il nome sta per \textit{hang-up}. Segnala che il
+ terminale dell'utente si è disconnesso (ad esempio perché si è interrotta la
+ rete). Viene usato anche per riportare la terminazione del processo di
+ controllo di un terminale a tutti i processi della sessione, in modo che
+ essi possano disconnettersi dal relativo terminale.
+
+ Viene inoltre usato in genere per segnalare ai demoni (che non hanno un
+ terminale di controllo) la necessità di reinizializzarsi e rileggere il/i
+ file di configurazione.
+\end{basedescript}
+
+
+\subsection{I segnali di allarme}
+\label{sec:sig_alarm}
+
+Questi segnali sono generati dalla scadenza di un timer. Il loro comportamento
+di default è quello di causare la terminazione del programma, ma con questi
+segnali la scelta di default è irrilevante, in quanto il loro uso presuppone
+sempre la necessità di un manipolatore. Questi segnali sono:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{SIGALRM}] Il nome sta per \textit{alarm}. Segnale la scadenza di
+ un timer misurato sul tempo reale o sull'orologio di sistema. È normalmente
+ usato dalla funzione \func{alarm}.
+\item[\macro{SIGVTALRM}] Il nome sta per \textit{virtual alarm}. È analogo al
+ precedente ma segnala la scadenza di un timer sul tempo di CPU usato dal
+ processo.
+\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.
+\end{basedescript}
+
+
+\subsection{I segnali di I/O asincrono}
+\label{sec:sig_asyncio}
+
+Questi segnali operano in congiunzione con le funzioni di I/O asincrono. Per
+questo occorre comunque usare \func{fcntl} per abilitare un file descriptor a
+generare questi segnali.
+
+L'azione di default è di essere ignorati. Questi segnali sono:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{SIGIO}] Questo segnale viene inviato quando un file descriptor è
+ pronto per eseguire dell'input/output. In molti sistemi solo i socket e i
+ terminali possono generare questo segnale, in Linux questo può essere usato
+ anche per i file, posto che la \func{fcntl} abbia avuto successo.
+\item[\macro{SIGURG}] Questo segnale è inviato quando arrivano dei dati
+ urgenti o \textit{out of band} su di un socket; per maggiori dettagli al
+ proposito si veda \secref{sec:xxx_urgent_data}.
+\item[\macro{SIGPOLL}] Questo segnale è equivalente a \macro{SIGIO}, è
+ definito solo per compatibilità con i sistemi System V.
+\end{basedescript}
+
+
+\subsection{I segnali per il controllo di sessione}
+\label{sec:sig_job_control}
+
+Questi sono i segnali usati dal controllo delle sessioni e dei processi, il
+loro uso è specifico e viene trattato in maniera specifica nelle sezioni in
+cui si trattano gli argomenti relativi. Questi segnali sono:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{SIGCHLD}] Questo è il segnale mandato al processo padre quando un
+ figlio termina o viene fermato. L'azione di default è di ignorare il
+ segnale, la sua gestione è trattata in \secref{sec:proc_wait}.
+\item[\macro{SIGCLD}] Per Linux questo è solo un segnale identico al
+ precedente, il nome è obsoleto e andrebbe evitato.
+\item[\macro{SIGCONT}] Il nome sta per \textit{continue}. Il segnale viene
+ usato per fare ripartire un programma precedentemente fermato da
+ \macro{SIGSTOP}. Questo segnale ha un comportamento speciale, e fa sempre
+ ripartire il processo prima della sua consegna. Il comportamento di default
+ è di fare solo questo; il segnale non può essere bloccato. Si può anche
+ installare un manipolatore, ma il segnale provoca comunque il riavvio del
+ processo.
+
+ La maggior pare dei programmi non hanno necessità di intercettare il
+ segnale, in quanto esso è completamente trasparente rispetto all'esecuzione
+ che riparte senza che il programma noti niente. Si possono installare dei
+ manipolatori per far si che un programma produca una qualche azione speciale
+ se viene fermato e riavviato, come per esempio riscrivere un prompt, o
+ inviare un avviso.
+\item[\macro{SIGSTOP}] Il segnale ferma un processo (lo porta in uno stato di
+ sleep); il segnale non può essere né intercettato, né ignorato, né bloccato.
+\item[\macro{SIGTSTP}] Il nome sta per \textit{interactive stop}. Il segnale
+ ferma il processo interattivamente, ed è generato dal carattere SUSP
+ (prodotto dalla combinazione \macro{C-z}), ed al contrario di
+ \macro{SIGSTOP} può essere intercettato e ignorato. In genere un programma
+ installa un manipolatore per questo segnale quando vuole lasciare il sistema
+ o il terminale in uno stato definito prima di fermarsi; se per esempio un
+ programma ha disabilitato l'eco sul terminale può installare un manipolatore
+ per riabilitarlo prima di fermarsi.
+\item[\macro{SIGTTIN}] Un processo non può leggere dal terminale se esegue una
+ sessione di lavoro in background. Quando un processo in background tenta di
+ leggere da un terminale viene inviato questo segnale a tutti i processi
+ della sessione di lavoro. L'azione di default è di fermare il processo.
+ L'argomento è trattato in \secref{sec:sess_xxx}.
+\item[\macro{SIGTTOU}] Segnale analogo al precedente \macro{SIGTTIN}, ma
+ generato quando si tenta di scrivere o modificare uno dei modi del
+ terminale. L'azione di default è di fermare il processo, l'argomento è
+ trattato in \secref{sec:sess_xxx}.
+\end{basedescript}
+
+
+\subsection{I segnali di operazioni errate}
+\label{sec:sig_oper_error}
+
+Questi segnali sono usati per riportare al programma errori generati da
+operazioni da lui eseguite; non indicano errori del programma quanto errori
+che impediscono il completamento dell'esecuzione dovute all'interazione con il
+resto del sistema.
+
+L'azione di default di questi segnali è di terminare il processo, questi
+segnali sono:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{SIGPIPE}] Sta per \textit{Broken pipe}. Se si usano delle pipe o
+ delle FIFO è necessario che, prima che un processo inizi a scrivere su di
+ essa, un'altro abbia aperto la pipe in lettura (si veda
+ \secref{sec:ipc_pipes}). Se il processo in lettura non è partito o è
+ terminato inavvertitamente alla scrittura sulla pipe il kernel genera questo
+ segnale. Se il segnale è bloccato, intercettato o ignorato la chiamata che
+ lo ha causato fallisce restituendo l'errore \macro{EPIPE}
+\item[\macro{SIGLOST}] Sta per \textit{Resource lost}. Viene generato quando
+ c'è un advisory lock su un file NFS, ed il server riparte dimenticando la
+ situazione precedente.
+\item[\macro{SIGXCPU}] Sta per \textit{CPU time limit exceeded}. Questo
+ segnale è generato quando un processo eccede il limite impostato per il
+ tempo di CPU disponibile, vedi \secref{sec:sys_xxx}.
+\item[\macro{SIGXFSZ}] Sta per \textit{File size limit exceeded}. Questo
+ segnale è generato quando un processo tenta di estendere un file oltre le
+ dimensioni specificate dal limite impostato per le dimensioni massime di un
+ file, vedi \secref{sec:sys_xxx}.
+\end{basedescript}
+
+
+\subsection{Ulteriori segnali}
+\label{sec:sig_misc_sig}
+
+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
+ 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
+ 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.
+\item[\macro{SIGINFO}] Il segnale indica una richiesta di informazioni. È
+ usato con il controllo di sessione, causa la stampa di informazioni da parte
+ del processo leader del gruppo associato al terminale di controllo, gli
+ altri processi lo ignorano.
+\end{basedescript}
+
+
+\subsection{Le funzioni \func{strsignal} e \func{psignal}}
+\label{sec:sig_strsignal}
+
+Per la descrizione dei segnali il sistema mette a disposizione due funzioni,
+\func{strsignal} e \func{psignal}, che stampano un messaggio di descrizione
+dato il numero. In genere si usano quando si vuole notificare all'utente il
+segnale avvenuto (nel caso di terminazione di un processo figlio o di un
+manipolatore che gestisce più segnali); la prima funzione è una estensione
+GNU, accessibile avendo definito \macro{\_GNU\_SOURCE}, ed è analoga alla
+funzione \func{strerror} (si veda \secref{sec:sys_strerror}) per gli errori:
+\begin{prototype}{string.h}{char *strsignal(int signum)}
+ Ritorna il puntatore ad una stringa che contiene la descrizione del segnale
+ \var{signum}.
+\end{prototype}
+\noindent dato che la stringa è allocata staticamente non se ne deve
+modificare il contenuto, che resta valido solo fino alla successiva chiamata
+di \func{strsignal}. Nel caso si debba mantenere traccia del messaggio sarà
+necessario copiarlo.
+
+La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror}
+descritta in \secref{sec:sys_strerror}; il suo prototipo è:
+\begin{prototype}{signal.h}{void psignal(int sig, const char *s)}
+ Stampa sullo standard error un messaggio costituito dalla stringa \param{s},
+ seguita da due punti ed una descrizione del segnale indicato da \param{sig}.
+\end{prototype}
+
+Una modalità alternativa per utilizzare le descrizioni restituite da
+\func{strsignal} e \func{psignal} è quello di fare usare la variabile
+\var{sys\_siglist}, che è definita in \file{signal.h} e può essere acceduta
+con la dichiarazione:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+ extern const char *const sys_siglist[]
+\end{lstlisting}
+l'array \var{sys\_siglist} contiene i puntatori alle stringhe di descrizione,
+indicizzate per numero di segnale, per cui una chiamata del tipo di \code{char
+ *decr = strsignal(SIGINT)} può essere sostituita dall'equivalente \code{char
+ *decr = sys\_siglist[SIGINT]}.
+
+
+
+\section{La gestione dei segnali}
+\label{sec:sig_management}
+
+I segnali sono il primo e più classico esempio di eventi asincroni, cioè di
+eventi che possono accadere in un qualunque momento durante l'esecuzione di un
+programma. Per questa loro caratteristica la loro gestione non può essere
+effettuata all'interno del normale flusso di esecuzione dello stesso, ma è
+delegata appunto agli eventuali manipolatori che si sono installati.
+
+In questa sezione vedremo come si effettua gestione dei segnali, a partire
+dalla loro interazione con le system call, passando per le varie funzioni che
+permettono di installare i manipolatori e controllare le reazioni di un
+processo alla loro occorrenza.
+
+
+\subsection{Il comportamento generale del sistema.}
+\label{sec:sig_gen_beha}
+
+Abbiamo già trattato in \secref{sec:sig_intro} le modalità con cui il sistema
+gestisce l'interazione fra segnali e processi, ci resta da esaminare però il
+comportamento delle system call; in particolare due di esse, \func{fork} ed
+\func{exec}, dovranno essere prese esplicitamente in considerazione, data la
+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.
+
+Quando si mette in esecuzione un nuovo programma con \func{exec} (si ricordi
+quanto detto in \secref{sec:prog_exec}) tutti i segnali per i quali è stato
+installato un manipolatore vengono resettati a \macro{SIG\_DFL}. Non ha più
+senso infatti fare riferimento a funzioni definite nel programma originario,
+che non sono nemmeno presenti nello spazio di indirizzi del nuovo programma.
+
+Si noti che questo vale solo per le azioni per le quali è stato installato un
+manipolatore; viene mantenuto invece ogni eventuale settaggio dell'azione a
+\macro{SIG\_IGN}. Questo permette ad esempio alla shell di settare ad
+\macro{SIG\_IGN} le risposte per \macro{SIGINT} e \macro{SIGQUIT} per i
+programmi eseguiti in background, che altrimenti sarebbero interrotti da una
+successiva pressione di \texttt{C-c} o \texttt{C-y}.
+
+Per quanto riguarda tutte le altre system call esse vengono tradizionalmente
+classificate, proprio in base al loro comportamento nei confronti dei segnali,
+in \textsl{lente} (\textit{slow}) e \textsl{veloci} (\textit{fast}). La gran
+parte appartiene a quest'ultima categoria che non è influenzata dall'arrivo di
+un segnale. In tal caso un eventuale manipolatore viene sempre eseguito dopo
+che la system call è stata completata. Esse sono dette \textsl{veloci} proprio
+in quanto la loro esecuzione è sostanzialmente immediata e attendere per
+eseguire un manipolatore non comporta nessun inconveniente.
+
+Esistono però dei casi in cui questo non è possibile perché renderebbe
+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, che per questo vengono chiamate \textsl{lente}. Un elenco
+dei casi in cui si presenta questa situazione è il seguente:
+\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
+ accettati immediatamente.
+\item apertura di un file di dispositivo che richiede operazioni non immediate
+ per una una risposta.
+\item operazioni eseguite con \func{ioctl} che non è detto possano essere
+ 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
+ segnale).
+\item la funzione \func{wait} (se nessun processo figlio è ancora terminato).
+\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
+anche la system call restituendo l'errore di \macro{EINTR}. Questa è a
+tutt'oggi una scelta corrente, ma comporta che i programmi che usano dei
+manipolatori controllino lo stato di uscita delle funzioni per ripeterne la
+chiamata qualora l'errore fosse questo.
+
+Dimenticarsi di richiamare una system call interrotta da un segnale è un
+errore comune, tanto che le \acr{glibc} provvedono una macro
+\code{TEMP\_FAILURE\_RETRY(expr)} che esegue l'operazione automaticamente,
+ripetendo l'esecuzione dell'espressione \var{expr} fintanto che il risultato
+non è diverso dall'uscita con un errore \macro{EINTR}.
+
+La soluzione è comunque poco elegante e BSD ha scelto un approccio molto
+diverso, che è quello di fare ripartire automaticamente la system call invece
+di farla fallire. In questo caso ovviamente non c'è da preoccuparsi di
+controllare il codice di errore; si perde però la possibilità di eseguire
+azioni specifiche all'occorrenza di questa particolare condizione.
+
+Linux e le \acr{glibc} consentono di utilizzare entrambi gli approcci,
+attraverso una opportuna opzione di \func{sigaction} (vedi
+\secref{sec:sig_sigaction}). È da chiarire comunque che nel caso di
+interruzione nel mezzo di un trasferimento parziale di dati, le system call
+ritornano sempre indicando i byte trasferiti.
+