Indicizzati file sotto /proc, ed ulteriore materiale su ''inotify''.
[gapil.git] / signal.tex
index edbc674a269a802be44392f4542287b56a155fbe..f2dd09b6ee78e523cd774f1e1413deac74f37997 100644 (file)
@@ -304,12 +304,12 @@ definiti in vari standard.
     \textbf{Sigla} & \textbf{Significato} \\
     \hline
     \hline
-    A & L'azione predefinita è terminare il processo. \\
-    B & L'azione predefinita è ignorare il segnale. \\
+    A & L'azione predefinita è terminare il processo.\\
+    B & L'azione predefinita è ignorare il segnale.\\
     C & L'azione predefinita è terminare il processo e scrivere un 
-        \itindex{core~dump} \textit{core dump}. \\
-    D & L'azione predefinita è fermare il processo. \\
-    E & Il segnale non può essere intercettato. \\
+        \itindex{core~dump} \textit{core dump}.\\
+    D & L'azione predefinita è fermare il processo.\\
+    E & Il segnale non può essere intercettato.\\
     F & Il segnale non può essere ignorato.\\
     \hline
   \end{tabular}
@@ -334,10 +334,10 @@ colonna standard sono stati indicati anche gli standard in cui ciascun segnale
     \textbf{Sigla} & \textbf{Standard} \\
     \hline
     \hline
-    P & POSIX. \\
-    B & BSD. \\
-    L & Linux.\\
-    S & SUSv2.\\
+    P & POSIX \\
+    B & BSD \\
+    L & Linux \\
+    S & SUSv2 \\
     \hline
   \end{tabular}
   \caption{Legenda dei valori della colonna \textbf{Standard} di 
@@ -904,18 +904,20 @@ e che prende un argomento di tipo \ctyp{int}.\footnote{si devono usare le
   operatori del C, senza di esse si sarebbe definita una funzione che ritorna
   un puntatore a \ctyp{void} e non un puntatore ad una funzione \ctyp{void}.}
 La funzione \func{signal} quindi restituisce e prende come secondo argomento
-un puntatore a una funzione di questo tipo, che è appunto il gestore del
-segnale.
-
-Il numero di segnale passato in \param{signum} può essere indicato
-direttamente con una delle costanti definite in sez.~\ref{sec:sig_standard}. Il
-gestore \param{handler} invece, oltre all'indirizzo della funzione da chiamare
-all'occorrenza del segnale, può assumere anche i due valori costanti
-\const{SIG\_IGN} con cui si dice di ignorare il segnale e \const{SIG\_DFL} per
-reinstallare l'azione predefinita.\footnote{si ricordi però che i due segnali
+un puntatore a una funzione di questo tipo, che è appunto la funzione che
+verrà usata come gestore del segnale.
+
+Il numero di segnale passato nell'argomento \param{signum} può essere indicato
+direttamente con una delle costanti definite in sez.~\ref{sec:sig_standard}.
+L'argomento \param{handler} che indica il gestore invece, oltre all'indirizzo
+della funzione da chiamare all'occorrenza del segnale, può assumere anche i
+due valori costanti \const{SIG\_IGN} e \const{SIG\_DFL}; il primo indica che
+il segnale deve essere ignorato,\footnote{si ricordi però che i due segnali
   \const{SIGKILL} e \const{SIGSTOP} non possono essere né ignorati né
   intercettati; l'uso di \const{SIG\_IGN} per questi segnali non ha alcun
-  effetto.}
+  effetto.} mentre il secondo ripristina l'azione predefinita.\footnote{e
+  serve a tornare al comportamento di default quando non si intende più
+  gestire direttamente un segnale.}
 
 La funzione restituisce l'indirizzo dell'azione precedente, che può essere
 salvato per poterlo ripristinare (con un'altra chiamata a \func{signal}) in un
@@ -954,9 +956,10 @@ questi segnali pu
 \subsection{Le funzioni \func{kill} e \func{raise}}
 \label{sec:sig_kill_raise}
 
-Come accennato in sez.~\ref{sec:sig_types}, un segnale può essere generato
-direttamente da un processo attraverso una opportuna system call. Le funzioni
-che si usano di solito per inviare un segnale generico sono due, \func{raise} e
+Come precedentemente accennato in sez.~\ref{sec:sig_types}, un segnale può
+anche essere generato direttamente nell'esecuzione di un programma, attraverso
+la chiamata ad una opportuna system call. Le funzioni che si utilizzano di
+solito per inviare un segnale generico ad un processo sono due: \func{raise} e
 \func{kill}.
 
 La prima funzione è \funcd{raise}, che è definita dallo standard ANSI C, e
@@ -1042,11 +1045,11 @@ Una seconda funzione che pu
     \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    $>0$ & il segnale è mandato al processo con il \acr{pid} indicato.\\
-    0    & il segnale è mandato ad ogni processo del \itindex{process~group}
+    $>0$ & Il segnale è mandato al processo con il \acr{pid} indicato.\\
+    0    & Il segnale è mandato ad ogni processo del \itindex{process~group}
            \textit{process group} del chiamante.\\ 
-    $-1$ & il segnale è mandato ad ogni processo (eccetto \cmd{init}).\\
-    $<-1$ & il segnale è mandato ad ogni processo del \textit{process group} 
+    $-1$ & Il segnale è mandato ad ogni processo (eccetto \cmd{init}).\\
+    $<-1$ & Il segnale è mandato ad ogni processo del \textit{process group} 
             \itindex{process~group} $|\code{pid}|$.\\
     \hline
   \end{tabular}
@@ -1550,17 +1553,21 @@ vuoto.
 
 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 gestore, in questo caso
-l'esecuzione non riprenderà nel gestore in questione, ma nel ciclo
-principale, interrompendone inopportunamente l'esecuzione.  Lo stesso tipo di
-problemi si presenterebbero se si volesse usare \func{alarm} per stabilire un
-timeout su una qualunque system call bloccante.
+infatti il segnale di allarme interrompe un altro gestore, l'esecuzione non
+riprenderà nel gestore in questione, ma nel ciclo principale, interrompendone
+inopportunamente l'esecuzione.  Lo stesso tipo di problemi si presenterebbero
+se si volesse usare \func{alarm} per stabilire un timeout su una qualunque
+system call bloccante.
 
 Un secondo esempio è quello in cui si usa il segnale per notificare una
 qualche forma di evento; in genere quello che si fa in questo caso è impostare
 nel gestore un opportuno flag da controllare nel corpo principale del
 programma (con un codice del tipo di quello riportato in
-fig.~\ref{fig:sig_event_wrong}).
+fig.~\ref{fig:sig_event_wrong}). La logica è quella di far impostare al
+gestore (\texttt{\small 14-19}) una variabile globale preventivamente
+inizializzata nel programma principale, il quale potrà determinare,
+osservandone il contenuto, l'occorrenza o meno del segnale, e prendere le
+relative azioni conseguenti (\texttt{\small 6-11}).
 
 \begin{figure}[!htb]
   \footnotesize\centering
@@ -1573,11 +1580,6 @@ fig.~\ref{fig:sig_event_wrong}).
   \label{fig:sig_event_wrong}
 \end{figure}
 
-La logica è quella di far impostare al gestore (\texttt{\small 14-19}) una
-variabile globale preventivamente inizializzata nel programma principale, il
-quale potrà determinare, osservandone il contenuto, l'occorrenza o meno del
-segnale, e prendere le relative azioni conseguenti (\texttt{\small 6-11}).
-
 Questo è il tipico esempio di caso, già citato in
 sez.~\ref{sec:proc_race_cond}, in cui si genera una \itindex{race~condition}
 \textit{race condition}; infatti, in una situazione in cui un segnale è già
@@ -1735,13 +1737,13 @@ l'invocazione.
 L'uso di questo campo permette ad esempio di risolvere il problema residuo
 dell'implementazione di \code{sleep} mostrata in
 fig.~\ref{fig:sig_sleep_incomplete}. In quel caso infatti se il segnale di
-allarme avesse interrotto un altro gestore questo non sarebbe stato
-eseguito correttamente; la cosa poteva essere prevenuta installando gli altri
-gestori usando \var{sa\_mask} per bloccare \const{SIGALRM} durante la
-loro esecuzione.  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 tab.~\ref{tab:sig_sa_flag}.
+allarme avesse interrotto un altro gestore questo non sarebbe stato eseguito
+correttamente; la cosa poteva essere prevenuta installando gli altri gestori
+usando \var{sa\_mask} per bloccare \const{SIGALRM} durante la loro esecuzione.
+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
+tab.~\ref{tab:sig_sa_flag}.
 
 \begin{table}[htb]
   \footnotesize
@@ -1756,30 +1758,39 @@ in tab.~\ref{tab:sig_sa_flag}.
                            fermato da uno dei segnali \const{SIGSTOP},
                            \const{SIGTSTP}, \const{SIGTTIN} o 
                            \const{SIGTTOU}.\\
-    \const{SA\_ONESHOT}  & Ristabilisce l'azione per il segnale al valore 
+    \const{SA\_RESETHAND}& Ristabilisce l'azione per il segnale al valore 
                            predefinito una volta che il gestore è stato
                            lanciato, riproduce cioè il comportamento della
                            semantica inaffidabile.\\  
-    \const{SA\_RESETHAND}& Sinonimo di \const{SA\_ONESHOT}. \\
+    \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\_RESTART}  & Riavvia automaticamente le \textit{slow system
                            call} quando vengono interrotte dal suddetto
                            segnale; riproduce cioè il comportamento standard
                            di BSD.\index{system~call~lente}\\ 
-    \const{SA\_NOMASK}   & Evita che il segnale corrente sia bloccato durante
+    \const{SA\_NODEFER}  & Evita che il segnale corrente sia bloccato durante
                            l'esecuzione del gestore.\\
-    \const{SA\_NODEFER}  & Sinonimo di \const{SA\_NOMASK}.\\
+    \const{SA\_NOMASK}   & Nome obsoleto, sinonimo non standard di
+                           \const{SA\_NODEFER}.\\ 
     \const{SA\_SIGINFO}  & Deve essere specificato quando si vuole usare un
                            gestore in forma estesa usando
-                           \var{sa\_sigaction} al posto di \var{sa\_handler}.\\
-    \const{SA\_ONSTACK}  & Stabilisce l'uso di uno \itindex{stack} stack 
-                           alternativo per l'esecuzione del gestore (vedi
-                           sez.~\ref{sec:sig_specific_features}).\\ 
+                           \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
+                           terminano.\footnotemark \\ 
     \hline
   \end{tabular}
   \caption{Valori del campo \var{sa\_flag} della struttura \struct{sigaction}.}
   \label{tab:sig_sa_flag}
 \end{table}
 
+\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
@@ -2224,11 +2235,88 @@ parte l'uso di \type{sigjmp\_buf} per \param{env}, 
 \func{longjmp}.
 
 
+\subsection{Criteri di programmazione per i gestori dei segnali}
+\label{sec:sig_signal_handler}
+
+Abbiamo finora parlato dei gestori dei segnali come funzioni chiamate in
+corrispondenza della consegna di un segnale. In realtà un gestore non può
+essere una funzione qualunque, in quanto esso può essere eseguito in
+corrispondenza all'interruzione in un punto qualunque del programma principale,
+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|(}
+
+Il concetto è comunque più generale e porta ad una distinzione fra quelle che
+che POSIX chiama \textsl{funzioni insicure} (\textit{n'Usane function}) e
+\textsl{funzioni sicure} (\textit{safe function}); quando un segnale
+interrompe una funzione insicura ed il gestore chiama al suo interno una
+funzione insicura il sistema può dare luogo ad un comportamento indefinito.
+
+Tutto questo significa che un gestore di segnale deve essere programmato con
+molta cura per evitare questa evenienza, pertanto è non è possibile chiamare
+al suo interno una funzione qualunque, e si può ricorrere soltanto all'uso di
+funzioni sicure.
+
+L'elenco delle funzioni sicure varia a secondo dello standard a cui si fa
+riferimento, secondo quanto riportato dallo standard POSIX 1003.1 nella
+revisione del 2003, le ``\textit{signal safe function}'' che possono essere
+chiamate anche all'interno di un gestore di segnali sono quelle della lista
+riportata in fig.~\ref{fig:sig_safe_functions}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \func{\_exit}, \func{abort}, \func{accept}, \func{access},
+    \func{aio\_error} \func{aio\_return}, \func{aio\_suspend}, \func{alarm},
+    \func{bind}, \func{cfgetispeed}, \func{cfgetospeed}, \func{cfsetispeed},
+    \func{cfsetospeed}, \func{chdir}, \func{chmod}, \func{chown},
+    \func{clock\_gettime}, \func{close}, \func{connect}, \func{creat},
+    \func{dup}, \func{dup2}, \func{execle}, \func{execve}, \func{fchmod},
+    \func{fchown}, \func{fcntl}, \func{fdatasync}, \func{fork},
+    \func{fpathconf}, \func{fstat}, \func{fsync}, \func{ftruncate},
+    \func{getegid}, \func{geteuid}, \func{getgid}, \func{getgroups},
+    \func{getpeername}, \func{getpgrp}, \func{getpid}, \func{getppid},
+    \func{getsockname}, \func{getsockopt}, \func{getuid}, \func{kill},
+    \func{link}, \func{listen}, \func{lseek}, \func{lstat}, \func{mkdir},
+    \func{mkfifo}, \func{open}, \func{pathconf}, \func{pause}, \func{pipe},
+    \func{poll}, \func{posix\_trace\_event}, \func{pselect}, \func{raise},
+    \func{read}, \func{readlink}, \func{recv}, \func{recvfrom},
+    \func{recvmsg}, \func{rename}, \func{rmdir}, \func{select},
+    \func{sem\_post}, \func{send}, \func{sendmsg}, \func{sendto},
+    \func{setgid}, \func{setpgid}, \func{setsid}, \func{setsockopt},
+    \func{setuid}, \func{shutdown}, \func{sigaction}, \func{sigaddset},
+    \func{sigdelset}, \func{sigemptyset}, \func{sigfillset},
+    \func{sigismember}, \func{signal}, \func{sigpause}, \func{sigpending},
+    \func{sigprocmask}, \func{sigqueue}, \func{sigset}, \func{sigsuspend},
+    \func{sleep}, \func{socket}, \func{socketpair}, \func{stat},
+    \func{symlink}, \func{sysconf}, \func{tcdrain}, \func{tcflow},
+    \func{tcflush}, \func{tcgetattr}, \func{tcgetgrp}, \func{tcsendbreak},
+    \func{tcsetattr}, \func{tcsetpgrp}, \func{time}, \func{timer\_getoverrun},
+    \func{timer\_gettime}, \func{timer\_settime}, \func{times}, \func{umask},
+    \func{uname}, \func{unlink}, \func{utime}, \func{wait}, \func{waitpid},
+    \func{write}.
+  \end{minipage} 
+  \normalsize 
+  \caption{Elenco delle funzioni sicure secondo lo standard POSIX
+    1003.1-2003.}
+  \label{fig:sig_safe_functions}
+\end{figure}
+
+\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
+operazioni complesse è sempre preferibile utilizzare la tecnica in cui si usa
+il gestore per impostare il valore di una qualche variabile globale, e poi si
+eseguono le operazioni complesse nel programma verificando (con tutti gli
+accorgimenti visti in precedenza) il valore di questa variabile tutte le volte
+che si è rilevata una interruzione dovuta ad un segnale.
+
 
 \subsection{I segnali real-time}
 \label{sec:sig_real_time}
 
-
 Lo standard POSIX.1b, nel definire una serie di nuove interfacce per i servizi
 real-time, ha introdotto una estensione del modello classico dei segnali che
 presenta dei significativi miglioramenti,\footnote{questa estensione è stata
@@ -2364,8 +2452,8 @@ installato un gestore con \const{SA\_SIGINFO} e ci sono risorse disponibili,
   sez.~\ref{sec:sys_limits}; il suo valore minimo secondo lo standard,
   \const{\_POSIX\_SIGQUEUE\_MAX}, è pari a 32. Nel caso di Linux questo è uno
   dei parametri del kernel impostabili sia con \func{sysctl}, che scrivendolo
-  direttamente in \file{/proc/sys/kernel/rtsig-max}, il valore predefinito è
-  di 1024.} nella coda dei segnali real-time) esso viene inserito e diventa
+  direttamente in \procfile{/proc/sys/kernel/rtsig-max}, il valore predefinito
+  è di 1024.} nella coda dei segnali real-time) esso viene inserito e diventa
 pendente; una volta consegnato riporterà nel campo \var{si\_code} di
 \struct{siginfo\_t} il valore \const{SI\_QUEUE} e il campo \var{si\_value}
 riceverà quanto inviato con \param{value}. Se invece si è installato un
@@ -2462,10 +2550,7 @@ questa maniera devono essere mascherati per tutti i thread, compreso quello
 dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive.
 
 
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End: 
+
 
 % LocalWords:  kernel POSIX timer shell control ctrl kill raise signal handler
 % LocalWords:  reliable unreliable fig race condition sez struct process table
@@ -2497,5 +2582,22 @@ dedicato alla gestione, che potrebbe riceverlo fra due chiamate successive.
 % LocalWords:  how oldset BLOCK UNBLOCK SETMASK sigsuspend sigaltstack malloc
 % LocalWords:  SIGSTKSZ MINSIGSTKSZ ss oss ENOMEM flags DISABLE sp setrlimit LB
 % LocalWords:  RLIMIT rlim sigsetjmp siglongjmp sigjmp buf env savesigs jmp ptr
-% LocalWords:  SIGRTMIN SIGRTMAX sigval sival sigevent sigqueue EAGAIN sysctl
-% LocalWords:  QUEUE thread sigwait sigwaitinfo sigtimedwait info DEF SLB
+% LocalWords:  SIGRTMIN SIGRTMAX sigval sigevent sigqueue EAGAIN sysctl safe
+% LocalWords:  QUEUE thread sigwait sigwaitinfo sigtimedwait info DEF SLB bind
+% LocalWords:  function accept return cfgetispeed cfgetospeed cfsetispeed chdir
+% LocalWords:  cfsetospeed chmod chown gettime close connect creat dup execle
+% LocalWords:  execve fchmod fchown fdatasync fpathconf fstat fsync ftruncate
+% LocalWords:  getegid geteuid getgid getgroups getpeername getpgrp getppid sem
+% LocalWords:  getsockname getsockopt getuid listen lseek lstat mkdir mkfifo
+% LocalWords:  pathconf poll posix pselect read readlink recv recvfrom recvmsg
+% LocalWords:  rename rmdir select send sendmsg sendto setgid setpgid setsid
+% LocalWords:  setsockopt setuid shutdown sigpause socketpair stat symlink
+% LocalWords:  sysconf tcdrain tcflow tcflush tcgetattr tcgetgrp tcsendbreak
+% LocalWords:  tcsetattr tcsetpgrp getoverrun times umask uname unlink utime
+% LocalWords:  write sival
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: