gestione.
-
\section{Introduzione}
\label{sec:sig_intro}
\textsl{intercetta} il segnale).
-\subsection{Le modalità di funzionamento}
+\subsection{Le \textsl{semantiche} del funzionamento dei segnali}
\label{sec:sig_semantics}
Negli anni il comportamento del sistema in risposta ai segnali è stato
modificato in vari modi nelle differenti implementazioni di Unix. Si possono
individuare due tipologie fondamentali di comportamento dei segnali (dette
-semantiche) che vengono chiamate rispettivamente semantica \textsl{affidabile}
-(o \textit{reliable}) e semantica \textsl{inaffidabile} (o
+\textsl{semantiche}) che vengono chiamate rispettivamente \textsl{semantica
+ affidabile} (o \textit{reliable}) e \textsl{semantica inaffidabile} (o
\textit{unreliable}).
-Nella semantica \textsl{inaffidabile} (quella implementata dalle prime
+Nella \textsl{semantica inaffidabile} (quella implementata dalle prime
versioni di Unix) la routine di gestione del segnale specificata dall'utente
non resta attiva una volta che è stata eseguita; è perciò compito dell'utente
stesso ripetere l'installazione della stessa all'interno della routine di
attivo.
In questo caso è possibile una situazione in cui i segnali possono essere
-perduti. Si consideri il seguente segmento di codice, in cui la prima
-operazione del manipolatore è quella di reinstallare se stesso:
-\footnotesize
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
- int sig_handler(); /* handler function */
+perduti. Si consideri il segmento di codice riportato in
+\secref{fig:sig_old_handler}, nel programma principale viene installato un
+manipolatore (\texttt{\small 5}), ed in quest'ultimo la prima operazione
+(\texttt{\small 11}) è quella di reinstallare se stesso. Se nell'esecuzione
+del manipolatore un secondo segnale arriva prima che esso abbia potuto
+eseguire la reinstallazione, verrà eseguito il comportamento di default
+assegnato al segnale stesso, il che può comportare, a seconda dei casi, che il
+segnale viene perso (se il default era quello di ignorarlo) o la terminazione
+immediata del processo; in entrambi i casi l'azione prevista non verrà
+eseguita.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}{}
+int sig_handler(); /* handler function */
+int main()
+{
...
signal(SIGINT, sig_handler); /* establish handler */
...
+}
int sig_handler()
{
signal(SIGINT, sig_handler); /* restablish handler */
... /* process signal */
}
-\end{lstlisting}
-\normalsize
-se un secondo segnale arriva prima che il manipolatore invocato dal primo
-abbia eseguito la reinstallazione di se stesso il segnale può essere perso o
-causare il comportamento originale assegnato al segnale (in genere la
-terminazione del processo).
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{Esempio di codice di un manipolatore di segnale per la semantica
+ inaffidabile.}
+ \label{fig:sig_old_handler}
+\end{figure}
Questa è la ragione per cui l'implementazione dei segnali secondo questa
semantica viene chiamata \textsl{inaffidabile}; infatti la ricezione del
segnale, ma non è possibile istruire il sistema a non fare nulla in occasione
di un segnale, pur mantenendo memoria del fatto che è avvenuto.
-% Un caso classico in cui si incontra questo problema, è quello in cui si usa il
-% manipolatore per settare un flag che riporta al processo l'occorrenza del
-% segnale, così che questo possa prendere provvedimenti al di fuori del
-% manipolatore. Si consideri il seguente segmento di codice il cui scopo sarebbe
-% quello di fermare il processo fino all'occorrenza di un opportuno segnale:
-
-% \footnotesize
-% \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-% int signal_flag = 0;
-% main()
-% {
-% int sig_handler(); /* handler function */
-% ...
-% signal(SIGINT, sig_handler); /* establish handler */
-% ...
-% while(signal_flag == 0) { /* while flag is zero */
-% pause(); /* go to sleep */
-% }
-% ...
-% }
-% int sig_handler()
-% {
-% signal(SIGINT, sig_handler); /* restablish handler */
-% signal_flag = 1; /* set flag */
-% }
-% \end{lstlisting}
-% \normalsize
-% l'idea è che quando il processo trova il flag a zero viene messo in sleep e
-% verrà risvegliato solo dalla ricezione di un segnale. Il manipolatore si
-% limita in questo caso a settare il flag a uno; all'uscita dal manipolatore la
-% chiamata a \func{pause} è interrotta ed il processo viene risvegliato e
-% riprende l'esecuzione all'istruzione successiva, ma essendo cambiato il flag
-% la condizione non è più soddisfatta e il programma prosegue.
-
-% Il problema con l'implementazione inaffidabile è che niente ci garantisce che
-% il segnale arrivi fra la valutazione della condizione del \code{while} e la
-% chiamata a \func{pause}, nel qual caso, se il segnale non viene più generato,
-% il processo resterà in sleep permanentemente.
-
-% Questo ci mostra ad esempio come con la semantica inaffidabile non esista una
-% modalità semplice per ottenere una operazione di attesa mandando in stato di
-% sleep (vedi \ref{sec:proc_sched}) un processo fino all'arrivo di un segnale.
-
Nella semantica \textsl{affidabile} (quella utilizzata da Linux e da ogni Unix
moderno) il manipolatore una volta installato resta attivo e non si hanno
tutti i problemi precedenti. In questa semantica i segnali vengono
Si tenga presente che il kernel stabilisce cosa fare con un segnale che è
stato bloccato al momento della consegna, non quando viene generato; questo
consente di cambiare l'azione per il segnale prima che esso venga consegnato,
-e si può usare la funzione \func{sigpending} (vedi
-\secref{sec:sig_sigpending}) per determinare quali segnali sono bloccati e
-quali sono pendenti.
+e si può usare la funzione \func{sigpending} (vedi \secref{sec:sig_sigmask})
+per determinare quali segnali sono bloccati e quali sono pendenti.
\subsection{Tipi di segnali}
\textbf{Segnale}&\textbf{Standard}&\textbf{Azione}&\textbf{Descrizione} \\
\hline
\hline
- \macro{SIGHUP} &PL & A & Hangup o fine del processo di controllo \\
+ \macro{SIGHUP} &PL & A &Hangup o terminazione del processo di controllo\\
\macro{SIGINT} &PL & A & Interrupt da tastiera (\cmd{C-c}) \\
\macro{SIGQUIT} &PL & C & Quit da tastiera (\cmd{C-y}) \\
\macro{SIGILL} &PL & C & Istruzione illegale \\
\macro{SIGCHLD} &PL & B & Figlio terminato o fermato \\
\macro{SIGCONT} &PL & & Continua se fermato \\
\macro{SIGSTOP} &PL &DEF& Ferma il processo \\
- \macro{SIGTSTP} &PL & D & Stop typed at tty \\
+ \macro{SIGTSTP} &PL & D & Pressione del tasto di stop sul terminale \\
\macro{SIGTTIN} &PL & D & Input sul terminale per un processo
in background \\
\macro{SIGTTOU} &PL & D & Output sul terminale per un processo
\macro{SIGPOLL} &SL & A & Pollable event (Sys V).
Sinonimo di \macro{SIGIO} \\
\macro{SIGPROF} &SL & A & Timer del profiling scaduto \\
- \macro{SIGSYS} &SL & C & Bad argument to routine (SVID) \\
- \macro{SIGTRAP} &SL & C & Trace/breakpoint trap \\
- \macro{SIGURG} &SLB& B & Urgent condition on socket \\
+ \macro{SIGSYS} &SL & C & Argomento sbagliato per una subroutine (SVID) \\
+ \macro{SIGTRAP} &SL & C & Trappole per un Trace/breakpoint \\
+ \macro{SIGURG} &SLB& B & Ricezione di una urgent condition su un socket\\
\macro{SIGVTALRM}&SLB& A & Virtual alarm clock \\
\macro{SIGXCPU} &SLB& C & Ecceduto il limite sul CPU time \\
\macro{SIGXFSZ} &SLB& C & Ecceduto il limite sulla dimensione dei file \\
- \macro{SIGIOT} &L & C & IOT trap. A synonym for \macro{SIGABRT} \\
+ \macro{SIGIOT} &L & C & IOT trap. Sinonimo di \macro{SIGABRT} \\
\macro{SIGEMT} &L & & \\
- \macro{SIGSTKFLT}&L & A & Stack fault on coprocessor \\
- \macro{SIGIO} &LB & A & I/O now possible (4.2 BSD) \\
- \macro{SIGCLD} &L & & A synonym for \macro{SIGCHLD} \\
+ \macro{SIGSTKFLT}&L & A & Errore sullo stack del coprocessore \\
+ \macro{SIGIO} &LB & A & L'I/O è possibile (4.2 BSD) \\
+ \macro{SIGCLD} &L & & Sinonimo di \macro{SIGCHLD} \\
\macro{SIGPWR} &L & A & Fallimento dell'alimentazione \\
- \macro{SIGINFO} &L & & A synonym for \macro{SIGPWR} \\
+ \macro{SIGINFO} &L & & Sinonimo di \macro{SIGPWR} \\
\macro{SIGLOST} &L & A & Perso un lock sul file (per NFS) \\
- \macro{SIGWINCH} &LB & B & Window resize signal (4.3 BSD, Sun) \\
- \macro{SIGUNUSED}&L & A & Unused signal (will be SIGSYS) \\
+ \macro{SIGWINCH} &LB & B & Finestra ridimensionata (4.3 BSD, Sun) \\
+ \macro{SIGUNUSED}&L & A &Segnale inutilizzato (diventerà \macro{SIGSYS})\\
\hline
\end{tabular}
\caption{Lista dei segnali in Linux.}
aritmetici compresa la divisione per zero e l'overflow.
Se il manipolatore ritorna il comportamento del processo è indefinito, ed
- ignorare questo segnale può condurre ad un loop infinito.
+ ignorare questo segnale può condurre ad un ciclo infinito.
% Per questo segnale le cose sono complicate dal fatto che possono esserci
% molte diverse eccezioni che \texttt{SIGFPE} non distingue, mentre lo
\item[\macro{SIGPROF}] Il nome sta per \textit{profiling}. Indica la scadenza
di un timer che misura sia il tempo di CPU speso direttamente dal processo
che quello che il sistema ha speso per conto di quest'ultimo. In genere
- viene usato dai tool che servono a fare il profilo d'uso della CPU da parte
- del processo.
+ viene usato dagli strumenti che servono a fare la profilazione dell'utilizzo
+ del tempo di CPU da parte del processo.
\end{basedescript}
Raccogliamo qui infine usa serie di segnali che hanno scopi differenti non
classificabili in maniera omogenea. Questi segnali sono:
\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\macro{SIGUSR1} e \macro{SIGUSR2}] Sono due segnali a disposizione
+\item[\macro{SIGUSR1}] Vedi \macro{SIGUSR2}.
+\item[\macro{SIGUSR2}] Insieme a \macro{SIGUSR1} è un segnale a disposizione
dell'utente che li può usare per quello che vuole. Possono essere utili per
implementare una comunicazione elementare fra processi diversi, o per
eseguire a richiesta una operazione utilizzando un manipolatore. L'azione di
loro stretta relazione con la creazione di nuovi processi.
Come accennato in \secref{sec:proc_fork} quando viene creato un nuovo processo
-con \func{fork} esso eredita dal padre sia le azioni che sono state settate
-per i singoli segnali, che la maschera dei segnali bloccati (tratteremo
-quest'ultimo argomento in \ref{sec:sig_sigpending}). Invece tutti i segnali
-pendenti e gli allarmi vengono cancellati; essi infatti devono essere
-recapitati solo al padre, al figlio dovranno arrivare solo i segnali dovuti
-alle sue azioni.
+esso eredita dal padre sia le azioni che sono state settate per i singoli
+segnali, che la maschera dei segnali bloccati (vedi \secref{sec:sig_sigmask}).
+Invece tutti i segnali pendenti e gli allarmi vengono cancellati; essi infatti
+devono essere recapitati solo al padre, al figlio dovranno arrivare solo i
+segnali dovuti alle sue azioni.
Quando si mette in esecuzione un nuovo programma con \func{exec} (si ricordi
quanto detto in \secref{sec:proc_exec}) tutti i segnali per i quali è stato
le volte che si ha a che fare con system call che possono bloccarsi
indefinitamente, (quelle che, per questo, vengono chiamate \textsl{lente}). Un
elenco dei casi in cui si presenta questa situazione è il seguente:
-\begin{itemize*}
+\begin{itemize}
\item lettura da file che possono bloccarsi in attesa di dati non ancora
presenti (come per certi file di dispositivo, la rete o le pipe).
\item scrittura sugli stessi file, nel caso in cui dati non possano essere
eseguite immediatamente.
\item le funzioni di intercomunicazione che si bloccano in attesa di risposte
da altri processi.
-\item la funzione \func{pause} (usata appunto per attendere l'-arrivo di un
+\item la funzione \func{pause} (usata appunto per attendere l'arrivo di un
segnale).
\item la funzione \func{wait} (se nessun processo figlio è ancora terminato).
-\end{itemize*}
+\end{itemize}
In questo caso si pone il problema di cosa fare una volta che il manipolatore
sia ritornato. La scelta originaria dei primi Unix era quella di far ritornare
però non considera sistemi multitasking, per cui la definizione è tanto vaga
da essere del tutto inutile in un sistema Unix; è questo il motivo per cui
ogni implementazione successiva ne ha modificato e ridefinito il
-comportamento, pur mantenendone immutato il prototipo\footnote{in realtà
- alcune vecchie implementazioni (SVR4 e 4.3+BSD) usano parametri aggiuntivi
- per definire il comportamento della funzione.} che è:
+comportamento, pur mantenendone immutato il prototipo\footnote{in realtà in
+ alcune vecchie implementazioni (SVr4 e 4.3+BSD in particolare) vengono usati
+ alcuni parametri aggiuntivi per definire il comportamento della funzione,
+ vedremo in \secref{sec:sig_sigaction} che questo è possibile usando la
+ funzione \func{sigaction}.} che è:
\begin{prototype}{signal.h}
{sighandler\_t signal(int signum, sighandler\_t handler)}
o \macro{SIG\_ERR} in caso di errore.}
\end{prototype}
-In questa definizione si è usato il tipo \type{sighandler\_t} che è una
-estensione GNU, definita dalle \acr{glibc}, che permette di riscrivere il
-prototipo in una forma più leggibile dell'originario:
+In questa definizione si è usato un tipo di dato, \type{sighandler\_t}, che è
+una estensione GNU, definita dalle \acr{glibc}, esso permette di riscrivere il
+prototipo di \func{signal} nella forma appena vista, che risulta molto più
+leggibile di quanto non sia la versione originaria che di norma è definita
+come:
\begin{verbatim}
-void (*signal(int signum, void (*handler)(int)))int)
+ void (*signal(int signum, void (*handler)(int)))int)
\end{verbatim}
questa infatti, per la poca chiarezza della sintassi del C quando si vanno a
trattare puntatori a funzioni, è molto meno comprensibile. Da un confronto
secondo la semantica inaffidabile; Linux seguiva questa convenzione fino alle
\acr{libc5}. Al contrario BSD segue la semantica affidabile, non resettando il
manipolatore e bloccando il segnale durante l'esecuzione dello stesso. Con
-l'utilizzo delle \acr{glibc2} anche Linux è passato a questo comportamento;
-quello della versione originale della funzione, il cui uso è deprecato per i
-motivi visti in \secref{sec:sig_semantics}, può essere ottenuto chiamando
-\func{sysv\_signal}. In generale, per evitare questi problemi, tutti i nuovi
-programmi dovrebbero usare \func{sigaction}.
+l'utilizzo delle \acr{glibc} dalla versione 2 anche Linux è passato a questo
+comportamento; quello della versione originale della funzione, il cui uso è
+deprecato per i motivi visti in \secref{sec:sig_semantics}, può essere
+ottenuto chiamando \func{sysv\_signal}. In generale, per evitare questi
+problemi, tutti i nuovi programmi dovrebbero usare \func{sigaction}.
È da tenere presente che, seguendo lo standard POSIX, il comportamento di un
processo che ignora i segnali \macro{SIGFPE}, \macro{SIGILL}, o
\label{sec:sig_alarm_abort}
Un caso particolare di segnali generati a richiesta è quello che riguarda i
-vari segnali di temporizzazione e \macro{SIGABORT}, per ciascuno di questi
+vari segnali di temporizzazione e \macro{SIGABRT}, per ciascuno di questi
segnali sono previste funzioni specifiche che ne effettuino l'invio. La più
comune delle funzioni usate per la temporizzazione è \func{alarm} il cui
prototipo è:
\begin{prototype}{unistd.h}{unsigned int alarm(unsigned int seconds)}
- Predispone l'invio di \macro{SIGALARM} dopo \param{seconds} secondi.
+ Predispone l'invio di \macro{SIGALRM} dopo \param{seconds} secondi.
\bodydesc{La funzione restituisce il numero di secondi rimanenti ad un
precedente allarme, o zero se non c'erano allarmi pendenti.}
La funzione fornisce un meccanismo che consente ad un processo di predisporre
un'interruzione nel futuro, (ad esempio per effettuare una qualche operazione
dopo un certo periodo di tempo), programmando l'emissione di un segnale (nel
-caso in questione \macro{SIGALARM}) dopo il numero di secondi specificato da
+caso in questione \macro{SIGALRM}) dopo il numero di secondi specificato da
\param{seconds}.
Se si specifica per \param{seconds} un valore nullo non verrà inviato nessun
\begin{itemize}
\item un \textit{real-time timer} che calcola il tempo reale trascorso (che
corrisponde al \textit{clock time}). La scadenza di questo timer provoca
- l'emissione di \macro{SIGALARM}.
+ l'emissione di \macro{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 \macro{SIGVTALRM}.
\label{sec:sig_pause_sleep}
Il metodo tradizionale per fare attendere\footnote{cioè di porre
- temporanemente il processo in stato di \textit{sleep}, vedi
+ temporaneamente il processo in stato di \textit{sleep}, vedi
\ref{sec:proc_sched}.} ad un processo fino all'arrivo di un segnale è
quello di usare la funzione \func{pause}, il cui prototipo è:
\begin{prototype}{unistd.h}{int pause(void)}
segnale è quello della gestione di \macro{SIGCHLD}. Abbiamo visto in
\secref{sec:proc_termination} che una delle azioni eseguite dal kernel alla
conclusione di un processo è quella di inviare questo segnale al
-padre.\footnote{in realtà in SRV4 eredita la semantica di System V, in cui il
+padre.\footnote{in realtà in SVr4 eredita la semantica di System V, in cui il
segnale si chiama \macro{SIGCLD} e viene trattato in maniera speciale; in
System V infatti se si setta esplicitamente l'azione a \macro{SIG\_IGN} il
segnale non viene generato ed il sistema non genera zombie (lo stato di
In \figref{fig:sig_sigchld_handl} è mostrato il codice della nostra
implementazione del manipolatore; se aggiungiamo al codice di
-\file{ForkTest.c} l'intallazione di questo manipolatore potremo verificare che
+\file{ForkTest.c} l'installazione di questo manipolatore potremo verificare che
ripetendo l'esempio visto in \secref{sec:proc_termination} che non si ha più
la creazione di zombie.
rimosso sarà recapitato un solo segnale.
Allora nel caso della terminazione dei processi figli, se si chiamasse
-\func{waitpid} una sola volta, essa leggerebbe lo stato di teminazione per un
+\func{waitpid} una sola volta, essa leggerebbe lo stato di terminazione per un
solo processo, anche se i processi terminati sono più di uno, e gli altri
resterebbero in stato di zombie per un tempo indefinito.
\label{sec:sig_example}
Come accennato in \secref{sec:sig_pause_sleep} è possibile implementare
-\func{sleep} a partire da dall'uso di \func{pause} e \func{alarm}. A prima
-vista questo può sembrare di implementazione immediata; ad esempio una
-semplice versione di \func{sleep} potrebbe essere quella illustrata in
+\func{sleep} a partire dall'uso di \func{pause} e \func{alarm}. A prima vista
+questo può sembrare di implementazione immediata; ad esempio una semplice
+versione di \func{sleep} potrebbe essere quella illustrata in
\figref{fig:sig_sleep_wrong}.
-
-Dato che è nostra intenzione utilizzare \macro{SIGALARM} il primo passo della
+Dato che è nostra intenzione utilizzare \macro{SIGALRM} il primo passo della
nostra implementazione di sarà quello di installare il relativo manipolatore
salvando il precedente (\texttt{\small 4-7}). Si effettuerà poi una chiamata
ad \func{alarm} per specificare il tempo d'attesa per l'invio del segnale a
presenta una pericolosa race condition. Infatti se il processo viene
interrotto fra la chiamata di \func{alarm} e \func{pause} può capitare (ad
esempio se il sistema è molto carico) che il tempo di attesa scada prima
-dell'esecuzione quest'ultima, cosicchè essa sarebbe eseguita dopo l'arrivo di
+dell'esecuzione quest'ultima, cosicché essa sarebbe eseguita dopo l'arrivo di
\macro{SIGALRM}. In questo caso ci si troverebbe di fronte ad un deadlock, in
quanto \func{pause} non verrebbe mai più interrotta (se non in caso di un
altro segnale).
Questo problema può essere risolto (ed è la modalità con cui veniva fatto in
-SVr2) usando la funzione \func{longjump} (vedi \secref{sec:proc_longjmp}) per
+SVr2) usando la funzione \func{longjmp} (vedi \secref{sec:proc_longjmp}) per
uscire dal manipolatore; in questo modo, con una condizione sullo stato di
uscita di quest'ultima, si può evitare la chiamata a \func{pause}, usando un
codice del tipo di quello riportato in \figref{fig:sig_sleep_incomplete}.
timeout su una qualunque system call bloccante.
Un secondo esempio è quello in cui si usa il segnale per notificare una
-quelche forma di evento; in genere quello che si fa in questo caso è settare
+qualche forma di evento; in genere quello che si fa in questo caso è settare
nel manipolatore un opportuno flag da controllare nel corpo principale del
programma (con un codice del tipo di quello riportato in
\secref{fig:sig_event_wrong}.
segnali ha introdotto una interfaccia di gestione completamente nuova, che
permette di ottenete un controllo molto più dettagliato. In particolare lo
standard ha introdotto un nuovo tipo di dato \type{sigset\_t}, che permette di
-rappresentare un insieme di segnali (un \textit{signal set}, come viene
-usualmente chiamato), che è il tipo di dato che viene usato per gestire il
-blocco dei segnali.
-
-In genere un \textit{signal set} è rappresentato da un intero di dimensione
-opportuna, di solito si pari al numero di bit dell'architettura della
-macchina\footnote{nel caso dei PC questo comporta un massimo di 32 segnali
- distinti, dato che in Linux questi sono sufficienti non c'è necessità di
- nessuna struttura più complicata.}, ciascun bit del quale è associato ad uno
-specifico segnale; in questo modo è di solito possibile implementare le
-operazioni direttamente con istruzioni elementari del processore; lo standard
-POSIX.1 definisce cinque funzioni per la manipolazione dei \textit{signal set},
-\func{sigemptyset}, \func{sigfillset}, \func{sigaddset}, \func{sigdelset} e
-\func{sigismember}, i cui prototipi sono:
+rappresentare un \textsl{insieme di segnali} (un \textit{signal set}, come
+viene usualmente chiamato), che è il tipo di dato che viene usato per gestire
+il blocco dei segnali.
+
+In genere un \textsl{insieme di segnali} è rappresentato da un intero di
+dimensione opportuna, di solito si pari al numero di bit dell'architettura
+della macchina\footnote{nel caso dei PC questo comporta un massimo di 32
+ segnali distinti, dato che in Linux questi sono sufficienti non c'è
+ necessità di nessuna struttura più complicata.}, ciascun bit del quale è
+associato ad uno specifico segnale; in questo modo è di solito possibile
+implementare le operazioni direttamente con istruzioni elementari del
+processore; lo standard POSIX.1 definisce cinque funzioni per la manipolazione
+degli insiemi di segnali: \func{sigemptyset}, \func{sigfillset},
+\func{sigaddset}, \func{sigdelset} e \func{sigismember}, i cui prototipi sono:
\begin{functions}
\headdecl{signal.h}
-
- \funcdecl{int sigemptyset(sigset\_t *set)} Inizializza un \textit{signal set}
- vuoto.
+
+ \funcdecl{int sigemptyset(sigset\_t *set)} Inizializza un insieme di segnali
+ vuoto (in cui non c'è nessun segnale).
- \funcdecl{int sigfillset(sigset\_t *set)} Inizializza un \textit{signal set}
- pieno (con tutti i segnali).
+ \funcdecl{int sigfillset(sigset\_t *set)} Inizializza un insieme di segnali
+ pieno (in cui ci sono tutti i segnali).
\funcdecl{int sigaddset(sigset\_t *set, int signum)} Aggiunge il segnale
- \param{signum} al \textit{signal set} \param{set}.
+ \param{signum} all'insieme di segnali \param{set}.
\funcdecl{int sigdelset(sigset\_t *set, int signum)} Toglie il segnale
- \param{signum} dal \textit{signal set} \param{set}.
+ \param{signum} dall'insieme di segnali \param{set}.
\funcdecl{int sigismember(const sigset\_t *set, int signum)} Controlla se il
- segnale \param{signum} è nel \textit{signal set} \param{set}
+ segnale \param{signum} è nell'insieme di segnali \param{set}.
\bodydesc{Le prime quattro funzioni ritornano 0 in caso di successo, mentre
\func{sigismember} ritorna 1 se \param{signum} è in \param{set} e 0
immagazzinate ulteriori informazioni) tutte le operazioni devono essere
comunque eseguite attraverso queste funzioni.
-In genere si usa un \textit{signal set} per specificare quali segnali si vuole
+In genere si usa un insieme di segnali per specificare quali segnali si vuole
bloccare, o per riottenere dalle varie funzioni di gestione la maschera dei
-segnali attivi. Essi possono essere definiti in due diverse maniere,
-aggiungendo i segnali voluti ad un insieme vuoto ottenuto con
-\func{sigemptyset} o togliendo quelli che non servono da un insieme completo
-ottenuto con \func{sigfillset}. Infine \func{sigismember} permette di vericare
-la presenza di uno specifico segnale in un \textit{signal set}.
+segnali attivi (vedi \secref{sec:sig_sigmask}). Essi possono essere definiti
+in due diverse maniere, aggiungendo i segnali voluti ad un insieme vuoto
+ottenuto con \func{sigemptyset} o togliendo quelli che non servono da un
+insieme completo ottenuto con \func{sigfillset}. Infine \func{sigismember}
+permette di verificare la presenza di uno specifico segnale in un
+insieme.
\subsection{La funzione \func{sigaction}}
\hline
\hline
\macro{SA\_NOCLDSTOP}& Se il segnale è \macro{SIGCHLD} allora non deve
- essere notificato quando il processo figlio viene fermato da uno dei
- segnali \macro{SIGSTOP}, \macro{SIGTSTP}, \macro{SIGTTIN} or
- \macro{SIGTTOU}.\\
+ essere notificato quando il processo figlio viene
+ fermato da uno dei segnali \macro{SIGSTOP},
+ \macro{SIGTSTP}, \macro{SIGTTIN} o
+ \macro{SIGTTOU}.\\
\macro{SA\_ONESHOT} & Ristabilisce l'azione per il segnale al valore di
- default una volta che il manipolatore è stato lanciato, riproduce cioè il
- comportamento della semantica inaffidabile.\\
+ default una volta che il manipolatore è stato
+ lanciato, riproduce cioè il comportamento della
+ semantica inaffidabile.\\
\macro{SA\_RESETHAND}& Sinonimo di \macro{SA\_ONESHOT}. \\
\macro{SA\_RESTART} & Riavvia automaticamente le \textit{slow system
- call} quando vengono interrotte dal suddetto segnale; riproduce cioè il
- comportamento standard di BSD.\\
+ call} quando vengono interrotte dal suddetto
+ segnale; riproduce cioè il comportamento standard
+ di BSD.\\
\macro{SA\_NOMASK} & Evita che il segnale corrente sia bloccato durante
- l'esecuzione del manipolatore.\\
- \macro{SA\_NODEFER} & Sinonimo di \macro{SA\_NOMASK}.\\
+ l'esecuzione del manipolatore.\\
+ \macro{SA\_NODEFER} & Sinonimo di \macro{SA\_NOMASK}.\\
\macro{SA\_SIGINFO} & Deve essere specificato quando si vuole usare un
- manipolatore in forma estesa usando \var{sa\_sigaction} al posto di
- \var{sa\_handler}. \\
- \macro{SA\_ONSTACK} & Stabilisce l'uso di uno stack alternativo per
- l'esecuzione del manipolatore (vedi \secref{sec:sig_altstack}).\\
+ manipolatore in forma estesa usando
+ \var{sa\_sigaction} al posto di \var{sa\_handler}.\\
+ \macro{SA\_ONSTACK} & Stabilisce l'uso di uno stack alternativo per
+ l'esecuzione del manipolatore (vedi
+ \secref{sec:sig_xxx}).\\
\hline
\end{tabular}
\caption{Valori del campo \var{sa\_flag} della struttura \var{sigaction}.}
Come spiegato in \secref{sec:sig_semantics} tutti i moderni sistemi unix-like
permettono si bloccare temporaneamente (o di eliminare completamente, settando
\macro{SIG\_IGN} come azione) la consegna dei segnali ad un processo. Questo è
-fatto specificando la cosiddetta \textit{signal mask} del
-processo\footnote{nel caso di Linux essa è mantenuta dal campo \var{blocked}
- della \var{task\_struct} del processo.} che viene espressa come il signal
-set dei segnali la cui consegna è bloccata. Abbiamo accennato in
+fatto specificando la \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 specificata, durante l'esecuzione di un manipolatore,
+che essa può essere modificata, durante l'esecuzione di un manipolatore,
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 la
-sezione fra il test e la eventuale cancellazione del flag che testimoniava
-l'avvenuta occorrenza del segnale) in modo da essere sicuri che essi siano
-eseguiti senza interruzioni. Le operazioni più semplici, come l'assegnazione o
-il controllo di una variabile (per essere sicuri si può usare il tipo
-\type{sig\_atomic\_t}) di norma sono atomiche, ma quando le operazioni sono
-più complesse si può usare la funzione \func{sigprocmask} per bloccare uno o
-più segnali; il suo prototipo è:
+che in molti casi è necessario proteggere delle sezioni di codice (nel caso in
+questoine la sezione fra il controllo e la eventuale cancellazione del flag
+che testimoniava l'avvenuta occorrenza del segnale) in modo da essere sicuri
+che essi siano eseguiti senza interruzioni.
+
+Le operazioni più semplici, come l'assegnazione o il controllo di una
+variabile (per essere sicuri si può usare il tipo \type{sig\_atomic\_t}) di
+norma sono atomiche, quando occorrono operazioni più complesse si può invece
+usare la funzione \func{sigprocmask} che permette di bloccare uno o più
+segnali; il suo prototipo è:
\begin{prototype}{signal.h}
{int sigprocmask(int how, const sigset\_t *set, sigset\_t *oldset)}
- Cambia la \textit{signal mask} del processo corrente.
+ Cambia la \textsl{maschera dei segnali} del processo corrente.
\bodydesc{La funzione restituisce zero in caso di successo e -1 per un
errore, nel qual caso \var{errno} assumerà i valori:
\end{errlist}}
\end{prototype}
-La funzione
-
+La funzione usa l'insieme di segnali dato all'indirizzo \param{set} per
+modificare la maschera dei segnali del processo corrente. La modifica viene
+effettuta a seconda del valore dell'argomento \param{how}, secondo le modalità
+specificate in \tabref{tab:sig_procmask_how}. Qualora si specifichi un valore
+non nullo per \param{oldset} la mashera dei segnali corrente viene salvata a
+quell'indirizzo.
\begin{table}[htb]
\footnotesize
\textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \macro{SIG\_BLOCK} & .\\
- \macro{SIG\_UNBLOCK} & .\\
- \macro{SIG\_SETMASK} & .\\
+ \macro{SIG\_BLOCK} & L'insieme dei segnali bloccati è l'unione fra
+ quello specificato e quello corrente.\\
+ \macro{SIG\_UNBLOCK} & I segnali specificati in \param{set} sono rimossi
+ dalla maschera dei segnali, specificare la
+ cancellazione di un segnale non bloccato è legale.\\
+ \macro{SIG\_SETMASK} & La maschera dei segnali è settata al valore
+ specificato da \param{set}.\\
\hline
\end{tabular}
\caption{Valori e significato dell'argomento \param{how} della funzione
\label{tab:sig_procmask_how}
\end{table}
-
Un altro
+
\begin{prototype}{signal.h}
{int sigsuspend(const sigset\_t *mask)}
-\subsection{Le funzioni \func{sigpending} e \func{sigsuspend}}
-\label{sec:sig_sigpending}
-