\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}
+ \includecodesample{listati/unreliable_sig.c}
\end{minipage}
\normalsize
\caption{Esempio di codice di un gestore di segnale per la semantica
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[\const{SIGUSR1}] Vedi \const{SIGUSR2}.
-\item[\const{SIGUSR2}] Insieme a \const{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 gestore. L'azione
- predefinita è di terminare il processo.
+\item[\const{SIGUSR1}] Insieme a \const{SIGUSR2} è un segnale a disposizione
+ dell'utente che lo può usare per quello che vuole. Viene generato solo
+ attraverso l'invocazione della funzione \func{kill}. Entrambi i segnali
+ possono essere utili per implementare una comunicazione elementare fra
+ processi diversi, o per eseguire a richiesta una operazione utilizzando un
+ gestore. L'azione predefinita è di terminare il processo.
+\item[\const{SIGUSR2}] È il secondo segnale a dispozione degli utenti. Vedi
+ quanto appena detto per \const{SIGUSR1}.
\item[\const{SIGWINCH}] Il nome sta per \textit{window (size) change} e viene
generato in molti sistemi (GNU/Linux compreso) quando le dimensioni (in
righe e colonne) di un terminale vengono cambiate. Viene usato da alcuni
\func{strsignal} e \func{psignal} è quello di fare usare la variabile
\var{sys\_siglist}, che è definita in \file{signal.h} e può essere acceduta
con la dichiarazione:
-\begin{lstlisting}[stepnumber=0,frame=]{}
- extern const char *const sys_siglist[]
-\end{lstlisting}
+\includecodesnip{listati/siglist.c}
l'array \var{sys\_siglist} contiene i puntatori alle stringhe di descrizione,
indicizzate per numero di segnale, per cui una chiamata del tipo di \code{char
*decr = strsignal(SIGINT)} può essere sostituita dall'equivalente \code{char
una estensione GNU, definita dalle \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:
-\begin{lstlisting}[stepnumber=0,frame=]{}
- void (*signal(int signum, void (*handler)(int)))int)
-\end{lstlisting}
+\includecodesnip{listati/signal.c}
questa infatti, per la poca chiarezza 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
\type{sighandler\_t} che è:
-\begin{lstlisting}[stepnumber=0,frame=]{}
- typedef void (* sighandler_t)(int)
-\end{lstlisting}
+\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}.\footnote{si devono usare le
parentesi intorno al nome della funzione per via delle precedenze degli
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 semantica inaffidabile; Linux seguiva questa convenzione fino alle
-\acr{libc5}. Al contrario BSD segue la semantica affidabile, non
-disinstallando il gestore e bloccando il segnale durante l'esecuzione
-dello stesso. Con 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}.
+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 le \acr{libc4} e le \acr{libc5}.\footnote{nelle
+ \acr{libc5} esiste però la possibilità di includere \file{bsd/signal.h} al
+ posto di \file{signal.h}, nel qual caso la funzione \func{signal} viene
+ 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
+\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 \secref{sec:sig_semantics}, può essere ottenuto
+chiamando \func{sysv\_signal}, uno volta che si sia definita la macro
+\macro{\_XOPEN\_SOURCE}. In generale, per evitare questi problemi, l'uso di
+\func{signal} (ed ogni eventuale ridefinizine della stessa) è da evitare;
+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 \const{SIGFPE}, \const{SIGILL}, o
-\const{SIGSEGV} (qualora non originino da una \func{kill} o una \func{raise})
-è indefinito. Un gestore che ritorna da questi segnali può dare luogo ad
-un ciclo infinito.
+\const{SIGSEGV} (qualora questi non originino da una chiamata ad una
+\func{kill} o ad una \func{raise}) è indefinito. Un gestore che ritorna da
+questi segnali può dare luogo ad un ciclo infinito.
\subsection{Le funzioni \func{kill} e \func{raise}}
Il valore dell'argomento \param{pid} specifica il processo (o i processi) di
destinazione a cui il segnale deve essere inviato e può assumere i valori
riportati in \tabref{tab:sig_kill_values}.
+
+Si noti pertanto che la funzione \code{raise(sig)} può essere definita in
+termini di \func{kill}, ed è sostanzialmente equivalente ad una
+\code{kill(getpid(), sig)}. Siccome \func{raise}, che è definita nello
+standard ISO C, non esiste in alcune vecchie versioni di Unix, in generale
+l'uso di \func{kill} finisce per essere più portabile.
+
+Una seconda funzione che può essere definita in termini di \func{kill} è
+\funcd{killpg}, che è sostanzialmente equivalente a
+\code{kill(-pidgrp, signal)}; il suo prototipo è:
+\begin{prototype}{signal.h}{int killpg(pid\_t pidgrp, int signal)}
+
+ Invia il segnale \param{signal} al process group \param{pidgrp}.
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore, gli errori sono gli stessi di \func{kill}.}
+\end{prototype}
+\noindent e che permette di inviare un segnale a tutto un \textit{process
+ group} (vedi \secref{sec:sess_proc_group}).
+
\begin{table}[htb]
\footnotesize
\centering
\label{tab:sig_kill_values}
\end{table}
-Si noti pertanto che la funzione \code{raise(sig)} può essere definita in
-termini di \func{kill}, ed è sostanzialmente equivalente ad una
-\code{kill(getpid(), sig)}. Siccome \func{raise}, che è definita nello
-standard ISO C, non esiste in alcune vecchie versioni di Unix, in generale
-l'uso di \func{kill} finisce per essere più portabile.
-
-Una seconda funzione che può essere definita in termini di \func{kill} è
-\funcd{killpg}, che è sostanzialmente equivalente a
-\code{kill(-pidgrp, signal)}; il suo prototipo è:
-\begin{prototype}{signal.h}{int killpg(pid\_t pidgrp, int signal)}
-
- Invia il segnale \param{signal} al process group \param{pidgrp}.
- \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- 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_proc_group}).
-
Solo l'amministratore può inviare un segnale ad un processo qualunque, in
tutti gli altri casi l'user-ID reale o l'user-ID effettivo del processo
chiamante devono corrispondere all'user-ID reale o all'user-ID salvato della
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
- \begin{lstlisting}[stepnumber=0]{}
-struct itimerval
-{
- struct timeval it_interval; /* next value */
- struct timeval it_value; /* current value */
-};
- \end{lstlisting}
+ \includestruct{listati/itimerval.h}
\end{minipage}
\normalsize
\caption{La struttura \structd{itimerval}, che definisce i valori dei timer
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
+%%% TeX-master: "gapil"
%%% End: