La differenza che si ha nei due processi è che nel processo padre il valore di
ritorno della funzione fork è il \acr{pid} del processo figlio, mentre nel
figlio è zero; in questo modo il programma può identificare se viene eseguito
-dal padre o dal figlio.
-Si noti come la funzione \func{fork} ritorni \textbf{due} volte: una nel padre
-e una nel figlio. La sola differenza che si ha nei due processi è il valore di
-ritorno restituito dalla funzione, che nel padre è il \acr{pid} del figlio
-mentre nel figlio è zero; in questo modo il programma può identificare se
-viene eseguito dal padre o dal figlio.
+dal padre o dal figlio. Si noti come la funzione \func{fork} ritorni
+\textbf{due} volte: una nel padre e una nel figlio. La sola differenza che si
+ha nei due processi è il valore di ritorno restituito dalla funzione, che nel
+padre è il \acr{pid} del figlio mentre nel figlio è zero; in questo modo il
+programma può identificare se viene eseguito dal padre o dal figlio.
La scelta di questi valori non è casuale, un processo infatti può avere più
figli, ed il valore di ritorno di \func{fork} è l'unico modo che permette di
verrà scartata e la terminazione potrà dirsi completamente conclusa.
Possiamo utilizzare il nostro programma di prova per analizzare anche questa
-condizione: lanciamo il comando \cmd{forktest -e10 3 &} in background,
+condizione: lanciamo il comando \cmd{forktest -e10 3 \&} in background,
indicando al processo padre di aspettare 10 secondi prima di uscire; in questo
caso, usando \cmd{ps} sullo stesso terminale (prima dello scadere dei 10
secondi) otterremo:
\subsection{Le funzioni \texttt{wait} e \texttt{waitpid}}
\label{sec:proc_wait}
-Come accennato la funzioni che permettono di leggere lo stato di uscita di un
-processo, e di completarne il processo di terminazione sono \func{wait} e
-\func{waitpid}, il loro prototipo è:
+Abbiamo già visto in precedenza come uno degli usi possibili delle capacità
+multitasking di un sistema unix-like consiste nella creazione di programmi di
+tipo server, in cui un processo principale attende le richieste che vengono
+poi soddisfatte creando una serie di processi figli. Si è gia sottolineato
+come in questo caso diventi necessario gestire esplicitamente la conclusione
+dei vari processi figli; le funzioni deputate a questo sono sostanzialmente
+due, \func{wait} e \func{waitpid}. La prima, il cui prototipo è:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/wait.h}
\funcdecl{pid\_t wait(int * status)}
-\funcdecl{pid\_t waitpid(pid\_t pid, int *status, int options)}
+
+Sospende il processo corrente finché un figlio non è uscito, o finché un
+segnale termina il processo o chiama una funzione di gestione. Se un figlio è
+già uscito la funzione ritorna immediatamente. Al ritorno lo stato di
+termininazione del processo viene salvato nella variabile puntata da
+\var{status} e tutte le informazioni relative al processo (vedi
+\secref{sec:proc_termination}) vengono rilasciate.
+
+La funzione restituisce il \acr{pid} del figlio in caso di successo e -1 in
+caso di errore; \var{errno} può assumere i valori:
+ \begin{errlist}
+ \item \macro{EINTR} la funzione è stata interrotta da un segnale.
+ \end{errlist}
+\end{functions}
+è presente fin dalle prime versioni di unix; la funzione ritorna alla
+conclusione del primo figlio (o immediatamente se un figlio è già uscito), nel
+caso un processo abbia più figli il valore di ritorno permette di identificare
+qual'è quello che è uscito.
+
+Questa funzione però ha il difetto di essere poco flessibile, in quanto
+ritorna all'uscita di un figlio qualunque, per cui se si vuole attendere la
+conclusione di un processo specifico occorre predisporre un meccanismo che
+tenga conto dei processi già terminati, e ripeta la chiamata alla funzione nel
+caso il processo cercato sia ancora attivo.
+
+Per questo motivo lo standard Posix.1 ha introdotto \func{waitpid} che
+effettua lo stesso servizio, ma dispone di una serie di funzionalità più
+ampie; il suo prototipo è:
+\begin{functions}
+\headdecl{sys/types.h}
+\headdecl{sys/wait.h}
+\funcdecl{pid\_t waitpid(pid\_t pid, int * status, int options)}
+
+La funzione restituisce il \acr{pid} del figlio che è uscito, 0 se è stata
+specificata l'opzione \macro{WNOHANG} e il figlio non è uscito e -1 per un
+errore, nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item \macro{EINTR} non è stata specificata l'opzione \macro{WNOHANG} e la
+ funzione è stata interrotta da un segnale.
+ \item \macro{ECHILD} il processo specificato da \var{pid} non esiste o non è
+ figlio del processo chiamante.
+ \end{errlist}
\end{functions}
+Le differenze principali fra le due funzioni sono che \func{wait} si blocca
+sempre fino a che un figlio non termina, mentre \func{waitpid} ha la
+possibilità si specificare un'opzione, \macro{WNOHANG} che ne previene il
+blocco, inoltre \func{waitpid} può specificare quale figlio attendere sulla
+base del valore soecificato tramite la variabile \var{pid} secondo lo
+specchietto riportato in \ntab:
+\begin{table}[!htb]
+ \centering
+ \begin{tabular}[c]{|c|p{10cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato}\\
+ \hline
+ \hline
+ -1 & attende per un figlio qualsiasi, equivalente a \func{wait}\\
+ > 0 & \\
+ 0 & \\
+ < -1& \\
+ \hline
+ \end{tabular}
+ \caption{Significato del parametro \var{pid} della funzione \func{waitpid}.}
+ \label{tab:proc_waidpid_pid}
+\end{table}
+
+
Come abbiamo appena visto una delle azioni prese dal kernel alla terminazione
di un processo è quella di salvarne lo stato e mandare un segnale di