Correzioni per le footnote e scritta altra roba sui segnali (finite kill e
[gapil.git] / signal.tex
index aad92a9a6ff9ac9e9a3310f0888d2e0f3403ddd5..90885ffd70e750208ae212cd8dbedd9bc5a3a2b1 100644 (file)
@@ -45,8 +45,8 @@ il seguente:
 \item una richiesta dell'utente di terminare o fermare il programma. In genere
   si realizza attraverso un segnale mandato dalla shell in corrispondenza
   della pressione di tasti del terminale come \code{C-c} o
-  \code{C-z}\footnote{indichiamo con \code{C-x} la pressione simultanea al
-    tasto \code{x} del tasto control (ctrl in molte tastiere)}.
+  \code{C-z}.\footnote{indichiamo con \code{C-x} la pressione simultanea al
+    tasto \code{x} del tasto control (ctrl in molte tastiere).}
 \item l'esecuzione di una \func{kill} o di una \func{raise} da parte del
   processo stesso o di un'altro (solo nel caso della \func{kill}).
 \end{itemize*}
@@ -873,7 +873,7 @@ da essere del tutto inutile in un sistema Unix; 
 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 è:
+  per definire il comportamento della funzione.} che è:
 \begin{prototype}{signal.h}
   {sighandler\_t signal(int signum, sighandler\_t handler)} 
   
@@ -898,10 +898,10 @@ con il precedente prototipo si pu
     typedef void (* sighandler_t)(int) 
 \end{verbatim}
 e cioè un puntatore ad una funzione \type{void} (cioè senza valore di ritorno)
-e che prende un argomento di tipo \type{int}\footnote{si devono usare le
+e che prende un argomento di tipo \type{int}.\footnote{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 \type{void} e non un puntatore ad una funzione \type{void}}.
+  un puntatore a \type{void} e non un puntatore ad una funzione \type{void}.}
 La funzione \func{signal} quindi restituisce e prende come secondo argomento
 un puntatore a una funzione di questo tipo, che è appunto il manipolatore del
 segnale.
@@ -911,19 +911,30 @@ direttamente con una delle costanti definite in \secref{sec:sig_standard}. Il
 manipolatore \param{handler} invece, oltre all'indirizzo della funzione da
 chiamare all'occorrenza del segnale, può assumere anche i due valori costanti
 \macro{SIG\_IGN} con cui si dice ignorare il segnale e \macro{SIG\_DFL} per
-installare l'azione di di default\footnote{si ricordi però che i due segnali
+installare l'azione di di default.\footnote{si ricordi però che i due segnali
   \macro{SIGKILL} e \macro{SIGSTOP} non possono essere ignorati né
-  intercettati}.
-
-La funzione \func{signal} originale (e quella attuale in System V) era
-conforme alla semantica inaffidabile e resettava l'azione di default a
-\macro{SIG\_DEF}; Linux fino alle \acr{libc4} e le \acr{libc5} seguiva la
-stessa semantica; al contrario con l'utilizzo delle \acr{glibc2}, Linux, come
-BSD, non resetta il manipolatore e blocca il segnale durante la chiamata. La
-versione originale della funzione, il cui uso è deprecato, può essere
-utilizzata chiamando \func{sysv\_signal}.
-
-È da tenere presente che seguendo lo standard POSIX, il comportamento di un
+  intercettati.}
+
+La funzione restituisce l'indirizzo dell'azione precedente, che può essere
+salvato per poterlo ripristinare (con un'altra chiamata a \func{signal}) in un
+secondo tempo. Si ricordi che se si setta come azione \macro{SIG\_IGN} (o si
+setta un \macro{SIG\_DFL} per un segnale il cui default è di essere ignorato),
+tutti i segnali pendenti saranno scartati, e non verranno mai notificati.
+
+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 manipolatore 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 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}.
+
+È da tenere presente che, seguendo lo standard POSIX, il comportamento di un
 processo che ignora i segnali \macro{SIGFPE}, \macro{SIGILL}, o
 \macro{SIGSEGV} (qualora non originino da una \func{kill} o una \func{raise})
 è indefinito. Un manipolatore che ritorna da questi segnali può dare luogo ad
@@ -934,16 +945,33 @@ un ciclo infinito.
 \label{sec:sig_kill_raise}
 
 Come accennato in \secref{sec:sig_types}, un segnale può essere generato
-``artificialmente'' attraverso l'uso delle funzioni \func{kill} e
-\func{raise}, i cui prototipi sono:
+direttamente da un processo. L'invio di un sengale generico può essere
+effettuato attraverso delle funzioni \func{kill} e \func{raise}. La prima
+serve per inviare un segnale al processo corrente, ed il suo prototipo è:
+\begin{prototype}{signal.h}{int raise(int sig)}
+  Invia il segnale \param{sig} al processo corrente.
+  
+  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
+    errore, il solo errore restituito è \macro{EINVAL} qualora si sia
+    specificato un numero di segnale invalido.}
+\end{prototype}
+
+Il valore di \param{sig} specifica il segnale che si vuole inviare e può
+essere specificato con una delle macro definite in
+\secref{sec:sig_classification}.  In genere questa funzione viene usata per
+riprodurre il comportamento di default di un segnale che sia stato
+intercettato. In questo caso, una volta eseguite le operazioni volute, il
+manipolatore potrà reinstallare l'azione di default, e attivarla con
+\func{raise}.
+
+Se invece si vuole inviare un segnale ad un altro processo occorre utilizzare
+la funzione \func{kill}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h}
   \headdecl{signal.h}
-  \funcdecl{int kill(pid\_t pid, int sig)} invia il segnale \param{sig} al
+  \funcdecl{int kill(pid\_t pid, int sig)} Invia il segnale \param{sig} al
   processo specificato con \param{pid}.
-  \funcdecl{int raise(int sig)} invia il segnale \param{sig} al processo
-  corrente.
-  
+
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
     errore, nel qual caso \var{errno} assumerà i valori:
   \begin{errlist}
@@ -957,26 +985,19 @@ Come accennato in \secref{sec:sig_types}, un segnale pu
 \end{functions}
 
 La funzione \code{raise(sig)} è sostanzialmente equivalente ad una
-\code{kill(getpid(), sig)}. Il valore di \param{sig} specifica il segnale che
-si vuole inviare e può essere specificato con una delle macro definite in
-\ref{sec:sig_classification}. 
+\code{kill(getpid(), sig)}. Siccome \func{raise} è definita nello standard ISO
+C non esiste in alcune vecchie versioni di Unix, per cui in generale l'uso di
+\func{kill} è più portabile.
 
 Lo standard POSIX poi prevede che il valore 0 sia usato per specificare il
 segnale nullo.  Se le funzioni vengono chiamate con questo valore non viene
 inviato nessun segnale, ma viene eseguito il controllo degli errori, in tal
 caso si otterrà un errore \macro{EPERM} se non si hanno i permessi necessari
 ed un errore \macro{ESRCH} se il processo specificato non esiste. Si tenga
-conto però che il sistema ricicla i \acr{pid}, così come visto in
-\secref{sec:proc_pid}, per cui l'esistenza di un processo non significa che
+conto però che il sistema ricicla i \acr{pid} (come accennato in
+\secref{sec:proc_pid}) per cui l'esistenza di un processo non significa che
 esso sia realmente quello a cui si intendeva mandare il segnale.
 
-Per poter effettuare l'invio del segnale ad un altro processo, si devono
-possedere i privilegi di amministratore, oppure il \textit{real user id} o
-l'\textit{effective user id} del chiamante devono corrispondere al
-\textit{real user id} o al \textit{aved user id} della destinazione. Nel caso
-del segnale \macro{SIGCONT} entrambi i processi devono appartenere alla stessa
-sessione.
-
 Il valore dell'argomento \param{pid} specifica la destinazione a cui inviare
 il segnale e può assumere i seguenti significati:
 \begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
@@ -990,13 +1011,117 @@ il segnale e pu
   group $|\code{pid}|$.
 \end{basedescript}
 
+Solo l'amministratore può inviare un segnale ad un processo qualunque, in
+tutti gli altri casi il \textit{real user id} o l'\textit{effective user id}
+del processo chiamante devono corrispondere al \textit{real user id} o al
+\textit{saved user id} della destinazione. Fa eccezione il caso in cui il
+segnale inviato sia \macro{SIGCONT}, nel quale occorre che entrambi i processi
+appartengano alla stessa sessione. Inoltre, dato il ruolo fondamentale che
+riveste nel sistema (si ricordi quanto visto in \secref{sec:sig_termination}),
+non è possibile inviare al processo 1 (cioè a \cmd{init}) segnali per i quali
+esso non abbia un manipolatore installato.
+
+Infine, seguendo le specifiche POSIX 1003.1-2001, l'uso della chiamata
+\code{kill(-1, sig)} comporta che il segnale sia inviato (con la solita
+eccezione di \cmd{init}) a tutti i processi per i quali i permessi lo
+consentano. Lo standard permette comunque alle varie implementazione di
+escludere alcuni processi specifici: nel caso in questione Linux non invia il
+segnale al processo che ha effettuato la chiamata.
+
+
+\subsection{Le funzioni \func{alarm} e \func{abort}}
+\label{sec:sig_alarm_abort}
+
+Un caso particolare di segnali generati a richiesta è quello che riguarda i
+segnali di temporizzazione e e \macro{SIGABORT}, per i quali sono previste
+funzioni specifiche che ne effettuino l'invio. La prima di queste è
+\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.
+  
+  \bodydesc{La funzione restituisce il numero di secondi rimanenti ad un
+    precedente allarme, o zero se non c'erano allarmi pendenti.}
+\end{prototype}
 
-\subsection{Le funzioni \func{alarm} e \func{pause}}
-\label{sec:sig_alarm_pause}
+La funzione provvede 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 si un segnale di
+\macro{SIGALARM} dopo il numero di secondi specificato da \param{seconds}.
+Chiaramente la precisione è determinata da quella dell'orologio di sistema, e
+sono sempre possibili ritardi in caso di un sistema eccessivamente carico.
+
+Se si specifica per \param{seconds} un valore nullo non verrà inviato nessun
+segnale; siccome alla chiamata viene cancellato ogni precedente allarme,
+questo può essere usato per cancellare una programmazione precedente. La
+funzione inoltre ritorna il numero di secondi rimanenti all'invio dell'allarme
+precedentemente programmato, in modo che sia eventualmente possibile
+effettuare delle scelte in caso di necessità di più interruzioni.
+
+In \secref{sec:sys_unix_time} abbiamo visto che ad ogni processo sono
+associati tre tempi diversi: \textit{clock time}, \textit{user time} e
+\textit{system time}.  Per poterli calcolare il kernel mantiene tre diversi
+timer per ciascun processo:
+\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}.
+\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}.
+\item un \textit{profiling timer} che calcola la somma dei tempi di processore
+  utilizzati direttamente dal processo in user space, e dal kernel nelle
+  system call ad esso relative (che corrisponde a quello che in
+  \secref{sec:sys_unix_time} abbiamo chiamato \textit{CPU time}). La scadenza
+  di questo timer provoca l'emissione di \macro{SIGPROF}.
+\end{itemize}
+
+Il timer usato da \func{alarm} è il \textit{clock time}, e corrisponde cioè al
+tempo reale.  Dato che \func{alarm} non consente di usare gli altri timer, e
+non può specificare intervalli con precisione maggiore al secondo le
+\acr{glibc} provvedono la funzione \func{setitimer} che permette un controllo
+completo, a scapito di un uso molto più complesso. Il suo prototipo è:
+\begin{prototype}{sys/time.h}{int setitimer(int which, const struct
+    itimerval *value, struct itimerval *ovalue)} 
+  
+  Predispone l'invio di un segnale di allarme alla scadenza dell'intervallo
+  \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
+    \macro{EFAULT}.}
+\end{prototype}
 
+Il valore di \param{which} permette di specificare quale dei tre timer usare;
+i possibili valori sono riportati in \tabref{tab:sig_setitimer_values}.
+
+\begin{table}[htb]
+  \centering
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore} & \textbf{Timer} \\
+    \hline
+    \hline
+    \macro{ITIMER\_REAL}    & \textit{real-time timer}\\
+    \macro{ITIMER\_VIRTUAL} & \textit{virtual timer}\\
+    \macro{ITIMER\_PROF}    & \textit{profiling timer}\\
+    \hline
+  \end{tabular}
+  \caption{Valori dell'argomento \param{which} per la funzione
+    \func{setitimer}.}
+  \label{tab:sig_setitimer_values}
+\end{table}
+
+
+\subsection{Le funzioni \func{pause} e \func{sleep}}
+\label{sec:sig_pause_sleep}
+
+
+
+
+
+\subsection{Le semantiche di \macro{SIGCHLD}}
+\label{sec:sig_sigchld}
 
-\subsection{Funzioni rientranti e default dei segnali}
-\label{sec:sig_reentrant}
 
 
 
@@ -1016,6 +1141,9 @@ il segnale e pu
 
 
 
+\subsection{Funzioni rientranti e default dei segnali}
+\label{sec:sig_reentrant}
+
 
 , affrontando inoltre le varie problematiche di programmazione che si devono
 tenere presenti quando si ha a che fare con essi.