Risistemati un sacco di riferiementi, e la riorganizzazione della parte
[gapil.git] / signal.tex
index c5b2282be53a7d06d9607b827a7a52711f37f77c..ec3bf5547afcab767eddadcd7d14a91cb477bb67 100644 (file)
@@ -1,5 +1,5 @@
 \chapter{I segnali}
-\label{sec:signals}
+\label{cha:signals}
 
 I segnali sono il primo e più semplice meccanismo di comunicazione nei
 confronti dei processi. Non portano con se nessuna informazione che non sia il
@@ -28,61 +28,142 @@ segnale sono vari; un breve elenco di possibile cause 
   essere eseguita.
 \item una richiesta dell'utente di terminare o fermare il programma. In genere
   si realizza attraverso un segnale mandato dalla shell in corrispondenza
-  della pressione di tasti come 'ctrl-c' o 'ctrl-z'.
+  della pressione di tasti del terminale come 'ctrl-c' o 'ctrl-z'.
 \item l'esecuzione di una \texttt{kill} o di una \texttt{raise} da parte del
   processo stesso o di un'altro (solo nel caso della \texttt{kill}).
 \end{itemize}
 
 Ciascuno di questi eventi (tranne gli ultimi due che sono controllati
-dall'utente) comporta da parte del kernel la generazione un particolare tipo
-di segnale.
+dall'utente) comporta l'intervento diretto da parte del kernel che causa la
+generazione un particolare tipo di segnale.
 
 
 \subsection{Le modalità di funzionamento}
 \label{sec:sig_semantics}
 
-Quando un processo riceve un segnale il kernel esegue una apposita routine di
-gestione (il cosiddetto \textit{signal handler}) che può essere specificata
-dall'utente.  Negli anni il comportamento del sistema in risposta ai segnali è
-stato modificato in vari modi nelle differenti implementazioni di unix.
-Attualmente si possono individuare due tipologie fondamentali di comportamento
-dei segnali (dette semantiche) che vengono chiamate rispettivamente
-\textit{reliable} e \textit{unreliable}.
-
-Nella semantica \textit{unreliable} la routine di gestione del segnale
-specificata dall'utente non resta installata una volta chiamata; è perciò a
-carico dell'utente stesso ripetere l'installazione all'interno della routine
-stessa in tutti i casi in cui si vuole che il signal handler esterno resti
-attivo.
-
-Per questo motivo è possibile una race-condition in cui il segnale arriva
-prima che il suo manipolatore sia installato, nel qual caso il segnale può
-essere perso o causare il comportamento originale (in genere la terminazione
-del processo). Questa è la ragione per cui detti segnali sono chiamati
-\textit{inaffidabili}, in quanto la ricezione del segnale e la reinstallazione
-del suo manipolatore non sono operazioni atomiche.
-
-In caso di implementazione inaffidabile le chiamate di sistema non sono fatte
-ripartire automaticamente quando sono interrotte da un segnale, per questo il
-programma deve controllare lo stato di uscita della chiamata al sistema e
-riperterla nel caso l'errore riportato da \texttt{errno} sia \texttt{EINTR}.
-
-Inoltre in questo caso non esiste una modalità semplice per ottenere una
-operazione di pausa atomica (cioè mandare in sleep un processo fino all'arrivo
-di un segnale), dato che ci sono casi in cui un segnale può arrivare quando il
-programma non è in grado di accorgersene.
-
-In caso di segnali \textit{reliable} invece il signal handler resta installato
-quando viene chiamato e i problemi precedenti sono evitati. Inoltre alcune
-chiamate di sistema possono essere fatte ripartire automaticamente e si può
-ottenere un'operazione di pausa atomica (usando la funzione POSIX
-\texttt{sigsuspend}).
+Quando un processo riceve un segnale il kernel esegue una azione di default o
+una apposita routine di gestione (il cosiddetto \textit{signal handler} o
+\textsl{manipolatore}) che può essere specificata dall'utente (nel qual caso
+si dice che si \textsl{intercetta} il segnale).  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 \textit{reliable} e \textit{unreliable}.
+
+Nella semantica \textit{unreliable} (quella implementata dalle prime versioni
+di unix) la routine di gestione del segnale specificata dall'utente non resta
+installata una volta chiamata; è perciò a carico dell'utente stesso ripetere
+l'installazione all'interno della routine di gestione stessa in tutti i casi
+in cui si vuole che il signal handler 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:
+\begin{lstlisting}{showlines=false}
+
+    int sig_handler();            /* handler function */
+    ...
+    signal(SIGINT, sig_handler);  /* establish handler */
+    ...
+
+int sig_handler() 
+{
+    signal(SIGINT, sig_handler);  /* restablish handler */
+    ...                           /* process signal */
+}
+\end{lstlisting}
+se un secondo segnale arriva prima che il manipolatore invocato dal primo
+abbia eseguito la re-installazione di se stesso il segnale può essere perso o
+causare il comportamento originale assegnato al segnale (in genere la
+terminazione del processo).
+
+Questa è la ragione per cui l'implementazione dei segnali secondo questa
+semantica viene chiamata \textit{inaffidabile}, in quanto la ricezione del
+segnale e la reinstallazione del suo manipolatore non sono operazioni
+atomiche.
+
+Un'altro problema è che in questa semantica è che non esiste un modo per
+bloccare i segnali quando non si vuole che arrivino; i processi possono si
+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, riportato da Stevens, 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. Si consideri il seguente segmento di
+codice il cui scopo sarebbe quello di fermare il processo fino all'occorrenza
+di un opportuno segnale:
+\begin{lstlisting}{}
+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}
+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 \func{while} e la
+chiamata a \func{pause}, nel qual caso, se il segnale non viene più generato,
+il processo resterà in sleep permanentemente.
+
+% Un'altra caratteristica della implementazione inaffidabile è che le chiamate
+% di sistema non sono fatte ripartire automaticamente quando sono interrotte da
+% un segnale, per questo un programma deve controllare lo stato di uscita della
+% chiamata al sistema e riperterla nel caso l'errore riportato da \texttt{errno}
+% sia \texttt{EINTR}.
+
+Questo ci mostra ad esempio come con la semantica inaffidabile non esista una
+modalità semplice per ottenere una operazione di pausa atomica (cioè mandare
+in sleep un processo fino all'arrivo di un segnale).
+
+Nella semantica \textit{reliable} (quella utilizzata da Linux e da ogni Unix
+moderno) invece il signal handler una volta installato resta attivo e non si
+hanno tutti i problemi precedenti. In questa semantica i segnali vengono
+\textsl{generati} dal kernel per un processo all'occorrenza dell'evento che
+causa il segnale. In genere questo viene fatto dal kernel settanto un flag
+nella process table del processo.
+
+Si dice che il segnale viene \textsl{consegnato} al processo (dall'inglese
+\textit{delivered}) quando viene eseguita l'azione per esso prevista, mentre
+per tutto il tempo che passa fra la generazione del segnale e la sua consegna
+esso è detto \textsl{pendente}. In genere questa procedura viene effettuata
+dal kernel quando, riprendendo l'esecuzione del processo in questione, verifica
+la presenza del flag del segnale nella process table.
+
+In questa semantica un processo ha la possibilità di bloccare la consegna dei
+segnali, in questo caso se l'azione per il suddetto segnale non è quella di
+ignorarlo, il segnale resta \textsl{pendente} fintanto che il processo non lo
+sblocca (nel qual caso viene consegnato) o setta l'azione di default per
+ignorarlo. 
+
+Si tenga presente 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.
+
 
 
 \subsubsection{Tipi di segnali}
 \label{sec:sig_types}
 
-
 In generale gli eventi che generano i segnali si possono dividere in tre
 categorie principali: errori, eventi e richieste esplicite. 
 
@@ -122,7 +203,7 @@ sistema, nel qual caso qualunque tipo di segnale (quello scelto nella
 chiamata) può diventare sincrono o asincrono a seconda che sia generato
 internamente o esternamente al processo.
 
-\section{La notifica dei segnali}
+\subsection{La notifica dei segnali}
 \label{sec:sig_notification}
 
 Quando un segnale viene generato il kernel prende nota del fatto; si dice così
@@ -178,7 +259,7 @@ una \texttt{kill}.
 
 
 
-\subsection{I segnali standard}
+\section{I segnali standard}
 \label{sec:sig_standard}
 
 Esaminiamo ora i vari segnali disponibili e le loro caratteristiche. 
@@ -186,21 +267,102 @@ Ciascun segnale 
 diretto di questo numero da parte dei programmi è da evitare, in quanto esso
 può variare a seconda dell'implementazione del sistema.
 
-Per questo ad ogni tipo di segnale viene associato un nome, che corrisponde
-tramite una macro di preprocessore, al suddetto numero, e sono questi nomi,
-che sono standardizzati e uniformi rispetto alle varie implementazioni, che si
+Per questo ad ogni tipo di segnale viene associato un nome, che corrisponde,
+tramite una macro di preprocessore, al suddetto numero. Sono questi nomi, che
+sono standardizzati e uniformi rispetto alle varie implementazioni, che si
 devono usare nei programmi. Tutti i nomi e le funzioni che concernono i
 segnali sono definiti nell'header di sistema \texttt{signal.h}.
 
 Il numero totale di segnali presenti è dato dalla macro \texttt{NSIG}, e dato
 che i numeri dei segnali sono allocati progressivamente, essa corrisponde
 anche al successivo del valore numerico assegnato all'ultimo segnale definito.
-
+In \ntab\ si è riportato l'elenco completo dei segnali definiti in Linux
+(estratto dalle man page), comparati con quelli definiti in vari standard.
+\begin{table}[htb]
+  \centering
+  \begin{tabular}[c]{|l|c|c|c||c|p{8cm}|}
+    \hline
+    Segnale  & POSIX.1 & SUSv2 & Linux  &Azione &  Descrizione \\
+    \hline
+    \hline
+    SIGHUP   &$\bullet$&&$\bullet$&  A  & Hangup sul terminale  o
+    morte del processo di controllo  \\
+    SIGINT   &$\bullet$&&$\bullet$&  A  & Interrupt da tastiera (\cmd{C-c})\\
+    SIGQUIT  &$\bullet$&&$\bullet$&  C  & Quit da tastiera (\cmd{C-y}) \\
+    SIGILL   &$\bullet$&&$\bullet$&  C  & Istruzione illegale\\
+    SIGABRT  &$\bullet$&&$\bullet$&  C  & Segnale di Abort da \func{abort} \\
+    SIGFPE   &$\bullet$&&$\bullet$&  C  & Errore aritmetico\\
+    SIGKILL  &$\bullet$&&$\bullet$& AEF & Segnale di terminazione forzata \\
+    SIGSEGV  &$\bullet$&&$\bullet$&  C  & Errore di accesso in memoria\\
+    SIGPIPE  &$\bullet$&&$\bullet$&  A  & Pipe spezzata\\
+    SIGALRM  &$\bullet$&&$\bullet$&  A  & Segnale del timer da \func{alarm} \\
+    SIGTERM  &$\bullet$&&$\bullet$&  A  & Segnale di terminazione \verb|C-\|\\
+    SIGUSR1  &$\bullet$&&$\bullet$&  A  & User-defined signal 1\\
+    SIGUSR2  &$\bullet$&&$\bullet$&  A  & User-defined signal 2\\
+    SIGCHLD  &$\bullet$&&$\bullet$&  B  & Child stopped or terminated\\
+    SIGCONT  &$\bullet$&&$\bullet$&     & Continue if stopped\\
+    SIGSTOP  &$\bullet$&&$\bullet$& DEF & Stop process\\
+    SIGTSTP  &$\bullet$&&$\bullet$&  D  & Stop typed at tty \\
+    SIGTTIN  &$\bullet$&&$\bullet$&  D  & tty input for background process \\
+    SIGTTOU  &$\bullet$&&$\bullet$&  D  & tty output for background process \\
+    SIGBUS    &&$\bullet$&$\bullet$& C & Bus error (bad memory access) \\
+    SIGPOLL   &&$\bullet$&$\bullet$& A & Pollable event (Sys V). Synonym of SIGIO\\
+    SIGPROF   &&$\bullet$&$\bullet$& A & Profiling timer expired \\
+    SIGSYS    &&$\bullet$&$\bullet$& C & Bad argument to routine (SVID)\\
+    SIGTRAP   &&$\bullet$&$\bullet$& C & Trace/breakpoint trap \\
+    SIGURG    &&$\bullet$&$\bullet$& B & Urgent condition on socket (4.2 BSD)\\
+    SIGVTALRM &&$\bullet$&$\bullet$& A & Virtual alarm clock (4.2 BSD) \\
+    SIGXCPU   &&$\bullet$&$\bullet$& C & CPU time limit exceeded (4.2 BSD)  \\
+    SIGXFSZ   &&$\bullet$&$\bullet$& C & File size limit exceeded (4.2 BSD)\\
+    SIGIOT    &&&$\bullet$& C &     IOT trap. A synonym for SIGABRT        \\
+    SIGEMT    &&&$\bullet$&   &                                            \\
+    SIGSTKFLT &&&$\bullet$& A &     Stack fault on coprocessor             \\
+    SIGIO     &&&$\bullet$& A &     I/O now possible (4.2 BSD)             \\
+    SIGCLD    &&&$\bullet$&   &     A synonym for SIGCHLD                  \\
+    SIGPWR    &&&$\bullet$& A &     Power failure (System V)               \\
+    SIGINFO   &&&$\bullet$&   &     A synonym for SIGPWR                   \\
+    SIGLOST   &&&$\bullet$& A &     File lock lost                         \\
+    SIGWINCH  &&&$\bullet$& B &     Window resize signal (4.3 BSD, Sun)    \\
+    SIGUNUSED &&&$\bullet$& A &     Unused signal (will be SIGSYS)         \\
+    \hline
+  \end{tabular}
+  \caption{Lista dei segnali in Linux}
+  \label{tab:sig_signal_list}
+\end{table}
+in \curtab\ si sono riportate le azioni di default di ciascun segnale
+(riassunte con delle lettere, la cui legenda completa è in \ntab), quando
+nessun manipolatore è installato un segnale può essere ignorato o causare la
+terminazione del processo.
+
+In alcuni casi alla terminazione del processo è associata la creazione di un
+file (posto nella directory corrente del processo e chiamato \file{core}) su
+cui viene salvata un'immagine della memoria del processo (il cosiddetto
+\textit{core dump}), che può essere usata da un debugger per esaminare lo
+stato dello stack e delle variabili al momento della ricezione del segnale.
+
+\begin{table}[htb]
+  \centering
+  \begin{tabular}[c]{c p{6cm}}
+    A & L'azione di default è terminare il processo. \\
+    B & L'azione di default è ignorare il segnale. \\
+    C & L'azione di default è terminare il processo e scrivere un \textit{core
+        dump}. \\
+    D & L'azione di default è fermare il processo. \\
+    E & Il segnale non può essere intercettato. \\
+    F & Il segnale non può essere ignorato.\\
+  \end{tabular}
+  \caption{Legenda delle caratteristiche dei segnali riportate in 
+    \tabref{tab:sig_signal_list}. }
+  \label{tab:sig_action_leg}
+\end{table}
+la descrizione dettagliata del significato dei vari segnali, raggruppati per
+tipologia, è a seguire.
 
 \subsubsection{Segnali di errore di programma}
+\label{sec:sig_prog_error}
 
 Questi segnali sono generati quando il sistema, o in certi casi direttamente
-l'hardware (come per i page fault non valildi) rileva un qualche errore
+l'hardware (come per i page fault non validi) rileva un qualche errore
 insanabile nel programma in esecuzione. In generale la generazione di questi
 segnali significa che il programma ha dei gravi problemi (ad esempio ha
 dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica
@@ -216,32 +378,32 @@ non ci fosse stato.
 
 L'azione di default per tutti questi segnali è causare la terminazione del
 processo che li ha causati. In genere oltre a questo il segnale provoca pure
-la registrazione su disco di un \textit{core dump file} che viene scritto in
-un file \texttt{core} nella directory corrente del processo al momento
-dell'errore.
+la registrazione su disco di un file di \textit{core dump} che viene scritto
+in un file \texttt{core} nella directory corrente del processo al momento
+dell'errore, che il debugger può usare per ricostruire lo stato del programma
+al momento della terminazione.
 
 Questi segnali sono:
-
-\begin{itemize}
+\begin{description}
 \item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome
   derivi da \textit{floating point exception} si applica a tutti gli errori
-  aritmetici compresa la divisione per zero e l'overflow.
+  aritmetici compresa la divisione per zero e l'overflow. 
 
 %   Per questo segnale le cose sono complicate dal fatto che possono esserci
 %   molte diverse eccezioni che \texttt{SIGFPE} non distingue, mentre lo
 %   standard IEEE per le operazioni in virgola mobile definisce vaire eccezioni
 %   aritmetiche e richiede che esse siano notificate.  
+
 \item \texttt{SIGILL} Il nome deriva da \textit{illegal instruction},
   significa che il programma sta cercando di eseguire una istruzione
-  privilegiata od inesistente, in generale del codice illegale. Poiché il
+  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 array di
+  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
-  di un signal handler.
-
+  generato in caso di overflow dello stack o di problemi nell'esecuzione di di
+  un signal handler.
 \item \texttt{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
@@ -249,12 +411,199 @@ Questi segnali sono:
   accorge dell'errore ed il kernel genera il segnale.
 
   È tipico ottenere questo segnale dereferenziando un puntatore nullo o non
-  inizializzatoo leggendo al di la della fine di un vettore. 
-
-\item \texttt{SIGBUS} 
-\item \texttt{SIGABRT} 
-\item \texttt{SIGTRAP} 
-\item \texttt{SIGSYS} 
-
-\end{itemize}
+  inizializzato leggendo al di la della fine di un vettore. 
+\item \texttt{SIGBUS} In maniera analoga a \texttt{SIGSEGV} questo è un
+  segnale che viene generato di solito quando si dereferenzia un puntatore non
+  inzializzato, la differenza con con \texttt{SIGSEGV} è che questo indica un
+  accesso non valido su un indirizzo esistente (tipo fuori dallo heap o dallo
+  stack), mentre \texttt{SIGBUS} indica l'accesso ad un indirizzo non valido,
+  come nel caso di un puntatore non allineato. 
+\item \texttt{SIGABRT} Il segnale indica che il programma stesso ha rilevato
+  un errore che viene riportato chiamando la funzione \texttt{abort} che
+  genera questo segnale. 
+\item \texttt{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 \texttt{SIGSYS} Sta ad indicare che si è eseguta una istruzione che
+  richiede l'esecuzione di una system call, ma si è fornito un codice
+  sbagliato per quest'ultima.
+\end{description}
+
+
+\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 (tipi 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{description}
+\item \macro{SIGTERM} Questo è 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} E 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 interrupt (generato dalla sequenza \macro{C-\\}).
+\item  \macro{SIGQUIT} 
+\item  \macro{SIGKILL}
+\item  \macro{SIGHUP}
+\end{description}
+
+\subsection{I segnali di allarme}
+\label{sec:sig_alarm}
+
+Questi segnali sono generati dalla scadenza di un temporizzatore. 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{description}
+\item  \texttt{SIGALRM}
+\item  \texttt{SIGVTALRM}
+\item  \texttt{SIGPROF}
+\end{description}
+
+
+\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{description}
+\item  \texttt{SIGIO}
+\item  \texttt{SIGURG}
+\item  \texttt{SIGPOLL}
+\end{description}
+
+\subsection{I segnali per il controllo di sessione}
+\label{sec:sig_job_control}
+
+Questi sono i segnali usati dal controllo di sessione, il loro uso è specifico
+per questo argomento e verrà trattato quando lo affronteremo. 
+Questi  segnali sono:
+\begin{description}
+\item  \texttt{SIGCHLD}
+\item  \texttt{SIGCONT}
+\item  \texttt{SIGSTOP}
+\item  \texttt{SIGTSTP}
+\item  \texttt{SIGTTIN}
+\item  \texttt{SIGTTOU}
+\end{description}
+
+\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{description}
+\item  \texttt{SIGPIPE}
+\item  \texttt{SIGLOST}
+\item  \texttt{SIGXCPU}
+\item  \texttt{SIGXFSZ}
+\end{description}
+
+
+\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{description}
+\item  \texttt{SIGUSR1} e \texttt{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 utlizzando un manipolatore. L'azione di
+  default è terminare il processo.  
+\item \texttt{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  \texttt{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{description}
+
+
+
+\section{La gestione dei segnali}
+\label{sec:sig_handlers}
+
+I segnali sono il primo e più classico esempio di eventi asincroni, che
+possono accadere in un qualunque momento durante l'esecuzione di un programma.
+Non essendo sotto il controllo del programma la gestione dei segnali non potrà
+essere controllata all'interno del flusso di esecuzione di quest'ultimo, ma
+tutto quello che si potrà fare è di specificare (al kernel, che li genera)
+quale azione andrà intrapresa quando essi si verificano.
+
+In questa sezione vedremo allora come si gestiscono i segnali, esaminando le
+funzioni che si usano per effettuare la gestione dei segnali ed analizzando le
+problematiche relative alla gestione di eventi asincroni di questo tipo.
+
+
+\subsection{La funzione \func{signal}}
+\label{sec:sig_signal}
+
+L'interfaccia più semplice alla manipolazione dei segnali è costituita dalla
+funzione \func{signal}; questa funzione è definita fin dallo standard ANSI C
+che però non considera sistemi multitasking, per cui la sua definizione in
+tale standard è tanto vaga da essere del tutto inutile in un sistema unix, per
+questo 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 è:
+\begin{prototype}{signal.h}
+  {sighandler\_t signal(int signum, sighandler\_t handler)} 
+  
+  Installa una nuova funzione di gestione (manipolatore) per il segnale
+  \param{signum}, usando il manipolatore \param{handler}.
+  
+  La funzione ritorna il precedente manipolatore in caso di successo 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 in Linux che permette di riscrivere il prototipo in
+forma più leggibile dell'originario \func{void (*signal(int signum, void
+  (*handler)(int)))int)}, e che è sostanzialmente equivalente alla
+definizione:
+\begin{verbatim}
+typedef void (* sighandler_t)(int) 
+\end{verbatim}
+cioè un puntatore ad una funzione di tipo \type{void} con un parametro di tipo
+\type{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 puntatarore a \type{void} e non
+  un puntatore ad una funzione \type{void}}.
+
+Il numero di segnale passato in \param{signum} segnale può essere indicato
+direttamente con una delle costanti definite in \secref{sec:sig_standard}, il
+manipolatore \param{handler} invece, oltre all'indirizzo della funzione da
+chiamare all'occorrenza del segnale, può assumere anche i valori costanti
+\macro{SIG\_IGN} con cui si dice ignorare il segnale e \macro{SIG\_DFL} per
+installare l'azione di di default (si ricordi però che i due segnali
+\macro{SIGKILL} e \macro{SIGSTOP} non possono essere ignorati né
+intercettati).
+
+
+\subsection{Funzioni rientranti e default dei segnali}
+\label{sec:sig_reentrant}