Aggiunte varie sempre sui segnali real-time
[gapil.git] / signal.tex
index f53e50b04d572b4bba0022ca38ede2e5da24dccf..ea8454e2555c90322f0e83db3d7db492d783e634 100644 (file)
@@ -1855,11 +1855,11 @@ in \tabref{tab:sig_sa_flag}.
 
 Come si può notare in \figref{fig:sig_sigaction} \func{sigaction}
 permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ed è
 
 Come si può notare in \figref{fig:sig_sigaction} \func{sigaction}
 permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ed è
-  stata aggiunta a partire dai kernel della serie 2.1.x con l'introduzione dei
-  segnali real-time (vedi \secref{sec:sig_real_time}). In precedenza era
-  possibile ottenere alcune informazioni addizionali usando \var{sa\_handler}
-  con un secondo parametro addizionale di tipo \var{struct sigcontext}, che
-  adesso è deprecato.}  di utilizzare due forme diverse di manipolatore, da
+  stata aggiunta nei kernel della serie 2.1.x con l'introduzione dei segnali
+  real-time (vedi \secref{sec:sig_real_time}). In precedenza era possibile
+  ottenere alcune informazioni addizionali usando \var{sa\_handler} con un
+  secondo parametro addizionale di tipo \var{struct sigcontext}, che adesso è
+  deprecato.}  di utilizzare due forme diverse di manipolatore, da
 specificare, a seconda dell'uso o meno del flag \macro{SA\_SIGINFO},
 rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler},
 (che devono essere usati in maniera alternativa, in certe implementazioni
 specificare, a seconda dell'uso o meno del flag \macro{SA\_SIGINFO},
 rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler},
 (che devono essere usati in maniera alternativa, in certe implementazioni
@@ -1899,22 +1899,34 @@ siginfo_t {
 Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora
 possibile accedere alle informazioni restituite attraverso il puntatore a
 questa struttura. Tutti i segnali settano i campi \var{si\_signo}, che riporta
 Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora
 possibile accedere alle informazioni restituite attraverso il puntatore a
 questa struttura. Tutti i segnali settano i campi \var{si\_signo}, che riporta
-il segnale ricevuto, \var{si\_errno}, che riporta il codice di errore, e
-\var{si\_code}, che viene usato per indicare la ragione per cui è stato emesso
-il segnale (come i dettagli sul tipo di errore per \macro{SIGFPE} e
-\macro{SIGILL}) ed ha valori diversi\footnote{un elenco dettagliato è
-  disponibile nella man page di \func{sigaction}.} a seconda del tipo di
-segnale ricevuto.
-
-Il resto della struttura può essere definito come \ctyp{union} ed i valori
+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 (\macro{SIGFPE},
+\macro{SIGILL}, \macro{SIGBUS} e \macro{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 (\macro{SIGCHLD}, \macro{SIGTRAP} e \macro{SIGPOLL}) forniscono
+altre informazioni speecifiche.  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 man page
+di \func{sigaction}.
+
+Il resto della struttura è definito come \ctyp{union} ed i valori
 eventualmente presenti dipendono dal segnale, così \macro{SIGCHLD} ed i
 eventualmente presenti dipendono dal segnale, così \macro{SIGCHLD} ed i
-segnali POSIX.1b\footnote{NdA trovare quale sono e completare l'informazione.}
-inviati tramite \func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi
-valori corrispondenti al processo che ha emesso il segnale, \macro{SIGILL},
-\macro{SIGFPE}, \macro{SIGSEGV} e \macro{SIGBUS} avvalorano \var{si\_addr} con
-l'indirizzo cui è avvenuto l'errore, \macro{SIGIO} (vedi
-\secref{sec:file_asyncronous_io}) e \macro{SIGPOLL} avvalorano \var{si\_fd}
-con il numero del file descriptor.
+segnali real-time (vedi \secref{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, \macro{SIGILL}, \macro{SIGFPE},
+\macro{SIGSEGV} e \macro{SIGBUS} avvalorano \var{si\_addr} con l'indirizzo cui
+è avvenuto l'errore, \macro{SIGIO} (vedi \secref{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.
 
 Benché sia possibile usare nello stesso programma sia \func{sigaction} che
 \func{signal} occorre molta attenzione, in quanto le due funzioni possono
 
 Benché sia possibile usare nello stesso programma sia \func{sigaction} che
 \func{signal} occorre molta attenzione, in quanto le due funzioni possono
@@ -2087,14 +2099,9 @@ presenta neanche questa necessit
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}{}
-#include <unistd.h>      /* unix standard library */
-#include <signal.h>      /* POSIX signal library */
 void alarm_hand(int);
 unsigned int sleep(unsigned int seconds)
 {
 void alarm_hand(int);
 unsigned int sleep(unsigned int seconds)
 {
-/* 
- * Variables definition  
- */
     struct sigaction new_action, old_action;
     sigset_t old_mask, stop_mask, sleep_mask;
     /* set the signal handler */
     struct sigaction new_action, old_action;
     sigset_t old_mask, stop_mask, sleep_mask;
     /* set the signal handler */
@@ -2118,9 +2125,6 @@ unsigned int sleep(unsigned int seconds)
     /* return remaining time */
     return alarm(0);
 }
     /* return remaining time */
     return alarm(0);
 }
-/*
- * Signal Handler for SIGALRM
- */
 void alarm_hand(int sig) 
 {
     return;     /* just return to interrupt sigsuspend */
 void alarm_hand(int sig) 
 {
     return;     /* just return to interrupt sigsuspend */
@@ -2149,18 +2153,18 @@ fine (\texttt{\small 27}), e al contempo si prepara la maschera dei segnali
 \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
 \func{sigsuspend}.  
 
 \var{sleep\_mask} per riattivare \macro{SIGALRM} all'esecuzione di
 \func{sigsuspend}.  
 
-In questo modo non sono più possibili race condition\index{race conditionx}
+In questo modo non sono più possibili race condition\index{race condition}
 dato che \macro{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:
 dato che \macro{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}
+\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.
 \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}
+\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 dovuto
 all'arrivo del segnale prima dell'esecuzione di \func{sigsuspend}.
 Per quanto possa sembrare strano bloccare la ricezione di un segnale per poi
 riabilitarla immediatamente dopo, in questo modo si evita il deadlock dovuto
 all'arrivo del segnale prima dell'esecuzione di \func{sigsuspend}.
@@ -2196,7 +2200,7 @@ sistema un altro stack (invece di quello relativo al processo, vedi
 \secref{sec:proc_mem_layout}) solo durante l'esecuzione di un
 manipolatore. L'uso di uno stack alternativo è del tutto trasparente ai
 manipolatori, occorre però seguire una certa procedura:
 \secref{sec:proc_mem_layout}) solo durante l'esecuzione di un
 manipolatore. L'uso di uno stack alternativo è del tutto trasparente ai
 manipolatori, occorre però seguire una certa procedura:
-\begin{enumerate}
+\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
 \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
@@ -2205,7 +2209,7 @@ manipolatori, occorre per
   specificando il flag \macro{SA\_ONSTACK} (vedi \tabref{tab:sig_sa_flag}) per
   dire al sistema di usare lo stack alternativo durante l'esecuzione del
   manipolatore. 
   specificando il flag \macro{SA\_ONSTACK} (vedi \tabref{tab:sig_sa_flag}) per
   dire al sistema di usare lo stack alternativo durante l'esecuzione del
   manipolatore. 
-\end{enumerate}
+\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,
 
 In genere il primo passo viene effettuato allocando un'opportuna area di
 memoria con \code{malloc}; in \file{signal.h} sono definite due costanti,
@@ -2347,35 +2351,125 @@ presenta dei significativi miglioramenti,\footnote{questa estensione 
   2.1(?).} in particolare sono stati superati tre limiti fondamentali dei
 segnali classici:
 \begin{description}
   2.1(?).} in particolare sono stati superati tre limiti fondamentali dei
 segnali classici:
 \begin{description}
-\item[I segnali non sono accumulati] se più segnali vengono generati prima
-  dell'esecuzione di un manipolatore questo sarà eseguito una sola volta, ed
-  il processo non sarà in grado di accorgersi di quante volte l'evento che ha
-  generato il segnale è accaduto.
-\item[I segnali non trasportano informazione] i segnali classici non prevedono
-  prevedono altra informazione sull'evento che li ha generati che il loro
-  numero.
-\item[I segnali non hanno un ordine di consegna] l'ordine in cui diversi
-  segnali vengono consegnati è casuale e non prevedibile, e dipende dalla
-  situazione in cui si trova il kernel al momento.
+\item[I segnali non sono accumulati] 
+  
+  se più segnali vengono generati prima dell'esecuzione di un manipolatore
+  questo sarà eseguito una sola volta, ed il processo non sarà in grado di
+  accorgersi di quante volte l'evento che ha generato il segnale è accaduto.
+\item[I segnali non trasportano informazione] 
+  
+  i segnali classici non prevedono prevedono altra informazione sull'evento
+  che li ha generati se non il fatto che sono stati emessi (tutta
+  l'informazione che il kernel associa ad un segnale è il suo numero).
+\item[I segnali non hanno un ordine di consegna] 
+
+  l'ordine in cui diversi segnali vengono consegnati è casuale e non
+  prevedibile. Non è possibile stabilire una priorità per cui la reazione a
+  certi segnali ha la precedenza rispetto ad altri.
 \end{description}
 
 \end{description}
 
-Le nuove caratteristiche aggiunte a quelli che vengono chiamati
-\textsl{segnali real-time}, sono le seguenti:
+
+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:
 
 \begin{itemize*}
 
 \begin{itemize*}
-\item la creazione di una coda che permette di consegnare istanze multiple
-  dello stesso segnale qualora esso venga inviato più volte prima
-  dell'esecuzione del manipolatore.
-\item l'introduzione di una priorità nella consegna dei segnali (segnali a
-  priorità più alta vengono consegnati prima).
-\item la possibilità di restituire dei dati al manipolatore, attraverso l'uso
-  della struttura \type{siginfo\_t} e dei manipolatori di tipo
-  \var{sa_sigaction}.
+\item i segnali sono inseriti in una coda che permette di consegnare istanze
+  multiple dello stesso segnale qualora esso venga inviato più volte prima
+  dell'esecuzione del manipolatore; si assicura così che il processo riceva un
+  segnale per ogni occorrenza dell'evento che lo genera.
+\item è stata introdotta una priorità nella consegna dei segnali: i segnali
+  vengono consegnati in ordine a seconda del loro valore, partendo da quelli
+  con un numero minore, che pertanto hanno una priorità maggiore.
+\item è stata introdotta la possibilità di restituire dei dati al
+  manipolatore, attraverso l'uso di un campo apposito nella struttura
+  \type{siginfo\_t} accessibile tramite manipolatori di tipo
+  \var{sa\_sigaction}.
 \end{itemize*}
 
 \end{itemize*}
 
-Per non interferire con i segnali standard POSIX i nuovi segnali sono
-definiti, in \file{signal.h} a partire da un valore minimo \macro{SIGRTMIN}
-fino \macro{SIGRTMAX} ad un massimo di
+Queste nuove caratteristiche (eccetto l'ultima, che, come visto in
+\secref{sec:sig_sigaction}, è parzialmente disponibile anche con i segnali
+ordinari) si applicano solo ai nuovi segnali real-time; questi ultimi sono
+accessibili in un range di valori specificati dalle due macro \macro{SIGRTMIN}
+e \macro{SIGRTMAX},\footnote{in Linux di solito il primo valore è 32, ed il
+  secondo \code{\_NSIG-1}, che di norma è 63, per un totale di 32 segnali
+  disponibili, contro gli almeno 8 richiesti da POSIX.1b.} che specificano il
+numero minimo e massimo associato ad un segnale real-time.
+
+I segnali con un numero più basso hanno una priorità maggiore e vengono
+consegnati per primi, inoltre i segnali real-time non possono interrompere
+l'esecuzione di un manipolatore di un segnale a priorità più alta; la loro
+azione di default è quella di terminare il programma.  I segnali ordinari
+hanno tutti la stessa priorità, che è più alta di quella di qualunque segnale
+real-time.
+
+Si tenga presente che questi nuovi segnali non sono associati a nessun evento
+sepcifico (a meno di non utilizzarli, come vedremo in
+\secref{sec:file_asyncronous_io}, per l'I/O asincrono) e devono essere inviati
+esplicitamente. Tutti i segnali real-time restituiscono al manipolatore, oltre
+ai campi \var{si\_pid} e \var{si\_uid} di \type{siginfo\_t} una struttura
+\type{sigval} (riportata in \figref{fig:sig_sigval}) in cui può essere
+restituito al processo un valore o un indirizzo, che costituisce il meccanismo
+con cui il segnale è in grado di inviare una ulteriore informazione al
+processo.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+union sigval {
+        int sival_int;
+        void *sival_ptr;
+}
+          \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \type{sigval}, usata dai segnali real time per
+    restituire dati al manipolatore.}
+  \label{fig:sig_sigval}
+\end{figure}
+
+A causa di queste loro caratteristiche, la funzione \func{kill} non è adatta
+ad inviare un segnale real time, in quanto non è in grado di fornire alcun
+valore per \var{sigval}; per questo motivo lo standard ha previsto una nuova
+funzione, \func{sigqueue}, il cui prototipo è:
+\begin{prototype}{signal.h}
+  {int sigqueue(pid\_t pid, int signo, const union sigval value)}
+  
+  Invia il segnale \param{signo} al processo \param{pid}, restituendo al
+  manipolatore il valore \param{value}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} viene settata ai valori:
+  \begin{errlist}
+  \item[\macro{EAGAIN}] La coda è esarita, ci sono già \macro{SIGQUEUE\_MAX}
+    segnali in attesa si consegna.
+  \item[\macro{EPERM}] Non si hanno privilegi appropriati per inviare il
+    segnale al processo specificato.
+  \item[\macro{ESRCH}] Il processo \param{pid} non esiste.
+  \item[\macro{EINVAL}] Si è specificato un valore non valido per
+    \param{signo}.
+  \end{errlist}
+  ed inoltre \macro{ENOMEM}.}
+\end{prototype}
+
+Il comportamento della funzione è analogo a quello di \func{kill}, ed i
+privilegi occorrenti ad inviare il segnale ad un determinato processo sono gli
+stessi; un valore nullo di \func{signo} permette di verificare le condizioni
+di errore senza inviare nessun segnale.
+
+Se il segnale è bloccato la funzione ritorna immediatamente, se si è
+installato un manipolatore con \macro{SA\_SIGINFO} e ci sono risorse
+disponibili, vale a dire che c'è posto nella coda\footnote{la profondità della
+  coda è indicata dalla costante \macro{SIGQUEUE\_MAX}, una della tante
+  costanti di sistema definite dallo standard POSIX, che non abbiamo riportato
+  esplicitamente in \secref{sec:sys_limits}. Il suo valore minimo secondo lo
+  standard, \macro{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32.}, esso viene inserito
+e diventa pendente; una volta consegnato riporterà nel campo \var{si\_code} di
+\var{siginfo} il valore \macro{SI\_QUEUE} e il campo \var{si\_value} riceverà
+quanto inviato con \param{value}. Se invece si è installato un manipolatore
+nella forma classica il segnale sarà generato, ma in caso di emissioni
+multiple prima dell'esecuzione del manipolatore, sarà ricevuto una sola volta.