\signal{SIGSTOP}) questa azione è predeterminata dal kernel e non può essere
mai modificata, ma per tutti gli altri si può selezionare una delle tre
possibilità seguenti:
-
\begin{itemize*}
\item ignorare il segnale;
\item intercettare il segnale, ed utilizzare il gestore specificato;
presente che solo quelli elencati nella prima sezione della tabella sono
presenti su tutte le architetture. Nelle sezioni successive si sono riportati
rispettivamente quelli che esistono solo sull'architettura PC e quelli che non
-esistono sull'architettura PC, ma sono definiti sulle architetture
-\textit{alpha} o \textit{mips}.
+esistono sull'architettura PC, ma sono definiti su altre.
Alcuni segnali erano previsti fin dallo standard ANSI C, ed i segnali sono
presenti in tutti i sistemi unix-like, ma l'elenco di quelli disponibili non è
implementazioni solo per quelli definiti negli standard POSIX.1-1990 e
POSIX.1-2001.
-\begin{table}[htb]
+Come accennato in sez.~\ref{sec:sig_notification} a ciascun segnale è
+associata una specifica azione predefinita che viene eseguita quando nessun
+gestore è installato. Le azioni predefinite possibili, che abbiamo già
+descritto in sez.~\ref{sec:sig_notification}, sono state riportate in
+tab.~\ref{tab:sig_signal_list} nella terza colonna, e di nuovo sono state
+indicate con delle lettere la cui legenda completa è illustrata in
+tab.~\ref{tab:sig_action_leg}).
+\begin{table}[!htb]
\footnotesize
\centering
\begin{tabular}[c]{|c|l|}
\label{tab:sig_standard_leg}
\end{table}
-Come accennato in sez.~\ref{sec:sig_notification} a ciascun segnale è
-associata una specifica azione predefinita che viene eseguita quando nessun
-gestore è installato. Le azioni predefinite possibili, che abbiamo già
-descritto in sez.~\ref{sec:sig_notification}, sono state riportate in
-tab.~\ref{tab:sig_signal_list} nella terza colonna, e di nuovo sono state
-indicate con delle lettere la cui legenda completa è illustrata in
-tab.~\ref{tab:sig_action_leg}).
+Si inoltre noti come \signal{SIGCONT} sia l'unico segnale a non avere
+l'indicazione di una azione predefinita nella terza colonna di
+tab.~\ref{tab:sig_signal_list}, questo perché il suo effetto è sempre quello
+di far ripartire un programma in stato \texttt{T} fermato da un segnale di
+stop. Inoltre i segnali \signal{SIGSTOP} e \signal{SIGKILL} si distinguono da
+tutti gli altri per la specifica caratteristica di non potere essere né
+intercettati, né bloccati, né ignorati.
\begin{table}[htb]
\footnotesize
\label{tab:sig_action_leg}
\end{table}
-
-Si inoltre noti come \signal{SIGCONT} sia l'unico segnale a non avere
-l'indicazione di una azione predefinita nella terza colonna di
-tab.~\ref{tab:sig_signal_list}, questo perché il suo effetto è sempre quello
-di far ripartire un programma in stato \texttt{T} fermato da un segnale di
-stop. Inoltre i segnali \signal{SIGSTOP} e \signal{SIGKILL} si distinguono da
-tutti gli altri per la specifica caratteristica di non potere essere né
-intercettati, né bloccati, né ignorati.
-
Il numero totale di segnali presenti è dato dalla macro \macrod{NSIG} (e tiene
conto anche di quelli \textit{real-time}) e dato che i numeri dei segnali sono
allocati progressivamente, essa corrisponde anche al successivo del valore
ritornato. La scelta originaria dei primi Unix era quella di far ritornare
anche la \textit{system call} restituendo l'errore di \errcode{EINTR}. Questa
è a tutt'oggi una scelta corrente, ma comporta che i programmi che usano dei
-gestori controllino lo stato di uscita delle funzioni che eseguono una system
-call lenta per ripeterne la chiamata qualora l'errore fosse questo.
+gestori controllino lo stato di uscita delle funzioni che eseguono una
+\textit{system call} lenta per ripeterne la chiamata qualora l'errore fosse
+questo.
Dimenticarsi di richiamare una \textit{system call} interrotta da un segnale è
un errore comune, tanto che la \acr{glibc} provvede una macro
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 è:
\includecodesnip{listati/sighandler_t.c}
e cioè un puntatore ad una funzione \ctyp{void} (cioè senza valore di ritorno)
-e che prende un argomento di tipo \ctyp{int}. Si noti come si devono usare le
+che prende un argomento di tipo \ctyp{int}. Si noti come 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
puntatore a \ctyp{void} e non un puntatore ad una funzione \ctyp{void}.
due valori costanti \const{SIG\_IGN} e \const{SIG\_DFL}. Il primo indica che
il segnale deve essere ignorato. Il secondo ripristina l'azione predefinita, e
serve a tornare al comportamento di default quando non si intende più gestire
-direttamente un segnale. Si ricordi però che i due segnali \signal{SIGKILL} e
-\signal{SIGSTOP} non possono essere né ignorati né intercettati e per loro
-l'uso di \func{signal} non ha alcun effetto, qualunque cosa si specifichi
-per \param{handler}.
+direttamente un segnale.
+
+Si ricordi però che i due segnali \signal{SIGKILL} e \signal{SIGSTOP} non
+possono essere né ignorati né intercettati e per loro l'uso di \func{signal}
+non ha alcun effetto, qualunque cosa si specifichi nell'argomento
+\param{handler}.
La funzione restituisce l'indirizzo dell'azione precedente, che può essere
salvato per poterlo ripristinare (con un'altra chiamata a \func{signal}) in un
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
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, 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 che ritorna da
-questi segnali può dare luogo ad un ciclo infinito.
+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
+che ritorna da questi segnali può dare luogo ad un ciclo infinito.
\subsection{Le funzioni per l'invio di segnali}
chiamando \func{raise}.
In realtà \func{raise} è una funzione di libreria, che per i processi ordinari
-viene implementata attraverso la funzione di sistema \funcd{kill} che è quella
-che consente effettivamente di inviare un segnale generico ad un processo, il
- suo prototipo è:
+veniva implementata (nelle versioni più recenti del kernel viene usata
+\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}
$>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}|$.\\
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.
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}
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
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
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.
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
\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
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
\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
- con l'introduzione dei segnali \textit{real-time} (vedi
+ con l'itroduzione dei segnali \textit{real-time} (vedi
sez.~\ref{sec:sig_real_time}); in precedenza era possibile ottenere alcune
informazioni addizionali usando \var{sa\_handler} con un secondo parametro
addizionale di tipo \var{sigcontext}, che adesso è deprecato.} da
-specificare, a seconda dell'uso o meno del flag \const{SA\_SIGINFO},
-rispettivamente attraverso i campi \var{sa\_sigaction} o \var{sa\_handler}.
-Quest'ultima è quella classica usata anche con \func{signal}, mentre la prima
-permette di usare un gestore più complesso, in grado di ricevere informazioni
-più dettagliate dal sistema, attraverso la struttura \struct{siginfo\_t},
-riportata in fig.~\ref{fig:sig_siginfo_t}. I due campi devono essere usati in
-maniera alternativa, in certe implementazioni questi campi vengono addirittura
+specificare rispettivamente attraverso i campi \var{sa\_sigaction} o
+\var{sa\_handler}, a seconda dell'uso o meno del flag \const{SA\_SIGINFO}. La
+forma con \var{sa\_handler} è quella classica usata anche con \func{signal},
+mentre quella con \var{sa\_sigaction} permette di usare un gestore più
+complesso, in grado di ricevere informazioni più dettagliate dal sistema
+attraverso la struttura \struct{siginfo\_t}, riportata in
+fig.~\ref{fig:sig_siginfo_t}. I due campi devono essere usati in maniera
+alternativa, in certe implementazioni questi campi vengono addirittura
definiti come una \direct{union}.\footnote{la direttiva \direct{union} del
linguaggio C definisce una variabile complessa, analoga a una stuttura, i
cui campi indicano i diversi tipi di valori che possono essere salvati, in
maniera alternativa, all'interno della stessa.}
-Installando un gestore di tipo \var{sa\_sigaction} diventa allora possibile
+Installando un gestore di tipo \var{sa\_sigaction} diventa possibile
accedere alle informazioni restituite attraverso il puntatore a questa
struttura. Tutti i segnali impostano i campi \var{si\_signo}, che riporta il
numero del segnale ricevuto, \var{si\_errno}, che riporta, quando diverso da
In generale \var{si\_code} contiene, per i segnali generici, per quelli
\textit{real-time} e per tutti quelli inviati tramite da un processo con
\func{kill} o affini, le informazioni circa l'origine del segnale stesso, ad
-esempio se generato dal kernel, da un timer, da \func{kill}, ecc. Il valore
-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.
+esempio se generato dal kernel, da un timer, da \func{kill}, ecc. Il valore di
+\var{si\_code} 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}.
\begin{table}[!htb]
\footnotesize
\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
\begin{table}[!htb]
\footnotesize
\centering
- \begin{tabular}[c]{|l|p{8cm}|}
+ \begin{tabular}[c]{|l|p{10cm}|}
\hline
\textbf{Valore} & \textbf{Significato} \\
\hline
\hline
\constd{SEGV\_MAPERR} & Indirizzo non mappato.\\
\constd{SEGV\_ACCERR} & Permessi non validi per l'indirizzo.\\
+ \constd{SEGV\_BNDERR} & Controllo sui limiti di accesso (via MPX) fallito
+ (dal 3.19).\\
+ \constd{SEGV\_PKUERR} & Accesso negato da una protezione della memoria,
+ vedi sez.~\ref{sec:procadv_security_misc} (dal
+ 4.6).\\
\hline
\constd{BUS\_ADRALN} & Allineamento dell'indirizzo non valido.\\
\constd{BUS\_ADRERR} & Indirizzo fisico inesistente.\\
- \constd{BUS\_OBJERR} & Errore hardware sull'indirizzo.\\
+ \constd{BUS\_OBJERR} & Errore hardware specifico sull'indirizzo.\\
+ \constd{BUS\_MCEERR\_AR}& Rilevata corruzione sulla memoria utilizzata
+ direttamente dal processo è richiesta un'azione.\\
+ \constd{BUS\_MCEERR\_AO}& Rilevata corruzione sulla memoria su memoria non
+ utilizzata direttamente dal processo, l'azione
+ è opzionale.\\
+ % https://lore.kernel.org/patchwork/patch/158250/
\hline
\constd{TRAP\_BRKPT} & Breakpoint sul processo.\\
\constd{TRAP\_TRACE} & Trappola di tracciamento del processo.\\
+ \constd{TRAP\_BRANCH} & Il processo ha preso una branch trap.\\
+ % https://stackoverflow.com/questions/45895234/what-is-process-branch-trap
+ \constd{TRAP\_HWBKPT} & Breakpoint/watchpoint hardware.\\
\hline
\constd{CLD\_EXITED} & Il figlio è uscito.\\
\constd{CLD\_KILLED} & Il figlio è stato terminato.\\
\constd{CLD\_DUMPED} & Il figlio è terminato in modo anormale.\\
\constd{CLD\_TRAPPED} & Un figlio tracciato ha raggiunto una trappola.\\
\constd{CLD\_STOPPED} & Il figlio è stato fermato.\\
- \constd{CLD\_CONTINUED}& Il figlio è ripartito.\\
+ \constd{CLD\_CONTINUED}& Il figlio è ripartito (dal 2.6.9).\\
\hline
\constd{POLL\_IN} & Disponibili dati in ingresso.\\
\constd{POLL\_OUT} & Spazio disponibile sul buffer di uscita.\\
\constd{POLL\_PRI} & Disponibili dati di alta priorità in ingresso.\\
\constd{POLL\_HUP} & Il dispositivo è stato disconnesso.\\
\hline
+ \constd{SYS\_SECCOMP}& Innescato da una regola di \func{seccomp}, vedi
+ sez.~\ref{sec:procadv_seccomp} (dal 3.5).\\
+ \hline
\end{tabular}
\caption{Valori del campo \var{si\_code} della struttura \struct{sigaction}
impostati rispettivamente dai segnali \signal{SIGILL}, \signal{SIGFPE},
- \signal{SIGSEGV}, \signal{SIGBUS}, \signal{SIGCHLD}, \signal{SIGTRAP} e
- \signal{SIGPOLL}/\signal{SIGIO}.}
+ \signal{SIGSEGV}, \signal{SIGBUS}, \signal{SIGCHLD}, \signal{SIGTRAP},
+ \signal{SIGPOLL}/\signal{SIGIO} e \signal{SIGSYS}.}
\label{tab:sig_si_code_special}
\end{table}
del codice, appesantendo inutilmente il programma. Originariamente questo
comportamento veniva ottenuto con delle macro, ma queste hanno tutta una serie
di problemi di sintassi nel passaggio degli argomenti (si veda ad esempio
-\cite{PratC}) che in questo modo possono essere evitati.
+\cite{PratC}) che in questo modo possono essere evitati.
citato un controllo ed una assegnazione) o comunque eseguire una serie di
istruzioni, l'atomicità non è più possibile.
-In questo caso, se si vuole essere sicuri di non poter essere interrotti da un
-segnale durante l'esecuzione di una sezione di codice, lo si può bloccare
-esplicitamente modificando la maschera dei segnali del processo con la
-funzione di sistema \funcd{sigprocmask}, il cui prototipo è:
+In questo caso, se si vuole essere sicuri di non poter essere interrotti da
+uno o più segnali durante l'esecuzione di una sezione di codice, li si possono
+bloccare esplicitamente modificando la maschera dei segnali del processo
+usando la funzione di sistema \funcd{sigprocmask},\footnote{in realtà quello
+ che viene usato normalmente è il \textit{wrapper} omonimo delle \acr{glibc}
+ dato che con l'introduzione dei segnali \textit{real time} nel kernel 2.2 le
+ dimensioni del tipo \type{sigset\_t} sono cambiate e la \textit{system call}
+ sottostante è diventata \funcm{rt\_sigprocmask} che richiede un quarto
+ argomento di tipo \ctyp{size\_t} per indicare questa dimensione; il
+ \textit{wrapper} maschera questi dettagli ed inoltre ignora in maniera
+ silente i tentativi di bloccare i segnali \textit{real time} impiegati per
+ la gestione dei \textit{thread} dalla \textit{Native Thread Posix Library}
+ (vedi sez.~\ref{sec:linux_ntpl}).} il cui prototipo è:
\begin{funcproto}{
\fhead{signal.h}
dell'argomento \param{how}, secondo le modalità specificate in
tab.~\ref{tab:sig_procmask_how}. Qualora si specifichi un valore non nullo
per \param{oldset} la maschera dei segnali corrente viene salvata a
-quell'indirizzo.
+quell'indirizzo. Se è nullo \param{set} non viene eseguito nessun cambiamento
+e si può usare la funzione per leggere la maschera corrente in \param{oldset}.
\begin{table}[htb]
\footnotesize
\label{tab:sig_procmask_how}
\end{table}
-In questo modo diventa possibile proteggere delle sezioni di codice bloccando
-l'insieme di segnali voluto per poi riabilitarli alla fine della sezione
-critica. La funzione permette di risolvere problemi come quelli mostrati in
-fig.~\ref{fig:sig_event_wrong}, proteggendo la sezione fra il controllo del
-flag e la sua cancellazione. La funzione può essere usata anche all'interno
-di un gestore, ad esempio per riabilitare la consegna del segnale che l'ha
-invocato, in questo caso però occorre ricordare che qualunque modifica alla
-maschera dei segnali viene perduta al ritorno dallo stesso.
+La funzione consente di proteggere delle sezioni di codice bloccando l'insieme
+di segnali voluto per poi riabilitarli alla fine della sezione critica e
+risolvere problemi come quelli mostrati in fig.~\ref{fig:sig_event_wrong},
+proteggendo la sezione fra il controllo del flag e la sua cancellazione. La
+funzione può essere usata anche all'interno di un gestore, ad esempio per
+riabilitare la consegna del segnale che l'ha invocato, in questo caso però
+occorre ricordare che qualunque modifica alla maschera dei segnali viene
+perduta al ritorno dallo stesso.
Benché con l'uso di \func{sigprocmask} si possano risolvere la maggior parte
dei casi di \textit{race condition} restano aperte alcune possibilità legate
ottenere un'implementazione, riportata in fig.~\ref{fig:sig_sleep_ok} che non
presenta neanche questa necessità.
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{\codesamplewidth}
\includecodesample{listati/sleep.c}
\itindend{POSIX~Timer~API}
-
\subsection{Ulteriori funzioni di gestione}
\label{sec:sig_specific_features}
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 è:
% 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