From 4a4c9aa963c52279a1c3aa5c7c4b31aca927f3f5 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 25 Dec 2019 16:50:48 +0100 Subject: [PATCH] Piccole revisioni natalizie --- listati/sighandler_t.c | 2 +- signal.tex | 62 ++++++++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/listati/sighandler_t.c b/listati/sighandler_t.c index 9fe01bc..b678062 100644 --- a/listati/sighandler_t.c +++ b/listati/sighandler_t.c @@ -1 +1 @@ - typedef void (* sighandler_t)(int) +typedef void (* sighandler_t)(int) diff --git a/signal.tex b/signal.tex index c408ef3..936397d 100644 --- a/signal.tex +++ b/signal.tex @@ -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 @@ -3649,7 +3648,6 @@ specificato \const{TIMER\_ABSTIME} per \param{flags}. \itindend{POSIX~Timer~API} - \subsection{Ulteriori funzioni di gestione} \label{sec:sig_specific_features} @@ -3836,6 +3834,22 @@ 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: 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 +% man pidfd_send_signal su le versioni più recenti della man pages + + + + % 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 -- 2.30.2