agiunti TODO, informazioni e riferimenti
[gapil.git] / signal.tex
index c408ef30cbfb11306d8cd3b9a73191afaaacb57a..08f7b8d2d504695f5b9fb5ddcdd0d2f626367c68 100644 (file)
@@ -1044,7 +1044,7 @@ estensione GNU, definita dalla \acr{glibc}, che permette di riscrivere il
 prototipo di \func{signal} nella forma appena vista, molto più leggibile di
 quanto non sia la versione originaria, che di norma è definita come:
 \includecodesnip{listati/signal.c}
-questa infatti, per la poca chiarezza della sintassi del C quando si vanno a
+questa infatti, per la complessità della sintassi del C quando si vanno a
 trattare puntatori a funzioni, è molto meno comprensibile.  Da un confronto
 con il precedente prototipo si può dedurre la definizione di
 \typed{sighandler\_t} che è:
@@ -1083,11 +1083,11 @@ notificati.
 L'uso di \func{signal} è soggetto a problemi di compatibilità, dato che essa
 si comporta in maniera diversa per sistemi derivati da BSD o da System V. In
 questi ultimi infatti la funzione è conforme al comportamento originale dei
-primi Unix in cui il gestore viene disinstallato alla sua chiamata, secondo la
+primi Unix in cui il gestore viene disinstallato alla sua chiamata secondo la
 semantica inaffidabile; anche Linux seguiva questa convenzione con le vecchie
 librerie del C come la \acr{libc4} e la \acr{libc5}.\footnote{nelle
-  \acr{libc5} esiste però la possibilità di includere \file{bsd/signal.h} al
-  posto di \headfile{signal.h}, nel qual caso la funzione \func{signal} viene
+  \acr{libc5} esisteva però la possibilità di includere \file{bsd/signal.h} al
+  posto di \headfile{signal.h}, nel qual caso la funzione \func{signal} era
   ridefinita per seguire la semantica affidabile usata da BSD.}
 
 Al contrario BSD segue la semantica affidabile, non disinstallando il gestore
@@ -1096,12 +1096,16 @@ e bloccando il segnale durante l'esecuzione dello stesso. Con l'utilizzo della
 comportamento della versione originale della funzione, il cui uso è deprecato
 per i motivi visti in sez.~\ref{sec:sig_semantics}, può essere ottenuto
 chiamando \funcm{sysv\_signal}, una volta che si sia definita la macro
-\macro{\_XOPEN\_SOURCE}.  In generale, per evitare questi problemi, l'uso di
-\func{signal}, che tra l'altro ha un comportamento indefinito in caso di
-processo multi-\textit{thread}, è da evitare: tutti i nuovi programmi devono
+\macro{\_XOPEN\_SOURCE}.
+
+In generale, per evitare questi problemi e per le possibili differenze nella
+semantica fra versioni diverse di kernel, l'uso di \func{signal} è sempre da
+evitare, visto che tra l'altro la funzione ha un comportamento indefinito in
+caso di processi multi-\textit{thread}; l'unico utilizzo sicuro della funzione
+è con \const{SIG\_IGN} e \const{SIG\_DFL}, in tutti gli altri casi si deve
 usare \func{sigaction}.
 
-È da tenere presente che su Linux, seguendo lo standard POSIX, il
+Infine si deve tenere presente che su Linux, seguendo lo standard POSIX, il
 comportamento di un processo che ignora i segnali \signal{SIGFPE},
 \signal{SIGILL}, o \signal{SIGSEGV}, qualora questi non originino da una
 chiamata ad una \func{kill} o altra funzione affine, è indefinito. Un gestore
@@ -1147,9 +1151,9 @@ chiamando \func{raise}.
 
 In realtà \func{raise} è una funzione di libreria, che per i processi ordinari
 veniva implementata (nelle versioni più recenti del kernel viene usata
-\func{tgkill} che vedremo in sez.~\ref{cha:thread_xxx}) attraverso la funzione
-di sistema \funcd{kill} che è quella che consente effettivamente di inviare un
-segnale generico ad un processo, il suo prototipo è:
+\func{tgkill} che vedremo in sez.~\ref{sec:thread_signal}) attraverso la
+funzione di sistema \funcd{kill} che è quella che consente effettivamente di
+inviare un segnale generico ad un processo, il suo prototipo è:
 
 \begin{funcproto}{
 \fhead{sys/types.h}
@@ -1190,7 +1194,7 @@ con \param{pid} non esistono.
     $>0$ & Il segnale è mandato al processo con \ids{PID} uguale
            a \param{pid}.\\
     0    & Il segnale è mandato ad ogni processo del \textit{process group}
-           del chiamante.\\  
+           (vedi sez.~\ref{sec:sess_proc_group}) del chiamante.\\  
     $-1$ & Il segnale è mandato ad ogni processo (eccetto \cmd{init}).\\
     $<-1$& Il segnale è mandato ad ogni processo del \textit{process group} 
            con \ids{PGID} uguale a $|\param{pid}|$.\\
@@ -1208,13 +1212,16 @@ illustrato in tab.~\ref{tab:sig_kill_values} che riporta i valori possibili
 per questo argomento. Si tenga conto però che il sistema ricicla i \ids{PID}
 (come accennato in sez.~\ref{sec:proc_pid}) per cui l'esistenza di un processo
 non significa che esso sia realmente quello a cui si intendeva mandare il
-segnale.
+segnale (torneremo su questo in sez.~\ref{sec:sig_pid_fd}).
 
 Indipendentemente dalla funzione specifica che viene usata solo
 l'amministratore può inviare un segnale ad un processo qualunque, in tutti gli
 altri casi l'\ids{UID} reale o l'\ids{UID} effettivo del processo chiamante
 devono corrispondere all'\ids{UID} reale o all'\ids{UID} salvato della
-destinazione. Fa eccezione il caso in cui il segnale inviato sia
+destinazione.\footnote{questo a partire dal kernel 1.3.78, seguendo lo
+  standard POSIX.1; in precedenza il comportamento era diverso, gli
+  interessati alla storia possono consultare la pagina di manuale della
+  funzione.} Fa eccezione il caso in cui il segnale inviato sia
 \signal{SIGCONT}, nel quale occorre anche che entrambi i processi appartengano
 alla stessa sessione.
 
@@ -1287,14 +1294,6 @@ standard POSIX, prima della terminazione tutti i file aperti e gli stream
 saranno chiusi ed i buffer scaricati su disco. Non verranno invece eseguite le
 eventuali funzioni registrate con \func{atexit} e \func{on\_exit}.
 
-% TODO trattare pidfd_send_signal, aggiunta con il kernel 5.1 (vedi
-% https://lwn.net/Articles/783052/) per mandare segnali a processi senza dover
-% usare un PID, vedi anche https://lwn.net/Articles/773459/,
-% https://git.kernel.org/linus/3eb39f47934f 
-
-% TODO c'è pure pidfd_open() (vedi https://lwn.net/Articles/789023/) per
-% ottere un pid fd pollabile aggiunta con il kernel 5.3
-
 \subsection{Le funzioni di allarme ed i \textit{timer}}
 \label{sec:sig_alarm_abort}
 
@@ -1503,7 +1502,7 @@ una operazione un numero sufficiente di volte per far passare il tempo
 richiesto.
 
 Ma in un sistema multitasking un ciclo di attesa è solo un inutile spreco di
-tempo di processore, dato che altri programmi possono essere eseguiti nel
+tempo di processore dato che altri programmi possono essere eseguiti nel
 frattempo, per questo ci sono delle apposite funzioni che permettono di
 mantenere un processo in attesa per il tempo voluto, senza impegnare il
 processore. In pratica si tratta di funzioni che permettono di portare
@@ -1838,12 +1837,12 @@ che si fa in questo caso è impostare all'interno del 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}.
 
-La logica del programma è quella di far impostare al gestore (\texttt{\small
-  14--19}) una variabile globale, preventivamente inizializzata nel programma
-principale, ad un diverso valore. In questo modo dal corpo principale del
-programma si potrà determinare, osservandone il contenuto di detta variabile,
-l'occorrenza o meno del segnale, ed eseguire le azioni conseguenti
-(\texttt{\small 6--11}) relative.
+La logica del programma è quella di impostare nel gestore una variabile
+globale preventivamente inizializzata nel programma principale ad un valore
+diverso (\texttt{\small 14--19}). In questo modo dal corpo principale del
+programma si potrà determinare, osservando il contenuto di detta variabile,
+l'occorrenza o meno del segnale, ed eseguire le conseguenti azioni relative
+(\texttt{\small 6--11}).
 
 \begin{figure}[!htbp]
   \footnotesize\centering
@@ -1866,11 +1865,11 @@ la sua occorrenza sarà perduta.
 
 Questi esempi ci mostrano come per poter eseguire una gestione effettiva dei
 segnali occorrono delle funzioni più sofisticate di quelle finora
-illustrate. La funzione \func{signal} infatti ha la sua origine nella
-interfaccia alquanto primitiva che venne adottata nei primi sistemi Unix, ma
-con questa funzione è sostanzialmente impossibile gestire in maniera adeguata
-di tutti i possibili aspetti con cui un processo deve reagire alla ricezione
-di un segnale.
+illustrate. La funzione \func{signal} infatti ha la sua origine
+nell'interfaccia alquanto primitiva che venne adottata nei primi sistemi Unix,
+ma con questa funzione è sostanzialmente impossibile gestire in maniera
+adeguata di tutti i possibili aspetti con cui un processo deve reagire alla
+ricezione di un segnale.
 
 
 
@@ -2046,16 +2045,9 @@ da esso specificata, se \param{oldact} non è nullo il valore dell'azione
 corrente viene restituito indietro.  Questo permette (specificando \param{act}
 nullo e \param{oldact} non nullo) di superare uno dei limiti di \func{signal},
 che non consente di ottenere l'azione corrente senza installarne una nuova. Se
-sia \param{act} che \param{oldact} la funzione può essere utilizzata per
-verificare, se da luogo ad un errore, se il segnale indicato è valido per la
-piattaforma che si sta usando.
-
-Entrambi i puntatori fanno riferimento alla struttura \struct{sigaction},
-tramite la quale si specificano tutte le caratteristiche dell'azione associata
-ad un segnale.  Anch'essa è descritta dallo standard POSIX.1 ed in Linux è
-definita secondo quanto riportato in fig.~\ref{fig:sig_sigaction}. Il campo
-\var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere
-più usato.
+sia \param{act} che \param{oldact} sono nulli la funzione può essere
+utilizzata per verificare che il segnale indicato sia valido per la
+piattaforma che si sta usando (se non lo è darà errore).
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2067,13 +2059,19 @@ più usato.
   \label{fig:sig_sigaction}
 \end{figure}
 
+Entrambi i puntatori fanno riferimento alla struttura \struct{sigaction},
+tramite la quale si specificano tutte le caratteristiche dell'azione associata
+ad un segnale.  Anch'essa è descritta dallo standard POSIX.1 ed in Linux è
+definita secondo quanto riportato in fig.~\ref{fig:sig_sigaction}. Il campo
+\var{sa\_restorer}, non previsto dallo standard, è obsoleto e non deve essere
+più usato.
+
 Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
 essere bloccati durante l'esecuzione del gestore, 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. Quando il
-gestore ritorna comunque la maschera dei segnali bloccati (vedi
-sez.~\ref{sec:sig_sigmask}) viene ripristinata al valore precedente
-l'invocazione.
+sia specificato con \var{sa\_flag} un comportamento diverso. Quando il gestore
+ritorna la maschera dei segnali bloccati (vedi sez.~\ref{sec:sig_sigmask})
+viene comunque ripristinata al valore precedente l'invocazione.
 
 L'uso di questo campo permette ad esempio di risolvere il problema residuo
 dell'implementazione di \code{sleep} mostrata in
@@ -2128,6 +2126,11 @@ tab.~\ref{tab:sig_sa_flag}.
                             call} quando vengono interrotte dal suddetto
                             segnale, riproduce cioè il comportamento standard
                             di BSD.\\ 
+    \constd{SA\_RESTORER} & Ad uso delle implementazioni delle liberie del C,
+                            non deve essere usato nelle applicazioni, serve ad
+                            indicare che il campo \var{sa\_restorer} contiene
+                            l'indirizzo di un cosiddetto \textit{signal
+                            trampoline}.\footnotemark \\ 
     \constd{SA\_SIGINFO}  & Deve essere specificato quando si vuole usare un
                             gestore in forma estesa usando
                             \var{sa\_sigaction} al posto di
@@ -2138,6 +2141,13 @@ tab.~\ref{tab:sig_sa_flag}.
   \label{tab:sig_sa_flag}
 \end{table}
 
+\footnotetext{il \itindex{signal~trampoline} \textit{signal trampoline} è il
+  codice usato per tornare da un gestore di segnali, che originariamente
+  veniva inserito nello \textit{stack}, ma i kernel recenti come misura di
+  sicurezza impediscono l'esecuzione di codice dallo stack, per cui questo
+  codice viene spostato altrove (ad esempio nella libreria del C) ed il suo
+  indirizzo viene indicato al kernel nel campo \var{sa\_restorer}.}
+
 Come si può notare in fig.~\ref{fig:sig_sigaction} \func{sigaction} permette
 di utilizzare due forme diverse di gestore,\footnote{la possibilità è prevista
   dallo standard POSIX.1b, ed è stata aggiunta nei kernel della serie 2.1.x
@@ -2183,15 +2193,6 @@ viene sempre espresso come una costante,\footnote{le definizioni di tutti i
   valori possibili si trovano in \file{bits/siginfo.h}.} ed i valori possibili
 in questo caso sono riportati in tab.~\ref{tab:sig_si_code_generic}.
 
-Nel caso di alcuni segnali però il valore di \var{si\_code} viene usato per
-fornire una informazione specifica relativa alle motivazioni della ricezione
-dello stesso; ad esempio i vari segnali di errore (\signal{SIGILL},
-\signal{SIGFPE}, \signal{SIGSEGV} e \signal{SIGBUS}) 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 (\signal{SIGCHLD}, \signal{SIGTRAP} e \signal{SIGPOLL}) forniscono
-altre informazioni specifiche.
-
 \begin{table}[!htb]
   \footnotesize
   \centering
@@ -2224,6 +2225,15 @@ altre informazioni specifiche.
   \label{tab:sig_si_code_generic}
 \end{table}
 
+Nel caso di alcuni segnali però il valore di \var{si\_code} viene usato per
+fornire una informazione specifica relativa alle motivazioni della ricezione
+dello stesso; ad esempio i vari segnali di errore (\signal{SIGILL},
+\signal{SIGFPE}, \signal{SIGSEGV} e \signal{SIGBUS}) 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 (\signal{SIGCHLD}, \signal{SIGTRAP} e \signal{SIGPOLL}) forniscono
+altre informazioni specifiche.
+
 
 In questo caso il valore del campo \var{si\_code} deve essere verificato nei
 confronti delle diverse costanti previste per ciascuno di detti segnali; dato
@@ -3649,7 +3659,6 @@ specificato \const{TIMER\_ABSTIME} per \param{flags}.
 \itindend{POSIX~Timer~API}
 
 
-
 \subsection{Ulteriori funzioni di gestione}
 \label{sec:sig_specific_features}
 
@@ -3657,9 +3666,6 @@ In questo ultimo paragrafo esamineremo le rimanenti funzioni di gestione dei
 segnali non descritte finora, relative agli aspetti meno utilizzati e più
 ``\textsl{esoterici}'' della interfaccia.
 
-% TODO: trattare (qui?) pidfd_send_signal() introdotta con il kernel 5.1 vedi
-% https://lwn.net/Articles/784831/ e https://lwn.net/Articles/773459/
-
 La prima di queste funzioni è la funzione di sistema \funcd{sigpending},
 anch'essa introdotta dallo standard POSIX.1, il suo prototipo è:
 
@@ -3836,6 +3842,27 @@ tipo \type{sigjmp\_buf}, è assolutamente identica a \func{longjmp}.
 % argomento a priorità IDLE (fare quando non resta niente altro da trattare)
 
 
+\subsection{I \textit{pidfd} e l'invio di segnali \textit{race-free}}
+\label{sec:sig_pid_fd}
+
+
+% TODO: trattare (qui? oppure sopra in "Ulteriori funzioni di gestione?)
+% pidfd_send_signal() introdotta con il kernel 5.1 vedi
+% https://lwn.net/Articles/784831/, https://lwn.net/Articles/773459/ e
+% https://lwn.net/Articles/801319/
+
+% TODO: Nuova subsection sui pidfd, e le funzioni correlate, in particolare:
+% trattare pidfd_send_signal, aggiunta con il kernel 5.1 (vedi
+% https://lwn.net/Articles/783052/) per mandare segnali a processi senza dover
+% usare un PID, vedi anche https://lwn.net/Articles/773459/,
+% https://git.kernel.org/linus/3eb39f47934f trattare pure pidfd_open() (vedi
+% https://lwn.net/Articles/789023/) per ottere un pid fd pollabile aggiunta
+% con il kernel 5.3 ed il nuovo flag PIDFD_NONBLOCK aggionto con il 5.10 (vedi
+% https://git.kernel.org/linus/4da9af0014b5), man pidfd_send_signal su le
+% versioni più recenti della man pages trattare pidfd_getfd aggiunta con il
+% kernel 5.6
+
+
 % LocalWords:  kernel POSIX timer shell control ctrl kill raise signal handler
 % LocalWords:  reliable unreliable fig race condition sez struct process table
 % LocalWords:  delivered pending scheduler sigpending l'I suspend SIGKILL wait