Risistemazioni varie, lavori in corso
[gapil.git] / signal.tex
index 58454408615332f9a7bc5d78e41a8c6de8f8e3f1..966e32a1aa0759a2d1d6b15210171c3f2680d5e7 100644 (file)
@@ -84,8 +84,7 @@ 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: 
 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: 
-s
-e un secondo segnale arriva prima che il manipolatore invocato dal primo
+se un secondo segnale arriva prima che il manipolatore invocato dal primo
 abbia eseguito la reinstallazione di se stesso il segnale può essere perso o
 causare il comportamento originale assegnato al segnale (in genere la
 terminazione del processo).
 abbia eseguito la reinstallazione di se stesso il segnale può essere perso o
 causare il comportamento originale assegnato al segnale (in genere la
 terminazione del processo).
@@ -1501,7 +1500,7 @@ fino a trattare le caratteristiche generali della gestione dei medesimi nella
 casistica ordinaria.
 
 
 casistica ordinaria.
 
 
-\subsection{Un esempio di problema}
+\subsection{Alcune problematiche aperte}
 \label{sec:sig_example}
 
 Come accennato in \secref{sec:sig_pause_sleep} è possibile implementare
 \label{sec:sig_example}
 
 Come accennato in \secref{sec:sig_pause_sleep} è possibile implementare
@@ -1622,9 +1621,45 @@ Ma anche questa implementazione comporta dei problemi; in questo caso infatti
 non viene gestita correttamente l'interazione con gli altri segnali; se
 infatti il segnale di allarme interrompe un altro manipolatore, in questo caso
 l'esecuzione non riprenderà nel manipolatore in questione, ma nel ciclo
 non viene gestita correttamente l'interazione con gli altri segnali; se
 infatti il segnale di allarme interrompe un altro manipolatore, in questo caso
 l'esecuzione non riprenderà nel manipolatore in questione, ma nel ciclo
-principale, interrompendone inopportunamente l'esecuzione.  È per questo
-motivo che occorrono funzioni più sofisticate della semplice \func{signal} che
-permettano di gestire i segnali in maniera più completa.
+principale, interrompendone inopportunamente l'esecuzione.  
+
+Lo stesso tipo di problema si presenterebbe se si volesse usare \func{alarm}
+per stabilire un timeout su una sistem call bloccante. Un secondo esempio è
+quello in cui si usa il segnale per notificare una quelche forma di evento; in
+genere quello che si fa in questo caso è settare nel manipolatore un opportuno
+flag da controllare nel corpo principale del programma (con un codice del tipo
+di quello riportato in 
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}{}
+sig_atomic_t flag;
+unsigned int control(unsigned int seconds)
+{
+    da fare
+}
+void alarm_hand(int sig) 
+{
+    /* set the flag 
+    flag = 1;
+}      
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Un esempio non funzionante di restituzione di un evento da parte di
+    un segnale.} 
+  \label{fig:sig_event_wrong}
+\end{figure}
+
+
+
+È per questo motivo che occorrono funzioni più sofisticate della semplice
+\func{signal} che permettano di gestire i segnali in maniera più completa.
+
+
+
+
 
 
 \subsection{I \textit{signal set}}
 
 
 \subsection{I \textit{signal set}}
@@ -1636,10 +1671,10 @@ superabili; in particolare non 
 gestire gestire il blocco dei segnali o di verificare lo stato dei segnali
 pendenti.
 
 gestire gestire il blocco dei segnali o di verificare lo stato dei segnali
 pendenti.
 
-Per questo motivo lo standard POSIX, insieme alla nuova semantica dei segnali
-ha introdotto una interfaccia di gestione completamente nuova, che permette di
-ottenete un controllo molto più dettagliato. In particolare lo standard ha
-introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
+Per questo motivo lo standard POSIX.1, insieme alla nuova semantica dei
+segnali ha introdotto una interfaccia di gestione completamente nuova, che
+permette di ottenete un controllo molto più dettagliato. In particolare lo
+standard ha introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
 rappresentare un insieme di segnali (un \textit{signal set}, come viene
 usualmente chiamato), che è il tipo di dato che viene usato per gestire il
 blocco dei segnali.
 rappresentare un insieme di segnali (un \textit{signal set}, come viene
 usualmente chiamato), che è il tipo di dato che viene usato per gestire il
 blocco dei segnali.
@@ -1651,7 +1686,7 @@ macchina\footnote{nel caso dei PC questo comporta un massimo di 32 segnali
   nessuna struttura più complicata.}, ciascun bit del quale è associato ad uno
 specifico segnale; in questo modo è di solito possibile implementare le
 operazioni direttamente con istruzioni elementari del processore; lo standard
   nessuna struttura più complicata.}, ciascun bit del quale è associato ad uno
 specifico segnale; in questo modo è di solito possibile implementare le
 operazioni direttamente con istruzioni elementari del processore; lo standard
-POSIX definisce cinque funzioni per la manipolazione dei \textit{signal set},
+POSIX.1 definisce cinque funzioni per la manipolazione dei \textit{signal set},
 \func{sigemptyset}, \func{sigfillset}, \func{sigaddset}, \func{sigdelset} e
 \func{sigismember}, i cui prototipi sono:
 \begin{functions}
 \func{sigemptyset}, \func{sigfillset}, \func{sigaddset}, \func{sigdelset} e
 \func{sigismember}, i cui prototipi sono:
 \begin{functions}
@@ -1697,7 +1732,7 @@ la presenza di uno specifico segnale in un \textit{signal set}.
 \subsection{La funzione \func{sigaction}}
 \label{sec:sig_sigaction}
 
 \subsection{La funzione \func{sigaction}}
 \label{sec:sig_sigaction}
 
-La funzione principale dell'interfaccia standard POSIX per i segnali è
+La funzione principale dell'interfaccia standard POSIX.1 per i segnali è
 \func{sigaction}, essa ha sostanzialemente le stesse funzioni di
 \func{signal}, permette cioè di specificare come un segnale può essere gestito
 da un processo. Il suo prototipo è:
 \func{sigaction}, essa ha sostanzialemente le stesse funzioni di
 \func{signal}, permette cioè di specificare come un segnale può essere gestito
 da un processo. Il suo prototipo è:
@@ -1717,14 +1752,14 @@ da un processo. Il suo prototipo 
   \end{errlist}}
 \end{prototype}
 
   \end{errlist}}
 \end{prototype}
 
-La funzione serve ad installare una nuova azione per il segnale
-\param{signum}; si parla di azione e non di manipolatore come nel caso di
-\func{signal}, in quanto la funzione consente di specificare le varie
-caratteristiche della risposta al segnale, non solo la funzione del
-manipolatore.  Lo standard POSIX raccomanda di usare sempre questa funzione al
-posto di \func{signal} (che in genere viene definita tramite essa), in quanto
-offre un controllo completo su tutti gli aspetti della gestione di un segnale,
-sia pure al prezzo di una maggiore complessità d'uso.
+La funzione serve ad installare una nuova \textsl{azione} per il segnale
+\param{signum}; si parla di \textsl{azione} e non di \textsl{manipolatore}
+come nel caso di \func{signal}, in quanto la funzione consente di specificare
+le varie caratteristiche della risposta al segnale, non solo la funzione del
+manipolatore.  Per questo lo standard raccomanda di usare sempre questa
+funzione al posto di \func{signal} (che in genere viene definita tramite
+essa), in quanto offre un controllo completo su tutti gli aspetti della
+gestione di un segnale, sia pure al prezzo di una maggiore complessità d'uso.
 
 Se il puntatore \param{act} non è nullo, la funzione installa la nuova azione
 da esso specificata, se \param{oldact} non è nullo il valore dell'azione
 
 Se il puntatore \param{act} non è nullo, la funzione installa la nuova azione
 da esso specificata, se \param{oldact} non è nullo il valore dell'azione
@@ -1734,7 +1769,7 @@ che non consente di ottenere l'azione corrente senza installarne una nuova.
 
 Entrambi i puntatori fanno riferimento alla struttura \var{sigaction}, tramite
 la quale si specificano tutte le caratteristiche dell'azione associata ad un
 
 Entrambi i puntatori fanno riferimento alla struttura \var{sigaction}, tramite
 la quale si specificano tutte le caratteristiche dell'azione associata ad un
-segnale.  Anch'essa è descritta dallo standard POSIX ed in Linux è definita
+segnale.  Anch'essa è descritta dallo standard POSIX.1 ed in Linux è definita
 secondo quanto riportato in \figref{fig:sig_sigaction}. Il campo
 \var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere
 più usato.
 secondo quanto riportato in \figref{fig:sig_sigaction}. Il campo
 \var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere
 più usato.
@@ -1743,7 +1778,8 @@ pi
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct sigaction {
+struct sigaction 
+{
     void (*sa_handler)(int);
     void (*sa_sigaction)(int, siginfo_t *, void *);
     sigset_t sa_mask;
     void (*sa_handler)(int);
     void (*sa_sigaction)(int, siginfo_t *, void *);
     sigset_t sa_mask;
@@ -1757,26 +1793,95 @@ struct sigaction {
   \label{fig:sig_sigaction}
 \end{figure}
 
   \label{fig:sig_sigaction}
 \end{figure}
 
-Come riportato in \figref{fig:sig_sigaction} in Linux \func{sigaction} permette
-di specificare il manipolatore in due forme diverse, indicate dai campi
-\var{sa\_handler} e \var{sa\_sigaction}; esse devono essere usate in maniera
-alternativa (in certe implementazioni questi vengono specificati come
-\ctyp{union}); la prima è quella classica usata anche con \func{signal}, la
-seconda permette invece di usare un manipolatore in grado di ricevere
-informazioni più dettagliate dal sistema (ad esempio il tipo di errore in caso
-di \macro{SIGFPE}).
+Come si può notare da quanto riportato in \figref{fig:sig_sigaction} in Linux
+\func{sigaction} permette di specificare il manipolatore in due forme diverse,
+indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere
+usate in maniera alternativa (in certe implementazioni questi vengono
+specificati come \ctyp{union}): la prima è quella classica usata anche con
+\func{signal}, la seconda permette invece di usare un manipolatore in grado di
+ricevere informazioni più dettagliate dal sistema (ad esempio il tipo di
+errore in caso di \macro{SIGFPE}), attraverso dei parametri aggiuntivi; per i
+dettagli si consulti la man page di \func{sigaction}).
+
+Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
+essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque
+sempre aggiunto il segnale che ne ha causato la chiamata, a meno che non si
+sia specificato con \var{sa\_flag} un comportamento diverso.
+
+Il valore di \var{sa\_flag} permette di specificare vari aspetti del
+comportamento di \func{sigaction}, e della reazione del processo ai vari
+segnali; i valori possibili ed il relativo significato sono riportati in
+\tabref{tab:sig_sa_flag}. 
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Timer} \\
+    \hline
+    \hline
+    \macro{SA\_NOCLDSTOP}& Se il segnale è \macro{SIGCHLD} allora non deve
+    essere notificato quando il processo figlio viene fermato da uno dei
+    segnali \macro{SIGSTOP}, \macro{SIGTSTP}, \macro{SIGTTIN} or 
+    \macro{SIGTTOU}.\\
+    \macro{SA\_ONESHOT}  & Ristabilisce l'azione per il segnale al valore di
+    default una volta che il manipolatore è stato lanciato, riproduce cioè il
+    comportamento della semantica inaffidabile.\\
+    \macro{SA\_RESETHAND}& Sinonimo di \macro{SA\_ONESHOT}. \\
+    \macro{SA\_RESTART}  & Riavvia automaticamente le \textit{slow system
+    call} quando vengono interrotte dal suddetto segnale; riproduce cioè il
+    comportamento standard di BSD.\\
+    \macro{SA\_NOMASK}   & Evita che il segnale corrente sia bloccato durante
+    l'esecuzione del manipolatore.\\
+    \macro{SA\_NODEFER}  & Sinonimo di  \macro{SA\_NOMASK}.\\
+    \macro{SA\_SIGINFO}  & Deve essere specificato quando si vuole usare un
+    manipolatore in forma estesa usando \var{sa\_sigaction} al posto di
+    \var{sa\_handler}. \\
+    \macro{SA\_ONSTACK}   & Stabilisce l'uso di uno stack alternativo per
+    l'esecuzione del manipolatore (vedi \secref{sec:sig_altstack}).\\
+    \hline
+  \end{tabular}
+  \caption{Valori del campo \var{sa\_flag} della struttura \var{sigaction}.}
+  \label{tab:sig_sa_flag}
+\end{table}
 
 
+Benché sia possibile usare nello stesso programma sia \func{sigaction} che
+\func{signal} occorre molta attenzione, in quanto le due funzioni possono
+interagire in maniera anomala. Infatti l'azione specificata con
+\var{sigaction} contiene un maggior numero di informazioni rispetto al
+semplice indirizzo del manipolatore restituito da \func{signal}.  Per questo
+motivo se si usa quest'ultima per installare un manipolatore sostituendone uno
+precedentemente installato con \func{sigaction}, non sarà possibile effettuare
+un ripristino corretto dello stesso.
 
 
+Per questo è sempre opportuno usare \func{sigaction}, che è in grado di
+ripristinare correttamente un manipolatore precedente, anche se questo è stato
+installato con \func{signal}. In generale poi non è il caso di usare il valore
+di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato
+che in certi sistemi questi possono essere diversi. In generale dunque, a meno
+che non si sia vincolati allo standard ISO C, è sempre il caso di evitare
+l'uso di \func{signal} a favore di \func{sigaction}.
 
 
 
 \subsection{La gestione del blocco dei segnali}
 \label{sec:sig_sigmask}
 
 
 
 
 \subsection{La gestione del blocco dei segnali}
 \label{sec:sig_sigmask}
 
-Una delle informazioni che ciascun processo porta con se è l'insieme
-(anch'esso un signal set) dei segnali bloccati (la cosiddetta \textit{signal
-  mask}, mantenuta nel campo \var{blocked} di \var{task\_struct}); abbiamo
-accennato in \secref{sec:proc_fork} che essa viene ereditata da un processo 
+Come spiegato in \secref{sec:sig_semantics} tutti i moderni sistemi unix-like
+permettono si bloccare temporaneamente (o di eliminare completamente, settando
+\macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è
+fatto specificando la cosiddetta \textit{signal mask} del
+processo\footnote{nel caso di Linux essa è mantenuta dal campo \var{blocked}
+  della relativa \var{task\_struct}} che viene espressa come il signal set dei
+segnali la cui consegna è bloccata. Abbiamo accennato in
+\secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre
+alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente
+che essa può essere specificata, durante l'esecuzione di un manipolatore,
+attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}.
+
+Uno dei problemi evidenziatisi con l'esempio di 
+
 
 
 \subsection{Le funzioni \func{sigpending} e \func{sigsuspend}}
 
 
 \subsection{Le funzioni \func{sigpending} e \func{sigsuspend}}