X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=signal.tex;h=3b11014a81f591a6a8aa10241da17911ca8ba83a;hp=801e6ff1a8dc325156d238e85b4d3e4d772144d4;hb=17e39705eccbaa9111592907195befd05dbbed2d;hpb=6c8d59152cff88b5835eeb749445148bb3546a5b diff --git a/signal.tex b/signal.tex index 801e6ff..3b11014 100644 --- a/signal.tex +++ b/signal.tex @@ -1,3 +1,13 @@ +%% signal.tex +%% +%% Copyright (C) 2000-2002 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 "Prefazione", +%% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the +%% license is included in the section entitled "GNU Free Documentation +%% License". +%% \chapter{I segnali} \label{cha:signals} @@ -140,9 +150,9 @@ Si dice che il segnale viene \textsl{consegnato} al processo (dall'inglese \textit{delivered}) quando viene eseguita l'azione per esso prevista, mentre per tutto il tempo che passa fra la generazione del segnale e la sua consegna esso è detto \textsl{pendente} (o \textit{pending}). In genere questa -procedura viene effettuata dallo scheduler quando, riprendendo l'esecuzione -del processo in questione, verifica la presenza del segnale nella -\var{task\_struct} e mette in esecuzione il gestore. +procedura viene effettuata dallo scheduler\index{scheduler} quando, +riprendendo l'esecuzione del processo in questione, verifica la presenza del +segnale nella \var{task\_struct} e mette in esecuzione il gestore. In questa semantica un processo ha la possibilità di bloccare la consegna dei segnali, in questo caso, se l'azione per il suddetto segnale non è quella di @@ -211,11 +221,12 @@ verr ignorarlo). Normalmente l'invio al processo che deve ricevere il segnale è immediato ed -avviene non appena questo viene rimesso in esecuzione dallo scheduler che -esegue l'azione specificata. Questo a meno che il segnale in questione non sia -stato bloccato prima della notifica, nel qual caso l'invio non avviene ed il -segnale resta \textsl{pendente} indefinitamente. Quando lo si sblocca il -segnale \textsl{pendente} sarà subito notificato. +avviene non appena questo viene rimesso in esecuzione dallo +scheduler\index{scheduler} che esegue l'azione specificata. Questo a meno che +il segnale in questione non sia stato bloccato prima della notifica, nel qual +caso l'invio non avviene ed il segnale resta \textsl{pendente} +indefinitamente. Quando lo si sblocca il segnale \textsl{pendente} sarà subito +notificato. Si ricordi però che se l'azione specificata per un segnale è quella di essere ignorato questo sarà scartato immediatamente al momento della sua generazione, @@ -617,25 +628,26 @@ cui si trattano gli argomenti relativi. Questi segnali sono: gestori per far si che un programma produca una qualche azione speciale se viene fermato e riavviato, come per esempio riscrivere un prompt, o inviare un avviso. -\item[\macro{SIGSTOP}] Il segnale ferma un processo (lo porta in uno stato di - sleep); il segnale non può essere né intercettato, né ignorato, né bloccato. +\item[\macro{SIGSTOP}] Il segnale ferma un processo (lo porta cioè in uno + stato di sleep, vedi \secref{sec:proc_sched}); il segnale non può essere né + intercettato, né ignorato, né bloccato. \item[\macro{SIGTSTP}] Il nome sta per \textit{interactive stop}. Il segnale ferma il processo interattivamente, ed è generato dal carattere SUSP - (prodotto dalla combinazione \macro{C-z}), ed al contrario di + (prodotto dalla combinazione \cmd{C-z}), ed al contrario di \macro{SIGSTOP} può essere intercettato e ignorato. In genere un programma installa un gestore per questo segnale quando vuole lasciare il sistema o il terminale in uno stato definito prima di fermarsi; se per esempio un programma ha disabilitato l'eco sul terminale può installare un gestore per riabilitarlo prima di fermarsi. \item[\macro{SIGTTIN}] Un processo non può leggere dal terminale se esegue una - sessione di lavoro in background. Quando un processo in background tenta di - leggere da un terminale viene inviato questo segnale a tutti i processi - della sessione di lavoro. L'azione predefinita è di fermare il processo. - L'argomento è trattato in \secref{sec:sess_xxx}. + sessione di lavoro in \textit{background}. Quando un processo in background + tenta di leggere da un terminale viene inviato questo segnale a tutti i + processi della sessione di lavoro. L'azione predefinita è di fermare il + processo. L'argomento è trattato in \secref{sec:sess_job_control_overview}. \item[\macro{SIGTTOU}] Segnale analogo al precedente \macro{SIGTTIN}, ma generato quando si tenta di scrivere o modificare uno dei modi del terminale. L'azione predefinita è di fermare il processo, l'argomento è - trattato in \secref{sec:sess_xxx}. + trattato in \secref{sec:sess_job_control_overview}. \end{basedescript} @@ -949,8 +961,8 @@ la funzione \func{kill}; il cui prototipo \funcdecl{int kill(pid\_t pid, int sig)} Invia il segnale \param{sig} al processo specificato con \param{pid}. - \bodydesc{ La funzione restituisce 0 in caso di successo e -1 in caso di - errore nel qual caso \var{errno} può assumere i valori: + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\macro{EINVAL}] Il segnale specificato non esiste. \item[\macro{ESRCH}] Il processo selezionato non esiste. @@ -1008,7 +1020,7 @@ Una seconda funzione che pu errore, gli errori sono gli stessi di \func{kill}.} \end{prototype} e che permette di inviare un segnale a tutto un \textit{process group} (vedi -\secref{sec:sess_xxx}). +\secref{sec:sess_proc_group}). Solo l'amministratore può inviare un segnale ad un processo qualunque, in tutti gli altri casi l'userid reale o l'userid effettivo del processo @@ -1094,7 +1106,7 @@ suo prototipo \param{value} sul timer specificato da \func{which}. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} può assumere i valori \macro{EINVAL} e + errore, nel qual caso \var{errno} assumerà uno dei valori \macro{EINVAL} o \macro{EFAULT}.} \end{prototype} @@ -1255,8 +1267,8 @@ quello di usare la funzione \func{pause}, il cui prototipo Pone il processo in stato di sleep fino al ritorno di un gestore. \bodydesc{La funzione ritorna solo dopo che un segnale è stato ricevuto ed - il relativo gestore è ritornato, nel qual caso restituisce -1 e imposta - \var{errno} a \macro{EINTR}.} + il relativo gestore è ritornato, nel qual caso restituisce -1 e + \var{errno} assumerà il valore \macro{EINTR}.} \end{prototype} La funzione segnala sempre una condizione di errore (il successo sarebbe @@ -1305,7 +1317,8 @@ seguono quella di SUSv2 che prevede il seguente prototipo: Pone il processo in stato di sleep per \param{usec} microsecondi. \bodydesc{La funzione restituisce zero se l'attesa viene completata, o -1 in - caso di errore, nel qual caso \var{errno} è impostata a \macro{EINTR}.} + caso di errore, nel qual caso \var{errno} assumerà il valore + \macro{EINTR}.} \end{prototype} @@ -1320,7 +1333,7 @@ POSIX1.b, il cui prototipo In caso di interruzione restituisce il tempo restante in \param{rem}. \bodydesc{La funzione restituisce zero se l'attesa viene completata, o -1 in - caso di errore, nel qual caso \var{errno} è impostata a + caso di errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\macro{EINVAL}] si è specificato un numero di secondi negativo o un numero di nanosecondi maggiore di 999.999.999. @@ -1345,11 +1358,11 @@ Chiaramente, anche se il tempo pu nanosecondo, la precisione di \func{nanosleep} è determinata dalla risoluzione temporale del timer di sistema. Perciò la funzione attenderà comunque il tempo specificato, ma prima che il processo possa tornare ad essere eseguito -occorrerà almeno attendere il successivo giro di scheduler e cioè un tempo che -a seconda dei casi può arrivare fino a 1/\macro{HZ}, (sempre che il sistema -sia scarico ed il processa venga immediatamente rimesso in esecuzione); per -questo motivo il valore restituito in \param{rem} è sempre arrotondato al -multiplo successivo di 1/\macro{HZ}. +occorrerà almeno attendere il successivo giro di scheduler\index{scheduler} e +cioè un tempo che a seconda dei casi può arrivare fino a 1/\macro{HZ}, (sempre +che il sistema sia scarico ed il processa venga immediatamente rimesso in +esecuzione); per questo motivo il valore restituito in \param{rem} è sempre +arrotondato al multiplo successivo di 1/\macro{HZ}. In realtà è possibile ottenere anche pause più precise del centesimo di secondo usando politiche di scheduling real time come \macro{SCHED\_FIFO} o @@ -1381,8 +1394,8 @@ zombie. In \figref{fig:sig_sigchld_handl} è mostrato il codice contenente una implementazione generica di una routine di gestione per \macro{SIGCHLD}, (che -si trova nei sorgenti allegati nel file \file{HandSIGCHLD.c}); se ripetiamo i -test di \secref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione +si trova nei sorgenti allegati nel file \file{SigHand.c}); se ripetiamo i test +di \secref{sec:proc_termination}, invocando \cmd{forktest} con l'opzione \cmd{-s} (che si limita ad effettuare l'installazione di questa funzione come gestore di \macro{SIGCHLD}) potremo verificare che non si ha più la creazione di zombie. @@ -1404,7 +1417,7 @@ di zombie. #include #include "macro.h" -void HandSIGCHLD(int sig) +void HandSigCHLD(int sig) { int errno_save; int status; @@ -1715,9 +1728,9 @@ degli insiemi di segnali: \func{sigemptyset}, \func{sigfillset}, \bodydesc{Le prime quattro funzioni ritornano 0 in caso di successo, mentre \func{sigismember} ritorna 1 se \param{signum} è in \param{set} e 0 - altrimenti. In caso di errore tutte ritornano -1, con \var{errno} impostata a - \macro{EINVAL} (il solo errore possibile è che \param{signum} non sia un - segnale valido).} + altrimenti. In caso di errore tutte ritornano -1, con \var{errno} + impostata a \macro{EINVAL} (il solo errore possibile è che \param{signum} + non sia un segnale valido).} \end{functions} Dato che in generale non si può fare conto sulle caratteristiche di una @@ -1899,13 +1912,13 @@ siginfo_t { \label{fig:sig_siginfo_t} \end{figure} -Installando un gestore di tipo \var{sa\_sigaction} diventa allora -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 zero, il codice dell'errore associato al segnale, e \var{si\_code}, che -viene usato dal kernel per specificare maggiori dettagli riguardo l'evento che -ha causato l'emissione del segnale. +Installando un gestore di tipo \var{sa\_sigaction} diventa allora 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 +zero, il codice dell'errore associato al segnale, e \var{si\_code}, che viene +usato dal kernel per specificare maggiori dettagli riguardo l'evento che ha +causato l'emissione del segnale. In generale \var{si\_code} contiene, per i segnali generici, per quelli real-time e per tutti quelli inviati tramite \func{kill}, informazioni circa @@ -1981,25 +1994,24 @@ inline SigFunc * Signal(int signo, SigFunc *func) Per questo motivo si è provveduto, per mantenere un'interfaccia semplificata che abbia le stesse caratteristiche di \func{signal}, a definire una funzione equivalente attraverso \func{sigaction}; la funzione è \code{Signal}, e si -trova definita come \code{inline} nel file \file{wrapper.h} (nei sorgenti -allegati), riportata in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso -in seguito. +trova definita nel file \file{SigHand.c} (nei sorgenti allegati), e riportata +in \figref{fig:sig_Signal_code}. La riutilizzeremo spesso in seguito. \subsection{La gestione della \textsl{maschera dei segnali} o \textit{signal mask}} \label{sec:sig_sigmask} Come spiegato in \secref{sec:sig_semantics} tutti i moderni sistemi unix-like -permettono si bloccare temporaneamente (o di eliminare completamente, impostando -\macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è -fatto specificando la cosiddetta \textsl{maschera dei segnali} (o -\textit{signal mask}) del processo\footnote{nel caso di Linux essa è mantenuta - dal campo \var{blocked} della \var{task\_struct} del processo.} cioè -l'insieme dei segnali la cui consegna è bloccata. Abbiamo accennato in -\secref{sec:proc_fork} che la \textit{signal mask} viene ereditata dal padre -alla creazione di un processo figlio, e abbiamo visto al paragrafo precedente -che essa può essere modificata, durante l'esecuzione di un gestore, -attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}. +permettono si bloccare temporaneamente (o di eliminare completamente, +impostando \macro{SIG\_IGN} come azione) la consegna dei segnali ad un +processo. Questo è fatto specificando la cosiddetta \textsl{maschera dei + segnali} (o \textit{signal mask}) del processo\footnote{nel caso di Linux + essa è mantenuta dal campo \var{blocked} della \var{task\_struct} del + processo.} cioè l'insieme dei segnali la cui consegna è bloccata. Abbiamo +accennato in \secref{sec:proc_fork} che la \textit{signal mask} viene +ereditata dal padre alla creazione di un processo figlio, e abbiamo visto al +paragrafo precedente che essa può essere modificata, durante l'esecuzione di +un gestore, attraverso l'uso dal campo \var{sa\_mask} di \var{sigaction}. Uno dei problemi evidenziatisi con l'esempio di \secref{fig:sig_event_wrong} è che in molti casi è necessario proteggere delle sezioni di codice (nel caso in @@ -2443,7 +2455,7 @@ funzione, \func{sigqueue}, il cui prototipo gestore il valore \param{value}. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} viene impostata ai valori: + errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\macro{EAGAIN}] La coda è esarita, ci sono già \macro{SIGQUEUE\_MAX} segnali in attesa si consegna. @@ -2485,7 +2497,7 @@ meccanismi di comunicazione elementare; la prima di queste funzioni Attende che uno dei segnali specificati in \param{set} sia pendente. \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} viene impostata ai valori: + errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\macro{EINTR}] La funzione è stata interrotta. \item[\macro{EINVAL}] Si è specificato un valore non valido per @@ -2530,8 +2542,8 @@ relativi prototipi sono: \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} viene impostata ai valori già visti per - \func{sigwait}, ai quali se aggiunge, per \func{sigtimedwait}: + errore, nel qual caso \var{errno} assumerà uno dei valori già visti per + \func{sigwait}, ai quali si aggiunge, per \func{sigtimedwait}: \begin{errlist} \item[\macro{EAGAIN}] Si è superato il timeout senza che un segnale atteso fosse emmesso.