partendo da una introduzione relativa ai concetti base con cui essi vengono
realizzati, per poi affrontarne la classificazione a secondo di uso e modalità
di generazione fino ad esaminare in dettaglio funzioni e le metodologie di
-gestione.
+gestione.
\section{Introduzione}
situazione precedente.
\item[\macro{SIGXCPU}] Sta per \textit{CPU time limit exceeded}. Questo
segnale è generato quando un processo eccede il limite impostato per il
- tempo di CPU disponibile, vedi \secref{sec:sys_xxx}.
+ tempo di CPU disponibile, vedi \secref{sec:sys_resource_limit}.
\item[\macro{SIGXFSZ}] Sta per \textit{File size limit exceeded}. Questo
segnale è generato quando un processo tenta di estendere un file oltre le
dimensioni specificate dal limite impostato per le dimensioni massime di un
- file, vedi \secref{sec:sys_xxx}.
+ file, vedi \secref{sec:sys_resource_limit}.
\end{basedescript}
necessario copiarlo.
La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror}
-descritta in \secref{sec:sys_strerror}; il suo prototipo è:
+descritta sempre in \secref{sec:sys_strerror}; il suo prototipo è:
\begin{prototype}{signal.h}{void psignal(int sig, const char *s)}
Stampa sullo standard error un messaggio costituito dalla stringa \param{s},
seguita da due punti ed una descrizione del segnale indicato da \param{sig}.
\subsection{Il comportamento generale del sistema.}
- \label{sec:sig_gen_beha}
+\label{sec:sig_gen_beha}
Abbiamo già trattato in \secref{sec:sig_intro} le modalità con cui il sistema
gestisce l'interazione fra segnali e processi, ci resta da esaminare però il
programmi eseguiti in background, che altrimenti sarebbero interrotti da una
successiva pressione di \texttt{C-c} o \texttt{C-y}.
-Per quanto riguarda tutte le altre system call esse vengono tradizionalmente
-classificate, proprio in base al loro comportamento nei confronti dei segnali,
-in \textsl{lente} (\textit{slow}) e \textsl{veloci} (\textit{fast}). La gran
-parte appartiene a quest'ultima categoria che non è influenzata dall'arrivo di
-un segnale. In tal caso un eventuale manipolatore viene sempre eseguito dopo
-che la system call è stata completata. Esse sono dette \textsl{veloci} proprio
-in quanto la loro esecuzione è sostanzialmente immediata e attendere per
-eseguire un manipolatore non comporta nessun inconveniente.
-
-Esistono però dei casi in cui questo non è possibile perché renderebbe
-impossibile una risposta pronta al segnale. In generale questo avviene tutte
-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:
+Per quanto riguarda il comportamento di tutte le altre system call si danno
+sostanzialmente due casi, a seconda che esse siano \textsl{lente}
+(\textit{slow}) o \textsl{veloci} (\textit{fast}). La gran parte di esse
+appartiene a quest'ultima categoria, che non è influenzata dall'arrivo di un
+segnale. Esse sono dette \textsl{veloci} in quanto la loro esecuzione è
+sostanzialmente immediata; la risposta al segnale viene sempre data dopo che
+la system call è stata completata, in quanto attendere per eseguire un
+manipolatore non comporta nessun inconveniente.
+
+In alcuni casi però alcune system call (che per questo motivo vengono chiamate
+\textsl{lente}) possono bloccarsi indefinitamente. In questo caso non si può
+attendere la conclusione della sistem call, perché questo renderebbe
+impossibile una risposta pronta al segnale, per cui il manipolatore viene
+eseguito prima che la system call sia ritornata. Un elenco dei casi in cui si
+presenta questa situazione è il seguente:
\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
+\item la lettura da file che possono bloccarsi in attesa di dati non ancora
+ presenti (come per certi file di dispositivo, i socket o le pipe).
+\item la scrittura sugli stessi file, nel caso in cui dati non possano essere
accettati immediatamente.
-\item apertura di un file di dispositivo che richiede operazioni non immediate
- per una una risposta.
-\item operazioni eseguite con \func{ioctl} che non è detto possano essere
+\item l'apertura di un file di dispositivo che richiede operazioni non
+ immediate per una una risposta.
+\item le operazioni eseguite con \func{ioctl} che non è detto possano essere
eseguite immediatamente.
\item le funzioni di intercomunicazione che si bloccano in attesa di risposte
da altri processi.
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
-
-struct timeval
-{
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
-};
\end{lstlisting}
\end{minipage}
\normalsize
indipendente da \func{alarm}\footnote{nel caso di Linux questo è fatto
utilizzando direttamente il timer del kernel.} e sia utilizzabile senza
interferenze con l'uso di \macro{SIGALRM}. La funzione prende come parametri
-delle strutture di tipo \var{timespec}, la cui definizione è riportata in
-\figref{fig:sig_timespec_def}, che permettono di specificare un tempo con una
-precisione (teorica) fino al nanosecondo.
+delle strutture di tipo \var{timespec}, la cui definizione è riportata in
+\figref{fig:sys_timeval_struct}, che permettono di specificare un tempo con
+una precisione (teorica) fino al nanosecondo.
La funzione risolve anche il problema di proseguire l'attesa dopo
l'interruzione dovuta ad un segnale; infatti in tal caso in \param{rem} viene
questo motivo il valore restituito in \param{rem} è sempre arrotondato al
multiplo successivo di 1/\macro{HZ}.
-\begin{figure}[!htb]
- \footnotesize \centering
- \begin{minipage}[c]{15cm}
- \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
- \end{lstlisting}
- \end{minipage}
- \normalsize
- \caption{La struttura \var{timespec} di \func{nanosleep}.}
- \label{fig:sig_timespec_def}
-\end{figure}
-
In realtà è possibile ottenere anche pause più precise del centesimo di
secondo usando politiche di scheduling real time come \macro{SCHED\_FIFO} o
\macro{SCHED\_RR}; in tal caso infatti il meccanismo di scheduling ordinario
#include <sys/wait.h>
#include "macro.h"
-void Hand_CHLD(int sig)
+void sigchld_hand(int sig)
{
int errno_save;
int status;
\label{fig:sig_sigaction}
\end{figure}
-Come si può notare da quanto riportato in \figref{fig:sig_sigaction} in Linux
-\func{sigaction} permette di specificare il manipolatore in due forme diverse,
-indicate dai campi \var{sa\_handler} e \var{sa\_sigaction}; esse devono essere
-usate in maniera alternativa (in certe implementazioni questi vengono
-specificati come \ctyp{union}): la prima è quella classica usata anche con
-\func{signal}, la seconda permette invece di usare un manipolatore in grado di
-ricevere informazioni più dettagliate dal sistema (ad esempio il tipo di
-errore in caso di \macro{SIGFPE}), attraverso dei parametri aggiuntivi; per i
-dettagli si consulti la man page di \func{sigaction}).
-
Il campo \var{sa\_mask} serve ad indicare l'insieme dei segnali che devono
essere bloccati durante l'esecuzione del manipolatore, ad essi viene comunque
sempre aggiunto il segnale che ne ha causato la chiamata, a meno che non si
\label{tab:sig_sa_flag}
\end{table}
+Come si può notare in \figref{fig:sig_sigaction} \func{sigaction}
+permette\footnote{La possibilità è prevista dallo standard POSIX.1b, ma in
+ Linux è stata aggiunta a partire dai kernel della serie 2.2.x. In precedenza
+ era possibile ottenere alcune informazioni addizionali usando
+ \var{sa\_handler} con un secondo parametro addizionale di tipo \var{struct
+ sigcontext}, che adesso è deprecato.} di utilizzare due forme diverse di
+manipolatore, da specificare, a seconda dell'uso o meno del flag
+\macro{SA\_SIGINFO}, rispettivamente attraverso i campi \var{sa\_sigaction} o
+\var{sa\_handler}, (che devono essere usati in maniera alternativa, in certe
+implementazioni questi vengono addirittura definiti come \ctyp{union}): la
+prima è quella classica usata anche con \func{signal}, la seconda permette
+invece di usare un manipolatore in grado di ricevere informazioni più
+dettagliate dal sistema, attraverso la struttura \var{siginfo\_t}, riportata
+in \figref{fig:sig_siginfo_t}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+siginfo_t {
+ int si_signo; /* Signal number */
+ int si_errno; /* An errno value */
+ int si_code; /* Signal code */
+ pid_t si_pid; /* Sending process ID */
+ uid_t si_uid; /* Real user ID of sending process */
+ int si_status; /* Exit value or signal */
+ clock_t si_utime; /* User time consumed */
+ clock_t si_stime; /* System time consumed */
+ sigval_t si_value; /* Signal value */
+ int si_int; /* POSIX.1b signal */
+ void * si_ptr; /* POSIX.1b signal */
+ void * si_addr; /* Memory location which caused fault */
+ int si_band; /* Band event */
+ int si_fd; /* File descriptor */
+}
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \var{siginfo\_t}.}
+ \label{fig:sig_siginfo_t}
+\end{figure}
+
+Installando un manipolatore di tipo \var{sa\_sigaction} diventa allora
+possibile accedere alle informazioni restituite attraverso il puntatore a
+questa struttura. Tutti i segnali settano i campi \var{si\_signo}, che riporta
+il segnale ricevuto, \var{si\_errno}, che riporta il codice di errore, e
+\var{si\_code}, che viene usato per indicare la ragione per cui è stato emesso
+il segnale (come i dettagli sul tipo di errore per \macro{SIGFPE} e
+\macro{SIGILL}) ed ha valori diversi\footnote{un elenco dettagliato è
+ disponibile nella man page di \func{sigaction}.} a seconda del tipo di
+segnale ricevuto.
+
+Il resto della struttura può essere definito come \ctyp{union} ed i valori
+eventualmente presenti dipendono dal segnale, così \macro{SIGCHLD} ed i
+segnali POSIX.1b\footnote{NdA trovare quale sono e completare l'informazione.}
+inviati tramite \func{kill} avvalorano \var{si\_pid} e \var{si\_uid} coi
+valori corrispondenti al processo che ha emesso il segnale, \macro{SIGILL},
+\macro{SIGFPE}, \macro{SIGSEGV} e \macro{SIGBUS} avvalorano \var{si\_addr} con
+l'indirizzo cui è avvenuto l'errore, \macro{SIGIO} (vedi
+\secref{sec:file_asyncronous_io}) e \macro{SIGPOLL} avvalorano \var{si\_fd}
+con il numero del file descriptor.
+
Benché sia possibile usare nello stesso programma sia \func{sigaction} che
\func{signal} occorre molta attenzione, in quanto le due funzioni possono
interagire in maniera anomala. Infatti l'azione specificata con
ripristinare correttamente un manipolatore precedente, anche se questo è stato
installato con \func{signal}. In generale poi non è il caso di usare il valore
di ritorno di \func{signal} come campo \var{sa\_handler}, o viceversa, dato
-che in certi sistemi questi possono essere diversi. In generale dunque, a meno
-che non si sia vincolati allo standard ISO C, è sempre il caso di evitare
-l'uso di \func{signal} a favore di \func{sigaction}.
-
-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.
+che in certi sistemi questi possono essere diversi. In definitiva dunque, a
+meno che non si sia vincolati all'aderenza stretta allo standard ISO C, è
+sempre il caso di evitare l'uso di \func{signal} a favore di \func{sigaction}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sig_Signal_code}
\end{figure}
+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.
+
\subsection{La gestione della \textsl{maschera dei segnali} o
\textit{signal mask}}
\label{sec:sig_sigmask}
parte l'uso di \type{sigjmp\_buf} per \param{env}, è assolutamente identica a
\func{longjmp}.
-\begin{prototype}{signal.h}
-{int sigaltstack(const stack\_t *ss, stack\_t *oss)}
-
-Installa un nuovo stack per i segnali.
-
- \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
- errore, nel qual caso \var{errno} assumerà i valori:
-
- \begin{errlist}
- \item[\macro{ENOMEM}] La dimensione specificata per il nuovo stack è minore
- di \macro{MINSIGSTKSZ}.
- \item[\macro{EPERM}] Uno degli indirizzi non è valido.
- \item[\macro{EFAULT}] Si è cercato di cambiare lo stack alternativo mentre
- questo è attivo (cioè il processo è in esecuzione su di esso).
- \item[\macro{EINVAL}] \param{ss} non è nullo e \var{ss\_flags} contiene un
- valore diverso da zero che non è \macro{SS\_DISABLE}.
- \end{errlist}}
-\end{prototype}
-
-
%%% Local Variables:
%%% mode: latex