Finita signal, iniziate kill e raise
[gapil.git] / signal.tex
index aafb4ecebfd83541240c676c89f5f59970ec2dec..aad92a9a6ff9ac9e9a3310f0888d2e0f3403ddd5 100644 (file)
@@ -830,6 +830,11 @@ dei casi in cui si presenta questa situazione 
   per una una risposta. 
 \item operazioni eseguite con \func{ioctl} che non è detto possano essere
   eseguite immediatamente.
   per una una risposta. 
 \item 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.
+\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*}
 
 In questo caso si pone il problema di cosa fare una volta che il manipolatore
 \end{itemize*}
 
 In questo caso si pone il problema di cosa fare una volta che il manipolatore
@@ -839,8 +844,23 @@ tutt'oggi una scelta corrente, ma comporta che i programmi che usano dei
 manipolatori controllino lo stato di uscita delle funzioni per ripeterne la
 chiamata qualora l'errore fosse questo.
 
 manipolatori controllino lo stato di uscita delle funzioni per ripeterne la
 chiamata qualora l'errore fosse questo.
 
-Dato che dimenticarsi di richiamare una funzione interrotta è un errore comune 
+Dimenticarsi di richiamare una system call interrotta da un segnale è un
+errore comune, tanto che le \acr{glibc} provvedono una macro
+\code{TEMP\_FAILURE\_RETRY(expr)} che esegue l'operazione automaticamente,
+ripetendo l'esecuzione dell'espressione \var{expr} fintanto che il risultato
+non è diverso dall'uscita con un errore \macro{EINTR}.
 
 
+La soluzione è comunque poco elegante e BSD ha scelto un approccio molto
+diverso, che è quello di fare ripartire automaticamente la system call invece
+di farla fallire. In questo caso ovviamente non c'è da preoccuparsi di
+controllare il codice di errore; si perde però la possibilità di eseguire
+azioni specifiche all'occorrenza di questa particolare condizione. 
+
+Linux e le \acr{glibc} consentono di utilizzare entrambi gli approcci,
+attraverso una opportuna opzione di \func{sigaction} (vedi
+\secref{sec:sig_sigaction}). È da chiarire comunque che nel caso di
+interruzione nel mezzo di un trasferimento parziale di dati, le system call
+ritornano sempre indicando i byte trasferiti.
 
 
 \subsection{La funzione \func{signal}}
 
 
 \subsection{La funzione \func{signal}}
@@ -865,7 +885,7 @@ comportamento, pur mantenendone immutato il prototipo\footnote{in realt
 \end{prototype}
 
 In questa definizione si è usato il tipo \type{sighandler\_t} che è una
 \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
+estensione GNU, definita dalle \acr{glibc}, che permette di riscrivere il
 prototipo in una forma più leggibile dell'originario:
 \begin{verbatim}
 void (*signal(int signum, void (*handler)(int)))int)
 prototipo in una forma più leggibile dell'originario:
 \begin{verbatim}
 void (*signal(int signum, void (*handler)(int)))int)
@@ -895,21 +915,92 @@ installare l'azione di di default\footnote{si ricordi per
   \macro{SIGKILL} e \macro{SIGSTOP} non possono essere ignorati né
   intercettati}.
 
   \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}.
 
 
-
-\subsection{Funzioni rientranti e default dei segnali}
-\label{sec:sig_reentrant}
-
+È 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
+un ciclo infinito.
 
 
 \subsection{Le funzioni \func{kill} e \func{raise}}
 \label{sec:sig_kill_raise}
 
 
 
 \subsection{Le funzioni \func{kill} e \func{raise}}
 \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:
+\begin{functions}
+  \headdecl{sys/types.h}
+  \headdecl{signal.h}
+  \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}
+  \item[\macro{EINVAL}] Si è specificato un numero di segnale invalido.
+  \item[\macro{EPERM}] Il processo non ha il permesso di inviare il segnale
+  alla destinazione specificata.
+  \item[\macro{ESRCH}] Il \acr{pid} o il process group indicati non
+  esistono. Gli zombie (vedi \ref{sec:proc_termination}) sono considerati come
+  processi esistenti.
+  \end{errlist}}
+\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}. 
+
+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
+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}}
+\item[$\texttt{pid}>0$] il segnale è mandato al processo con il \acr{pid}
+  indicato.
+\item[$\texttt{pid}=0$] il segnale è mandato ad ogni processo del
+  \textit{process group} del chiamante.
+\item[$\texttt{pid}=-1$] il segnale è mandato ad ogni processo (eccetto
+  \cmd{init}).
+\item[$\texttt{pid}<-1$] il segnale è mandato ad ogni processo del process
+  group $|\code{pid}|$.
+\end{basedescript}
+
+
 \subsection{Le funzioni \func{alarm} e \func{pause}}
 \label{sec:sig_alarm_pause}
 
 
 \subsection{Le funzioni \func{alarm} e \func{pause}}
 \label{sec:sig_alarm_pause}
 
 
-\section{Il controllo dei segnali}
+\subsection{Funzioni rientranti e default dei segnali}
+\label{sec:sig_reentrant}
+
+
+
+\section{Gestione avanzata}
 \label{sec:sig_control}
 
 
 \label{sec:sig_control}