X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=signal.tex;h=c408ef30cbfb11306d8cd3b9a73191afaaacb57a;hp=d05c4cac2102ec4eb3e2f99fbc54919957996449;hb=54a3f08494d976cbc6c0fd49926f9cf707ab2a6a;hpb=fae1b357c38b50ce788f3f06f7153b1ce4ee57df diff --git a/signal.tex b/signal.tex index d05c4ca..c408ef3 100644 --- a/signal.tex +++ b/signal.tex @@ -1,6 +1,6 @@ %% signal.tex %% -%% Copyright (C) 2000-2017 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2019 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -245,7 +245,6 @@ segnale. Per alcuni segnali (per la precisione \signal{SIGKILL} e \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; @@ -322,9 +321,9 @@ Linux anche a seconda della architettura hardware e della versione del kernel. Quelli che invece sono stati, almeno a grandi linee, standardizzati, sono i nomi dei segnali e le costanti di preprocessore che li identificano, che sono -tutte nella forma \texttt{SIGnome}, e sono queste che devono essere usate nei -programmi. Come tutti gli altri nomi e le funzioni che concernono i segnali, -esse sono definite nell'header di sistema \headfile{signal.h}. +tutte nella forma \texttt{SIG\textsl{nome}}, e sono queste che devono essere +usate nei programmi. Come tutti gli altri nomi e le funzioni che concernono i +segnali, esse sono definite nell'header di sistema \headfile{signal.h}. \begin{table}[!htb] \footnotesize @@ -393,8 +392,7 @@ quelli \textit{real-time} in sez.~\ref{sec:sig_real_time}). Ma si tenga 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 è @@ -407,7 +405,14 @@ presente che il significato dei segnali è abbastanza indipendente dalle 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|} @@ -428,13 +433,13 @@ POSIX.1-2001. \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 @@ -456,15 +461,6 @@ tab.~\ref{tab:sig_action_leg}). \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 @@ -700,7 +696,7 @@ in cui si trattano gli argomenti relativi. Questi segnali sono: La maggior pare dei programmi non hanno necessità di intercettare il segnale, in quanto esso è completamente trasparente rispetto all'esecuzione che riparte senza che il programma noti niente. Si possono installare dei - gestori per far si che un programma produca una qualche azione speciale + gestori per far sì che un programma produca una qualche azione speciale se viene fermato e riavviato, come per esempio riscrivere un prompt, o inviare un avviso. @@ -944,27 +940,28 @@ situazione è il seguente: essere riavvolto); \item le operazioni eseguite con \func{ioctl} che non è detto possano essere eseguite immediatamente; -\item le funzioni di intercomunicazione fra processi (vedi cap.~\ref{cha:IPC}) - che si bloccano in attesa di risposte da altri processi; -\item la funzione \func{pause} (vedi sez.~\ref{sec:sig_pause_sleep}) e le - analoghe \func{sigsuspend}, \func{sigtimedwait}, e \func{sigwaitinfo} (vedi - sez.~\ref{sec:sig_real_time}), usate appunto per attendere l'arrivo di un - segnale; -\item le funzioni associate al \textit{file locking} (vedi +\item l'uso di funzioni di intercomunicazione fra processi (vedi + cap.~\ref{cha:IPC}) che si bloccano in attesa di risposte da altri processi; +\item l'uso della funzione \func{pause} (vedi sez.~\ref{sec:sig_pause_sleep}) + e le analoghe \func{sigsuspend}, \func{sigtimedwait}, e \func{sigwaitinfo} + (vedi sez.~\ref{sec:sig_real_time}), usate appunto per attendere l'arrivo di + un segnale; +\item l'uso delle funzioni associate al \textit{file locking} (vedi sez.~\ref{sec:file_locking}) -\item la funzione \func{wait} e le analoghe funzioni di attesa se nessun - processo figlio è ancora terminato. +\item l'uso della funzione \func{wait} e le analoghe funzioni di attesa se + nessun processo figlio è ancora terminato. \end{itemize*} In questo caso si pone il problema di cosa fare una volta che il gestore sia 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 le \acr{glibc} provvedono una macro +un errore comune, tanto che la \acr{glibc} provvede una macro \code{TEMP\_FAILURE\_RETRY(expr)} che esegue l'operazione automaticamente, ripetendo l'esecuzione dell'espressione \var{expr} fintanto che il risultato non è diverso dall'uscita con un errore \errcode{EINTR}. @@ -976,7 +973,7 @@ bisogno di preoccuparsi di controllare il codice di errore; si perde però la possibilità di eseguire azioni specifiche all'occorrenza di questa particolare condizione. -Linux e le \acr{glibc} consentono di utilizzare entrambi gli approcci, +Linux e la \acr{glibc} consentono di utilizzare entrambi gli approcci, attraverso una opportuna opzione di \func{sigaction} (vedi sez.~\ref{sec:sig_sigaction}). È da chiarire comunque che nel caso di interruzione nel mezzo di un trasferimento parziale di dati, le \textit{system @@ -987,18 +984,18 @@ interrotte con un errore di \errcode{EINTR} indipendentemente dal fatto che ne possa essere stato richiesto il riavvio automatico, queste funzioni sono: \begin{itemize*} -\item le funzioni di attesa di un segnale, come \func{pause} (vedi - sez.~\ref{sec:sig_pause_sleep}), \func{sigsuspend}, \func{sigtimedwait}, e +\item le funzioni di attesa di un segnale: \func{pause} (vedi + sez.~\ref{sec:sig_pause_sleep}) o \func{sigsuspend}, \func{sigtimedwait}, e \func{sigwaitinfo} (vedi sez.~\ref{sec:sig_real_time}). -\item le funzioni di attesa dell'\textit{I/O multiplexing}, come - \func{select}, \func{pselect}, \func{poll}, \func{ppoll}, \func{epoll\_wait} - e \func{epoll\_pwait} (vedi sez.~\ref{sec:file_multiplexing}). +\item le funzioni di attesa dell'\textit{I/O multiplexing} (vedi + sez.~\ref{sec:file_multiplexing}) come \func{select}, \func{pselect}, + \func{poll}, \func{ppoll}, \func{epoll\_wait} e \func{epoll\_pwait}. \item le funzioni del System V IPC che prevedono attese: \func{msgrcv}, \func{msgsnd} (vedi sez.~\ref{sec:ipc_sysv_mq}), \func{semop} e \func{semtimedop} (vedi sez.~\ref{sec:ipc_sysv_sem}). -\item le funzioni di attesa di un processo: \func{usleep}, \func{nanosleep} - (vedi sez.~\ref{sec:sig_pause_sleep}) e \func{clock\_nanosleep} (vedi - sez.~\ref{sec:sig_timer_adv}). +\item le funzioni per la messa in attesa di un processo come \func{usleep}, + \func{nanosleep} (vedi sez.~\ref{sec:sig_pause_sleep}) e + \func{clock\_nanosleep} (vedi sez.~\ref{sec:sig_timer_adv}). \item le funzioni che operano sui socket quando è stato impostato un \textit{timeout} sugli stessi con \func{setsockopt} (vedi sez.~\ref{sec:sock_generic_options}) ed in particolare \func{accept}, @@ -1043,7 +1040,7 @@ comportamento, pur mantenendone immutato il prototipo\footnote{in realtà in In questa definizione per l'argomento \param{handler} che indica il gestore da installare si è usato un tipo di dato, \type{sighandler\_t}, che è una -estensione GNU, definita dalle \acr{glibc}, che permette di riscrivere il +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} @@ -1053,7 +1050,7 @@ 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}. @@ -1069,10 +1066,12 @@ 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. 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 @@ -1092,7 +1091,7 @@ librerie del C come la \acr{libc4} e la \acr{libc5}.\footnote{nelle ridefinita per seguire la semantica affidabile usata da BSD.} Al contrario BSD segue la semantica affidabile, non disinstallando il gestore -e bloccando il segnale durante l'esecuzione dello stesso. Con l'utilizzo delle +e bloccando il segnale durante l'esecuzione dello stesso. Con l'utilizzo della \acr{glibc} dalla versione 2 anche Linux è passato a questo comportamento. Il comportamento della versione originale della funzione, il cui uso è deprecato per i motivi visti in sez.~\ref{sec:sig_semantics}, può essere ottenuto @@ -1102,11 +1101,11 @@ chiamando \funcm{sysv\_signal}, una volta che si sia definita la macro processo multi-\textit{thread}, è da evitare: tutti i nuovi programmi devono 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. +È da 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} @@ -1147,9 +1146,10 @@ gestore dovrà prima reinstallare l'azione predefinita, per poi attivarla 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{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 è: \begin{funcproto}{ \fhead{sys/types.h} @@ -1287,8 +1287,13 @@ 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} @@ -1333,11 +1338,11 @@ processo tre diversi timer: corrisponde al \textit{clock time}). La scadenza di questo timer provoca l'emissione di \signal{SIGALRM}; \item un \textit{virtual timer} che calcola il tempo di processore usato dal - processo in user space (che corrisponde all'\textit{user time}). La scadenza - di questo timer provoca l'emissione di \signal{SIGVTALRM}; + processo in \textit{user space} (che corrisponde all'\textit{user time}). La + scadenza di questo timer provoca l'emissione di \signal{SIGVTALRM}; \item un \textit{profiling timer} che calcola la somma dei tempi di processore - utilizzati direttamente dal processo in user space, e dal kernel nelle - \textit{system call} ad esso relative (che corrisponde a quello che in + utilizzati direttamente dal processo in \textit{user space}, e dal kernel + nelle \textit{system call} ad esso relative (che corrisponde a quello che in sez.~\ref{sec:sys_unix_time} abbiamo chiamato \textit{processor time}). La scadenza di questo timer provoca l'emissione di \signal{SIGPROF}. \end{itemize*} @@ -1419,7 +1424,7 @@ questo modo il ciclo verrà ripetuto; se invece il valore di \var{it\_interval} L'uso di \func{setitimer} consente dunque un controllo completo di tutte le caratteristiche dei timer, ed in effetti la stessa \func{alarm}, benché definita direttamente nello standard POSIX.1, può a sua volta essere espressa -in termini di \func{setitimer}, come evidenziato dal manuale delle \acr{glibc} +in termini di \func{setitimer}, come evidenziato dal manuale della \acr{glibc} \cite{GlibcMan} che ne riporta la definizione mostrata in fig.~\ref{fig:sig_alarm_def}.\footnote{questo comporta anche che non è il caso di mescolare chiamate ad \func{abort} e a \func{setitimer}.} @@ -1565,15 +1570,15 @@ realizzata con l'uso di \func{pause} e \func{alarm}, in una maniera analoga a quella dell'esempio che vedremo in sez.~\ref{sec:sig_example}. In tal caso mescolare chiamate di \func{alarm} e \func{sleep} o modificare l'azione associata \signal{SIGALRM}, può portare a dei risultati indefiniti. Nel caso -delle \acr{glibc} è stata usata una implementazione completamente indipendente +della \acr{glibc} è stata usata una implementazione completamente indipendente e questi problemi non ci sono, ma un programma portabile non può fare questa assunzione. La granularità di \func{sleep} permette di specificare attese soltanto in secondi, per questo sia sotto BSD4.3 che in SUSv2 è stata definita un'altra funzione con una precisione teorica del microsecondo. I due standard hanno -delle definizioni diverse, ma le \acr{glibc} seguono (secondo la pagina di -manuale almeno dalla versione 2.2.2) seguono quella di SUSv2 per cui la +delle definizioni diverse, ma la \acr{glibc} segue (secondo la pagina di +manuale almeno dalla versione 2.2.2) quella di SUSv2 per cui la funzione \funcd{usleep} (dove la \texttt{u} è intesa come sostituzione di $\mu$), ha il seguente prototipo: @@ -2001,10 +2006,10 @@ relativi all'uso di \func{signal}. Per ovviare a tutto questo lo standard POSIX.1 ha ridefinito completamente l'interfaccia per la gestione dei segnali, rendendola molto più flessibile e robusta, anche se leggermente più complessa. -La funzione di sistema principale prevista dall'interfaccia POSIX.1 per i -segnali è \funcd{sigaction}. Essa ha sostanzialmente lo stesso uso di -\func{signal}, permette cioè di specificare le modalità con cui un segnale può -essere gestito da un processo. Il suo prototipo è: +La principale funzione di sistema prevista dall'interfaccia POSIX.1 per la +gestione dei segnali è \funcd{sigaction}. Essa ha sostanzialmente lo stesso +uso di \func{signal}, permette cioè di specificare le modalità con cui un +segnale può essere gestito da un processo. Il suo prototipo è: \begin{funcproto}{ \fhead{signal.h} @@ -2707,8 +2712,8 @@ massimo associato ad un segnale \textit{real-time}. Su Linux di solito il primo valore è 33, mentre il secondo è \code{\_NSIG-1}, che di norma (vale a dire sulla piattaforma i386) è 64. Questo dà un totale di 32 segnali disponibili, contro gli almeno 8 richiesti da POSIX.1b. Si tenga -presente però che i primi segnali \textit{real-time} disponibili vendono usati -dalle \acr{glibc} per l'implementazione dei \textit{thread} POSIX (vedi +presente però che i primi segnali \textit{real-time} disponibili vengono usati +dalla \acr{glibc} per l'implementazione dei \textit{thread} POSIX (vedi sez.~\ref{sec:thread_posix_intro}), ed il valore di \const{SIGRTMIN} viene modificato di conseguenza.\footnote{per la precisione vengono usati i primi tre per la vecchia implementazione dei \textit{LinuxThread} ed i primi due @@ -2820,7 +2825,7 @@ nell'argomento \param{value}. Se invece si è installato un gestore nella forma classica il segnale sarà generato, ma tutte le caratteristiche tipiche dei segnali \textit{real-time} (priorità e coda) saranno perse. -Secondo lo standard POSIX la profondità della coda è indicata dalla costante +Per lo standard POSIX la profondità della coda è indicata dalla costante \constd{SIGQUEUE\_MAX}, una della tante costanti di sistema definite dallo standard POSIX che non abbiamo riportato esplicitamente in sez.~\ref{sec:sys_limits}. Il suo valore minimo secondo lo standard, @@ -3043,11 +3048,21 @@ tab.~\ref{tab:sig_timer_clockid_types}. \end{table} +% TODO: dal 4.17 CLOCK_MONOTONIC e CLOCK_BOOTTIME sono identici vedi +% https://lwn.net/Articles/751651/ e +% https://git.kernel.org/linus/d6ed449afdb38f89a7b38ec50e367559e1b8f71f +% change reverted, vedi: https://lwn.net/Articles/752757/ + % NOTE: dal 3.0 anche i cosiddetti Posix Alarm Timers, con % CLOCK_REALTIME_ALARM vedi http://lwn.net/Articles/429925/ % TODO: dal 3.10 anche CLOCK_TAI -Per poter utilizzare queste funzionalità le \acr{glibc} richiedono che la +% TODO seguire l'evoluzione delle nuove syscall per il problema del 2038, +% iniziate ad entrare nel kernel dal 5.1, vedi +% https://lwn.net/Articles/776435/, https://lwn.net/Articles/782511/, +% https://git.kernel.org/linus/b1b988a6a035 + +Per poter utilizzare queste funzionalità la \acr{glibc} richiede che la macro \macro{\_POSIX\_C\_SOURCE} sia definita ad un valore maggiore o uguale di \texttt{199309L} (vedi sez.~\ref{sec:intro_gcc_glibc_std}), inoltre i programmi che le usano devono essere collegati con la libreria delle @@ -3642,6 +3657,9 @@ 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 è: @@ -3777,7 +3795,7 @@ ripristinata la maschera dei segnali precedente l'invocazione, come per un normale ritorno, mentre quella usata da System V no. Lo standard POSIX.1 non specifica questo comportamento per \func{setjmp} e -\func{longjmp}, ed il comportamento delle \acr{glibc} dipende da quale delle +\func{longjmp}, ed il comportamento della \acr{glibc} dipende da quale delle caratteristiche si sono abilitate con le macro viste in sez.~\ref{sec:intro_gcc_glibc_std}.