Aggiornamento anno note di copyright, dimenticato da gennaio...
[gapil.git] / prochand.tex
index 960a88f66625a99c3436d142727a0905a59f7fba..9f7b0d937a132cad4f443deb521e463a2e2e00d3 100644 (file)
@@ -1,6 +1,6 @@
 %% prochand.tex
 %%
-%% Copyright (C) 2000-2007 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2008 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -44,8 +44,8 @@ caratteristiche di Unix (che esamineremo in dettaglio pi
 qualunque processo può a sua volta generarne altri, detti processi figli
 (\textit{child process}). Ogni processo è identificato presso il sistema da un
 numero univoco, il cosiddetto \textit{process identifier} o, più brevemente,
-\acr{pid}, assegnato in forma progressiva (vedi sez.~\ref{sec:proc_pid}) quando
-il processo viene creato.
+\acr{pid}, assegnato in forma progressiva (vedi sez.~\ref{sec:proc_pid})
+quando il processo viene creato.
 
 Una seconda caratteristica di un sistema Unix è che la generazione di un
 processo è un'operazione separata rispetto al lancio di un programma. In
@@ -138,7 +138,7 @@ fig.~\ref{fig:proc_task_struct}.
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=13cm]{img/task_struct}
+  \includegraphics[width=12cm]{img/task_struct}
   \caption{Schema semplificato dell'architettura delle strutture usate dal
     kernel nella gestione dei processi.}
   \label{fig:proc_task_struct}
@@ -150,15 +150,24 @@ eseguito ad ogni system call ed ad ogni interrupt,\footnote{pi
   di altre occasioni.}
 % TODO completare questa parte su quando viene chiamato lo scheduler.
 (ma può essere anche attivato esplicitamente). Il timer di sistema provvede
-comunque a che esso sia invocato periodicamente, generando un interrupt
-periodico secondo la frequenza specificata dalla costante \const{HZ}, definita
-in \file{asm/param.h}, ed il cui valore è espresso in Hertz.\footnote{Fino al
-  kernel 2.4 il valore usuale di questa costante era 100, per tutte le
-  architetture eccetto l'alpha, per la quale era 1000. Occorre fare attenzione
-  a non confondere questo valore con quello dei clock tick (vedi
-  sez.~\ref{sec:sys_unix_time}).}
-% TODO verificare gli ultimi cambiamenti del 2.6
-% Si ha cioè un interrupt dal timer ogni centesimo di secondo.
+comunque a che esso sia invocato periodicamente; generando un interrupt
+periodico secondo la frequenza specificata dalla costante
+\const{HZ},\footnote{fino al kernel 2.4 il valore usuale di questa costante
+  era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000,
+  nel 2.6 è stato portato a 1000 su tutte le architetture; occorre fare
+  attenzione a non confondere questo valore con quello dei
+  \itindex{clock~tick} \textit{clock tick} (vedi
+  sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui
+valore è espresso in Hertz.\footnote{a partire dal kernel 2.6.21 è stato
+  introdotto (a cura di Ingo Molnar) un meccanismo completamente diverso,
+  detto \textit{tickless}, in cui non c'è più una interruzione periodica con
+  frequenza prefissata, ma ad ogni chiamata del time viene programmata
+  l'interruzione successiva sulla base di una stima; in questo modo si evita
+  di dover eseguire un migliaio di interruzioni al secondo anche su macchine
+  che non stanno facendo nulla, con un forte risparmio nell'uso dell'energia
+  da parte del processore che può essere messo in stato di sospensione anche
+  per lunghi periodi di tempo.}
+
 
 Ogni volta che viene eseguito, lo \itindex{scheduler} \textit{scheduler}
 effettua il calcolo delle priorità dei vari processi attivi (torneremo su
@@ -185,9 +194,9 @@ abbastanza limitata sulle cause della terminazione del processo figlio.
 Quando un processo ha concluso il suo compito o ha incontrato un errore non
 risolvibile esso può essere terminato con la funzione \func{exit} (si veda
 quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però
-termina solo quando la notifica della sua conclusione viene ricevuta dal
-processo padre, a quel punto tutte le risorse allocate nel sistema ad esso
-associate vengono rilasciate.
+termina completamente solo quando la notifica della sua conclusione viene
+ricevuta dal processo padre, a quel punto tutte le risorse allocate nel
+sistema ad esso associate vengono rilasciate.
 
 Avere due processi che eseguono esattamente lo stesso codice non è molto
 utile, normalmente si genera un secondo processo per affidargli l'esecuzione
@@ -209,7 +218,6 @@ prima ritorna due volte (nel processo padre e nel figlio) mentre la seconda
 non ritorna mai (in quanto con essa viene eseguito un altro programma).
 
 
-
 \section{Le funzioni di base}% della gestione dei processi}
 \label{sec:proc_handling}
 
@@ -240,11 +248,13 @@ massimo di 32768.  Oltre questo valore l'assegnazione riparte dal numero pi
 basso disponibile a partire da un minimo di 300,\footnote{questi valori, fino
   al kernel 2.4.x, sono definiti dalla macro \const{PID\_MAX} in
   \file{threads.h} e direttamente in \file{fork.c}, con il kernel 2.5.x e la
-  nuova interfaccia per i thread creata da Ingo Molnar anche il meccanismo di
-  allocazione dei \acr{pid} è stato modificato.} che serve a riservare i
-\acr{pid} più bassi ai processi eseguiti direttamente dal kernel.  Per questo
-motivo, come visto in sez.~\ref{sec:proc_hierarchy}, il processo di avvio
-(\cmd{init}) ha sempre il \acr{pid} uguale a uno.
+  nuova interfaccia per i \itindex{thread} \textit{thread} creata da Ingo
+  Molnar anche il meccanismo di allocazione dei \acr{pid} è stato modificato;
+  il valore massimo è impostabile attraverso il file
+  \procfile{/proc/sys/kernel/pid\_max} e di default vale 32768.} che serve a
+riservare i \acr{pid} più bassi ai processi eseguiti direttamente dal kernel.
+Per questo motivo, come visto in sez.~\ref{sec:proc_hierarchy}, il processo di
+avvio (\cmd{init}) ha sempre il \acr{pid} uguale a uno.
 
 Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
 sono stati creati, questo viene chiamato in genere \acr{ppid} (da
@@ -291,7 +301,7 @@ dell'identit
 affrontato in dettaglio in sez.~\ref{sec:proc_perms}.
 
 
-\subsection{La funzione \func{fork}}
+\subsection{La funzione \func{fork} e le funzioni di creazione dei processi}
 \label{sec:proc_fork}
 
 La funzione \funcd{fork} è la funzione fondamentale della gestione dei
@@ -321,7 +331,7 @@ Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
 il processo figlio continuano ad essere eseguiti normalmente a partire
 dall'istruzione successiva alla \func{fork}; il processo figlio è però una
 copia del padre, e riceve una copia dei \index{segmento!testo} segmenti di
-testo, \itindex{stack} stack e \index{segmento!dati} dati (vedi
+testo, \itindex{stack} \textit{stack} e \index{segmento!dati} dati (vedi
 sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo stesso codice del
 padre. Si tenga presente però che la memoria è copiata, non condivisa,
 pertanto padre e figlio vedono variabili diverse.
@@ -422,9 +432,7 @@ Se eseguiamo il comando\footnote{che 
 senza specificare attese (come si può notare in (\texttt{\small 17--19}) i
 valori predefiniti specificano di non attendere), otterremo come output sul
 terminale:
-
-\footnotesize
-\begin{verbatim}
+\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm,xrightmargin=1.5cm]
 [piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3
 Process 1963: forking 3 child
 Spawned 1 child, pid 1964 
@@ -439,21 +447,18 @@ Child 3 successfully executing
 Child 3, parent 1963, exiting
 Spawned 3 child, pid 1966 
 Go to next child 
-\end{verbatim} %$
-\normalsize
+\end{Verbatim} 
+%$
 
 Esaminiamo questo risultato: una prima conclusione che si può trarre è che non
-si può dire quale processo fra il padre ed il figlio venga eseguito per
-primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo
-  \itindex{scheduler} \textit{scheduler} di Ingo Molnar che esegue sempre per
-  primo il figlio; per mantenere la portabilità è opportuno non fare comunque
-  affidamento su questo comportamento.} dopo la chiamata a \func{fork};
-dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito
-per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi
-passare all'esecuzione del figlio (completata con i due avvisi di esecuzione
-ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al
-ciclo successivo), mentre la terza volta è stato prima eseguito il figlio
-(fino alla conclusione) e poi il padre.
+si può dire quale processo fra il padre ed il figlio venga eseguito per primo
+dopo la chiamata a \func{fork}; dall'esempio si può notare infatti come nei
+primi due cicli sia stato eseguito per primo il padre (con la stampa del
+\acr{pid} del nuovo processo) per poi passare all'esecuzione del figlio
+(completata con i due avvisi di esecuzione ed uscita), e tornare
+all'esecuzione del padre (con la stampa del passaggio al ciclo successivo),
+mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione)
+e poi il padre.
 
 In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
 \itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione
@@ -470,6 +475,24 @@ occorrer
 rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race
   condition} (vedi sez.~\ref{sec:proc_race_cond}).
 
+In realtà a partire dal kernel 2.5.2-pre10 il nuovo \itindex{scheduler}
+\textit{scheduler} di Ingo Molnar esegue sempre per primo il
+figlio;\footnote{i risultati precedenti sono stati ottenuti usando un kernel
+  della serie 2.4.}  questa è una ottimizzazione che serve a evitare che il
+padre, effettuando per primo una operazione di scrittura in memoria, attivi il
+meccanismo del \itindex{copy~on~write} \textit{copy on write}. Questa
+operazione infatti potrebbe risultare del tutto inutile qualora il figlio
+fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si
+invocherebbe un altro programma scartando completamente lo spazio degli
+indirizzi, rendendo superflua la copia della memoria modificata dal padre.
+
+Eseguendo sempre per primo il figlio la \func{exec} verrebbe effettuata subito
+avendo così la certezza che il \itindex{copy~on~write} \textit{copy on write}
+viene utilizzato solo quando necessario. Quanto detto in precedenza vale
+allora soltanto per i kernel fino al 2.4; per mantenere la portabilità è però
+opportuno non fare affidamento su questo comportamento, che non si riscontra
+in altri Unix e nelle versioni del kernel precendenti a quella indicata.
+
 Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
 processi completamente separati, le modifiche delle variabili nei processi
 figli (come l'incremento di \var{i} in \texttt{\small 31}) sono visibili solo
@@ -481,9 +504,7 @@ Un secondo aspetto molto importante nella creazione dei processi figli 
 quello dell'interazione dei vari processi con i file; per illustrarlo meglio
 proviamo a redirigere su un file l'output del nostro programma di test, quello
 che otterremo è:
-
-\footnotesize
-\begin{verbatim}
+\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm,xrightmargin=1.5cm]
 [piccardi@selidor sources]$ ./forktest 3 > output
 [piccardi@selidor sources]$ cat output
 Process 1967: forking 3 child
@@ -508,8 +529,7 @@ Spawned 2 child, pid 1969
 Go to next child 
 Spawned 3 child, pid 1970 
 Go to next child 
-\end{verbatim}
-\normalsize
+\end{Verbatim}
 che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
@@ -529,7 +549,7 @@ ogni figlio riceve una copia della memoria del padre, esso ricever
 quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal
 padre fino allora. Così quando il buffer viene scritto su disco all'uscita del
 figlio, troveremo nel file anche tutto quello che il processo padre aveva
-scritto prima della sua creazione.  E alla fine del file (dato che in questo
+scritto prima della sua creazione. E alla fine del file (dato che in questo
 caso il padre esce per ultimo) troveremo anche l'output completo del padre.
 
 L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
@@ -540,14 +560,15 @@ sez.~\ref{sec:file_sharing}), ma anche che, a differenza di quanto avviene per
 le variabili, la posizione corrente sul file è condivisa fra il padre e tutti
 i processi figli.
 
-Quello che succede è che quando lo standard output del padre viene rediretto,
-lo stesso avviene anche per tutti i figli; la funzione \func{fork} infatti ha
-la caratteristica di duplicare nei figli tutti i file descriptor aperti nel
-padre (allo stesso modo in cui lo fa la funzione \func{dup}, trattata in
-sez.~\ref{sec:file_dup}), il che comporta che padre e figli condividono le
-stesse voci della \itindex{file~table} \textit{file table} (per la spiegazione
-di questi termini si veda sez.~\ref{sec:file_sharing}) fra cui c'è anche la
-posizione corrente nel file.
+Quello che succede è che quando lo standard output del padre viene rediretto
+come si è fatto nell'esempio, lo stesso avviene anche per tutti i figli; la
+funzione \func{fork} infatti ha la caratteristica di duplicare nei processi
+figli tutti i file descriptor aperti nel processo padre (allo stesso modo in
+cui lo fa la funzione \func{dup}, trattata in sez.~\ref{sec:file_dup}), il che
+comporta che padre e figli condividono le stesse voci della
+\itindex{file~table} \textit{file table} (per la spiegazione di questi termini
+si veda sez.~\ref{sec:file_sharing}) fra cui c'è anche la posizione corrente
+nel file.
 
 In questo modo se un processo scrive sul file aggiornerà la posizione corrente
 sulla \itindex{file~table} \textit{file table}, e tutti gli altri processi,
@@ -559,21 +580,20 @@ mescolato, ma non ci saranno parti perdute per via di una sovrascrittura.
 
 Questo tipo di comportamento è essenziale in tutti quei casi in cui il padre
 crea un figlio e attende la sua conclusione per proseguire, ed entrambi
-scrivono sullo stesso file (un caso tipico è la shell quando lancia un
-programma, il cui output va sullo standard output). 
-
-In questo modo, anche se l'output viene rediretto, il padre potrà sempre
-continuare a scrivere in coda a quanto scritto dal figlio in maniera
-automatica; se così non fosse ottenere questo comportamento sarebbe
-estremamente complesso necessitando di una qualche forma di comunicazione fra
-i due processi per far riprendere al padre la scrittura al punto giusto.
+scrivono sullo stesso file; un caso tipico è la shell quando lancia un
+programma, il cui output va sullo standard output.  In questo modo, anche se
+l'output viene rediretto, il padre potrà sempre continuare a scrivere in coda
+a quanto scritto dal figlio in maniera automatica; se così non fosse ottenere
+questo comportamento sarebbe estremamente complesso necessitando di una
+qualche forma di comunicazione fra i due processi per far riprendere al padre
+la scrittura al punto giusto.
 
 In generale comunque non è buona norma far scrivere più processi sullo stesso
 file senza una qualche forma di sincronizzazione in quanto, come visto anche
 con il nostro esempio, le varie scritture risulteranno mescolate fra loro in
 una sequenza impredicibile. Per questo le modalità con cui in genere si usano
 i file dopo una \func{fork} sono sostanzialmente due:
-\begin{enumerate*}
+\begin{enumerate}
 \item Il processo padre aspetta la conclusione del figlio. In questo caso non
   è necessaria nessuna azione riguardo ai file, in quanto la sincronizzazione
   della posizione corrente dopo eventuali operazioni di lettura e scrittura
@@ -581,7 +601,7 @@ i file dopo una \func{fork} sono sostanzialmente due:
 \item L'esecuzione di padre e figlio procede indipendentemente. In questo caso
   ciascuno dei due processi deve chiudere i file che non gli servono una volta
   che la \func{fork} è stata eseguita, per evitare ogni forma di interferenza.
-\end{enumerate*}
+\end{enumerate}
 
 Oltre ai file aperti i processi figli ereditano dal padre una serie di altre
 proprietà; la lista dettagliata delle proprietà che padre e figlio hanno in
@@ -607,7 +627,7 @@ comune dopo l'esecuzione di una \func{fork} 
   sez.~\ref{sec:ipc_sysv_shm});
 \item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
 \item le priorità real-time e le affinità di processore (vedi
-  sez.~\ref{sec:proc_real_time});
+  sez.~\ref{sec:proc_real_time} e sez.\ref{sec:proc_sched_multiprocess});
 \item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}).
 \end{itemize*}
 Le differenze fra padre e figlio dopo la \func{fork} invece sono:
@@ -625,10 +645,8 @@ Le differenze fra padre e figlio dopo la \func{fork} invece sono:
 \end{itemize*}
 
 
-\subsection{La funzione \func{vfork}}
-\label{sec:proc_vfork}
-
-La funzione \func{vfork} è esattamente identica a \func{fork} ed ha la stessa
+Una seconda funzione storica usata per la creazione di un nuovo processo è
+\func{vfork}, che è esattamente identica a \func{fork} ed ha la stessa
 semantica e gli stessi errori; la sola differenza è che non viene creata la
 tabella delle pagine né la struttura dei task per il nuovo processo. Il
 processo padre è posto in attesa fintanto che il figlio non ha eseguito una
@@ -666,15 +684,15 @@ terminazione del processo da parte del kernel).
 Ma abbiamo accennato che oltre alla conclusione normale esistono anche delle
 modalità di conclusione anomala; queste sono in sostanza due: il programma può
 chiamare la funzione \func{abort} per invocare una chiusura anomala, o essere
-terminato da un segnale.  In realtà anche la prima modalità si riconduce alla
-seconda, dato che \func{abort} si limita a generare il segnale
-\const{SIGABRT}.
+terminato da un segnale (torneremo sui segnali in cap.~\ref{cha:signals}).  In
+realtà anche la prima modalità si riconduce alla seconda, dato che
+\func{abort} si limita a generare il segnale \const{SIGABRT}.
 
 Qualunque sia la modalità di conclusione di un processo, il kernel esegue
 comunque una serie di operazioni: chiude tutti i file aperti, rilascia la
 memoria che stava usando, e così via; l'elenco completo delle operazioni
 eseguite alla chiusura di un processo è il seguente:
-\begin{itemize*}
+\begin{itemize}
 \item tutti i file descriptor sono chiusi;
 \item viene memorizzato lo stato di terminazione del processo;
 \item ad ogni processo figlio viene assegnato un nuovo padre (in genere
@@ -689,7 +707,7 @@ eseguite alla chiusura di un processo 
     group} ciascun membro del gruppo viene bloccato, e poi gli vengono
   inviati in successione i segnali \const{SIGHUP} e \const{SIGCONT}
   (vedi ancora sez.~\ref{sec:sess_ctrl_term}).
-\end{itemize*}
+\end{itemize}
 
 Oltre queste operazioni è però necessario poter disporre di un meccanismo
 ulteriore che consenta di sapere come la terminazione è avvenuta: dato che in
@@ -720,6 +738,8 @@ che sia cos
 terminato (si potrebbe avere cioè quello che si chiama un processo
 \textsl{orfano}). 
 
+% TODO verificare il reparenting
+
 Questa complicazione viene superata facendo in modo che il processo orfano
 venga \textsl{adottato} da \cmd{init}. Come già accennato quando un processo
 termina, il kernel controlla se è il padre di altri processi in esecuzione: in
@@ -729,9 +749,7 @@ avr
 cui riportare il suo stato di terminazione.  Come verifica di questo
 comportamento possiamo eseguire il nostro programma \cmd{forktest} imponendo a
 ciascun processo figlio due secondi di attesa prima di uscire, il risultato è:
-
-\footnotesize
-\begin{verbatim}
+\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm,xrightmargin=1.5cm]
 [piccardi@selidor sources]$ ./forktest -c2 3
 Process 1972: forking 3 child
 Spawned 1 child, pid 1973 
@@ -746,8 +764,7 @@ Go to next child
 [piccardi@selidor sources]$ Child 3, parent 1, exiting
 Child 2, parent 1, exiting
 Child 1, parent 1, exiting
-\end{verbatim}
-\normalsize
+\end{Verbatim}
 come si può notare in questo caso il processo padre si conclude prima dei
 figli, tornando alla shell, che stampa il prompt sul terminale: circa due
 secondi dopo viene stampato a video anche l'output dei tre figli che
@@ -777,9 +794,7 @@ condizione: lanciamo il comando \cmd{forktest} in \textit{background} (vedi
 sez.~\ref{sec:sess_job_control}), 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:
-
-\footnotesize
-\begin{verbatim}
+\begin{Verbatim}[fontsize=\footnotesize,xleftmargin=1cm,xrightmargin=1.5cm]
 [piccardi@selidor sources]$ ps T
   PID TTY      STAT   TIME COMMAND
   419 pts/0    S      0:00 bash
@@ -788,8 +803,9 @@ terminale (prima dello scadere dei 10 secondi) otterremo:
   570 pts/0    Z      0:00 [forktest <defunct>]
   571 pts/0    Z      0:00 [forktest <defunct>]
   572 pts/0    R      0:00 ps T
-\end{verbatim} %$
-\normalsize e come si vede, dato che non si è fatto nulla per riceverne lo
+\end{Verbatim} 
+%$
+e come si vede, dato che non si è fatto nulla per riceverne lo
 stato di terminazione, i tre processi figli sono ancora presenti pur essendosi
 conclusi, con lo stato di \index{zombie} \textit{zombie} e l'indicazione che
 sono stati terminati.
@@ -822,7 +838,8 @@ terminare il processo che li ha generati, in modo che \cmd{init} possa
 adottarli e provvedere a concluderne la terminazione.
 
 
-\subsection{Le funzioni \func{wait} e \func{waitpid}}
+\subsection{La funzione \func{waitpid} e le funzioni di ricezione degli stati
+  di uscita}
 \label{sec:proc_wait}
 
 Uno degli usi più comuni delle capacità multitasking di un sistema unix-like
@@ -831,7 +848,7 @@ principale attende le richieste che vengono poi soddisfatte da una serie di
 processi figli. Si è già sottolineato al paragrafo precedente come in questo
 caso diventi necessario gestire esplicitamente la conclusione dei figli onde
 evitare di riempire di \index{zombie} \textit{zombie} la tabella dei processi;
-le funzioni deputate a questo compito sono sostanzialmente due, \funcd{wait} e
+le funzioni deputate a questo compito sono principalmente due, \funcd{wait} e
 \func{waitpid}. La prima, il cui prototipo è:
 \begin{functions}
 \headdecl{sys/types.h}
@@ -870,8 +887,10 @@ Per questo motivo lo standard POSIX.1 ha introdotto la funzione
 \funcd{waitpid} che effettua lo stesso servizio, ma dispone di una serie di
 funzionalità più ampie, legate anche al controllo di sessione (si veda
 sez.~\ref{sec:sess_job_control}).  Dato che è possibile ottenere lo stesso
-comportamento di \func{wait} si consiglia di utilizzare sempre questa
-funzione, il cui prototipo è:
+comportamento di \func{wait}\footnote{in effetti il codice
+  \code{wait(\&status)} è del tutto equivalente a \code{waitpid(WAIT\_ANY,
+    \&status, 0)}.} si consiglia di utilizzare sempre questa funzione, il cui
+prototipo è:
 \begin{functions}
 \headdecl{sys/types.h}
 \headdecl{sys/wait.h}
@@ -882,38 +901,41 @@ Attende la conclusione di un processo figlio.
   è stata specificata l'opzione \const{WNOHANG} e il processo non è uscito e
   -1 per un errore, nel qual caso \var{errno} assumerà i valori:
   \begin{errlist}
-  \item[\errcode{EINTR}] se non è stata specificata l'opzione \const{WNOHANG} e
+  \item[\errcode{EINTR}] non è stata specificata l'opzione \const{WNOHANG} e
     la funzione è stata interrotta da un segnale.
   \item[\errcode{ECHILD}] il processo specificato da \param{pid} non esiste o
     non è figlio del processo chiamante.
+  \item[\errcode{EINVAL}] si è specificato un valore non valido per
+    l'argomento \param{options}.
   \end{errlist}}
 \end{functions}
 
-Le differenze principali fra le due funzioni sono che \func{wait} si blocca
-sempre fino a che un processo figlio non termina, mentre \func{waitpid} ha la
-possibilità si specificare un'opzione \const{WNOHANG} che ne previene il
-blocco; inoltre \func{waitpid} può specificare in maniera flessibile quale
-processo attendere, sulla base del valore fornito dall'argomento \param{pid},
-secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}.
+La prima differenza fra le due funzioni è che con \func{waitpid} si può
+specificare in maniera flessibile quale processo attendere, sulla base del
+valore fornito dall'argomento \param{pid}, questo può assumere diversi valori,
+secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}, dove si
+sono riportate anche le costanti definite per indicare alcuni di essi.
 
 \begin{table}[!htb]
   \centering
   \footnotesize
   \begin{tabular}[c]{|c|c|p{8cm}|}
     \hline
-    \textbf{Valore} & \textbf{Opzione} &\textbf{Significato}\\
+    \textbf{Valore} & \textbf{Costante} &\textbf{Significato}\\
     \hline
     \hline
-    $<-1$& --               & attende per un figlio il cui
+    $<-1$& --               & Attende per un figlio il cui
                               \itindex{process~group} \textit{process group}
                               (vedi sez.~\ref{sec:sess_proc_group}) è uguale
                               al valore assoluto di \param{pid}. \\ 
-    $-1$& \const{WAIT\_ANY} & attende per un figlio qualsiasi, usata in
-                              questa maniera è equivalente a \func{wait}.\\ 
-    $0$ &\const{WAIT\_MYPGRP}&attende per un figlio il cui
-                              \itindex{process~group} \textit{process group} è
+    $-1$&\const{WAIT\_ANY}  & Attende per un figlio qualsiasi, usata in
+                              questa maniera senza specificare nessuna opzione
+                              è equivalente a \func{wait}.\\ 
+    $ 0$&\const{WAIT\_MYPGRP}&Attende per un figlio il cui
+                              \itindex{process~group} \textit{process group}
+                              (vedi sez.~\ref{sec:sess_proc_group}) è
                               uguale a quello del processo chiamante. \\ 
-    $>0$& --                & attende per un figlio il cui \acr{pid} è uguale
+    $>0$& --                & Attende per un figlio il cui \acr{pid} è uguale
                               al valore di \param{pid}.\\
     \hline
   \end{tabular}
@@ -922,45 +944,124 @@ secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}.
   \label{tab:proc_waidpid_pid}
 \end{table}
 
-Il comportamento di \func{waitpid} può inoltre essere modificato passando
-delle opportune opzioni tramite l'argomento \param{option}. I valori possibili
-sono il già citato \const{WNOHANG}, che previene il blocco della funzione
-quando il processo figlio non è terminato, e \const{WUNTRACED} che permette di
-tracciare i processi bloccati.  Il valore dell'opzione deve essere specificato
-come maschera binaria ottenuta con l'OR delle suddette costanti con zero.
-
-In genere si utilizza \const{WUNTRACED} all'interno del controllo di sessione,
-(l'argomento è trattato in sez.~\ref{sec:sess_job_control}). In tal caso
-infatti la funzione ritorna, restituendone il \acr{pid}, quando c'è un
-processo figlio che è entrato in stato di sleep (vedi
-tab.~\ref{tab:proc_proc_states}) e del quale non si è ancora letto lo stato
-(con questa stessa opzione). In Linux sono previste altre opzioni non standard
-relative al comportamento con i thread, che riprenderemo in
-sez.~\ref{sec:thread_xxx}.
-
-La terminazione di un processo figlio è chiaramente un evento asincrono
-rispetto all'esecuzione di un programma e può avvenire in un qualunque
-momento. Per questo motivo, come accennato nella sezione precedente, una delle
-azioni prese dal kernel alla conclusione di un processo è quella di mandare un
-segnale di \const{SIGCHLD} al padre. L'azione predefinita (si veda
+Il comportamento di \func{waitpid} può inoltre essere modificato passando alla
+funzione delle opportune opzioni tramite l'argomento \param{options}; questo
+deve essere specificato come maschera binaria dei flag riportati in
+tab.~\ref{tab:proc_waitpid_options},\footnote{oltre a queste in Linux sono
+  previste del altre opzioni non standard, relative al comportamento con i
+  \itindex{thread} \textit{thread}, che riprenderemo in
+  sez.~\ref{sec:thread_xxx}.} che possono essere combinati fra loro con un OR
+aritmetico.
+
+L'uso dell'opzione \const{WNOHANG} consente di prevenire il blocco della
+funzione qualora nessun figlio sia uscito (o non si siano verificate le altre
+condizioni per l'uscita della funzione); in tal caso la funzione ritornerà un
+valore nullo anziché positivo.\footnote{anche in questo caso un valore
+  positivo indicherà il \acr{pid} del processo di cui si è ricevuto lo stato
+  ed un valore negativo un errore.}
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Macro} & \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{WNOHANG}   & La funzione ritorna immediatamente anche se non è
+                        terminato nessun processo figlio. \\
+    \const{WUNTRACED} & Ritorna anche se un processo figlio è stato fermato. \\
+    \const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato
+                        fermato ha ripreso l'esecuzione.\footnotemark \\
+    \hline
+  \end{tabular}
+  \caption{Costanti che identificano i bit dell'argomento \param{options}
+    della funzione \func{waitpid}.} 
+  \label{tab:proc_waitpid_options}
+\end{table}
+
+\footnotetext{disponibile solo a partire dal kernel 2.6.10.}
+
+Le altre due opzioni \const{WUNTRACED} e \const{WCONTINUED} consentono
+rispettivamente di tracciare non la terminazione di un processo, ma il fatto
+che esso sia stato fermato, o fatto ripartire, e sono utilizzate per la
+gestione del controllo di sessione (vedi sez.~\ref{sec:sess_job_control}).
+
+Nel caso di \const{WUNTRACED} la funzione ritorna, restituendone il \acr{pid},
+quando un processo figlio entra nello stato \textit{stopped}\footnote{in
+  realtà viene notificato soltanto il caso in cui il processo è stato fermato
+  da un segnale di stop (vedi sez.~\ref{sec:sess_ctrl_term}), e non quello in
+  cui lo stato \textit{stopped} è dovuto all'uso di \func{ptrace} (vedi
+  sez.~\ref{sec:xxx_ptrace}).} (vedi tab.~\ref{tab:proc_proc_states}), mentre
+con \const{WCONTINUED} la funzione ritorna quando un processo in stato
+\textit{stopped} riprende l'esecuzione per la ricezione del segnale
+\const{SIGCONT} (l'uso di questi segnali per il controllo di sessione è
+dettagliato in sez.~\ref{sec:sess_ctrl_term}). 
+
+La terminazione di un processo figlio (così come gli altri eventi osservabili
+con \func{waitpid}) è chiaramente un evento asincrono rispetto all'esecuzione
+di un programma e può avvenire in un qualunque momento. Per questo motivo,
+come accennato nella sezione precedente, una delle azioni prese dal kernel
+alla conclusione di un processo è quella di mandare un segnale di
+\const{SIGCHLD} al padre. L'azione predefinita (si veda
 sez.~\ref{sec:sig_base}) per questo segnale è di essere ignorato, ma la sua
 generazione costituisce il meccanismo di comunicazione asincrona con cui il
 kernel avverte il processo padre che uno dei suoi figli è terminato.
 
-In genere in un programma non si vuole essere forzati ad attendere la
-conclusione di un processo per proseguire, specie se tutto questo serve solo
-per leggerne lo stato di chiusura (ed evitare la presenza di \index{zombie}
-\textit{zombie}), per questo la modalità più usata per chiamare queste
-funzioni è quella di utilizzarle all'interno di un \textit{signal handler}
-(vedremo un esempio di come gestire \const{SIGCHLD} con i segnali in
-sez.~\ref{sec:sig_example}). In questo caso infatti, dato che il segnale è
-generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
-\func{wait} non si bloccherà.
+Il comportamento delle funzioni è però cambiato nel passaggio dal kernel 2.4
+al kernel 2.6, quest'ultimo infatti si è adeguato alle prescrizioni dello
+standard POSIX.1-2001,\footnote{una revisione del 2001 dello standard POSIX.1
+  che ha aggiunto dei requisiti e delle nuove funzioni, come \func{waitid}.}
+e come da esso richiesto se \const{SIGCHLD} viene ignorato, o se si imposta il
+flag di \const{SA\_NOCLDSTOP} nella ricezione dello stesso (si veda
+sez.~\ref{sec:sig_sigaction}) i processi figli che terminano non diventano
+\textit{zombie} e sia \func{wait} che \func{waitpid} si bloccano fintanto che
+tutti i processi figli non sono terminati, dopo di che falliscono con un
+errore di \errcode{ENOCHLD}.\footnote{questo è anche il motivo per cui le
+  opzioni \const{WUNTRACED} e \const{WCONTINUED} sono utilizzabili soltanto
+  qualora non si sia impostato il flag di \const{SA\_NOCLDSTOP} per il segnale
+  \const{SIGCHLD}.}
+
+Con i kernel della serie 2.4 e tutti i kernel delle serie precedenti entrambe
+le funzioni di attesa ignorano questa prescrizione\footnote{lo standard POSIX.1
+  originale infatti lascia indefinito il comportamento di queste funzioni
+  quando \const{SIGCHLD} viene ignorato.} e si comportano sempre nello stesso
+modo, indipendentemente dal fatto \const{SIGCHLD} sia ignorato o meno:
+attendono la terminazione di un processo figlio e ritornano il relativo
+\acr{pid} e lo stato di terminazione nell'argomento \param{status}.
+
+In generale in un programma non si vuole essere forzati ad attendere la
+conclusione di un processo figlio per proseguire l'esecuzione, specie se tutto
+questo serve solo per leggerne lo stato di chiusura (ed evitare eventualmente
+la presenza di \index{zombie} \textit{zombie}). Per questo la modalità più
+comune di chiamare queste funzioni è quella di utilizzarle all'interno di un
+\textit{signal handler} (vedremo un esempio di come gestire \const{SIGCHLD}
+con i segnali in sez.~\ref{sec:sig_example}). In questo caso infatti, dato che
+il segnale è generato dalla terminazione di un figlio, avremo la certezza che
+la chiamata a \func{waitpid} non si bloccherà.
+
+Come accennato sia \func{wait} che \func{waitpid} restituiscono lo stato di
+terminazione del processo tramite il puntatore \param{status} (se non
+interessa memorizzare lo stato si può passare un puntatore nullo). Il valore
+restituito da entrambe le funzioni dipende dall'implementazione, ma
+tradizionalmente alcuni bit (in genere 8) sono riservati per memorizzare lo
+stato di uscita, e altri per indicare il segnale che ha causato la
+terminazione (in caso di conclusione anomala), uno per indicare se è stato
+generato un \itindex{core~dump} \textit{core dump}, ecc.\footnote{le
+  definizioni esatte si possono trovare in \file{<bits/waitstatus.h>} ma
+  questo file non deve mai essere usato direttamente, esso viene incluso
+  attraverso \file{<sys/wait.h>}.}
+
+Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
+analizzare lo stato di uscita. Esse sono definite sempre in
+\file{<sys/wait.h>} ed elencate in tab.~\ref{tab:proc_status_macro} (si tenga
+presente che queste macro prendono come parametro la variabile di tipo
+\ctyp{int} puntata da \param{status}).
 
 \begin{table}[!htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|c|p{10cm}|}
+  \begin{tabular}[c]{|l|p{10cm}|}
     \hline
     \textbf{Macro} & \textbf{Descrizione}\\
     \hline
@@ -970,29 +1071,33 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
     \macro{WEXITSTATUS(s)} & Restituisce gli otto bit meno significativi dello
                              stato di uscita del processo (passato attraverso
                              \func{\_exit}, \func{exit} o come valore di
-                             ritorno di \func{main}). Può essere valutata solo
+                             ritorno di \func{main}); può essere valutata solo
                              se \val{WIFEXITED} ha restituito un valore non
                              nullo.\\ 
-    \macro{WIFSIGNALED(s)} & Vera se il processo figlio è terminato
+    \macro{WIFSIGNALED(s)} & Condizione vera se il processo figlio è terminato
                              in maniera anomala a causa di un segnale che non
                              è stato catturato (vedi
                              sez.~\ref{sec:sig_notification}).\\ 
     \macro{WTERMSIG(s)}    & Restituisce il numero del segnale che ha causato
-                             la terminazione anomala del processo.  Può essere
+                             la terminazione anomala del processo; può essere
                              valutata solo se \val{WIFSIGNALED} ha restituito
                              un valore non nullo.\\ 
     \macro{WCOREDUMP(s)}   & Vera se il processo terminato ha generato un
                              file di \itindex{core~dump} \textit{core
-                               dump}. Può essere valutata solo se
+                               dump}; può essere valutata solo se
                              \val{WIFSIGNALED} ha restituito un valore non
                              nullo.\footnotemark \\
     \macro{WIFSTOPPED(s)}  & Vera se il processo che ha causato il ritorno di
-                             \func{waitpid} è bloccato. L'uso è possibile solo
-                             avendo specificato l'opzione \const{WUNTRACED}. \\
+                             \func{waitpid} è bloccato; l'uso è possibile solo
+                             con \func{waitpid} avendo specificato l'opzione
+                             \const{WUNTRACED}.\\
     \macro{WSTOPSIG(s)}    & Restituisce il numero del segnale che ha bloccato
-                             il processo. Può essere valutata solo se
+                             il processo; può essere valutata solo se
                              \val{WIFSTOPPED} ha restituito un valore non
                              nullo. \\ 
+    \macro{WIFCONTINUED(s)}& Vera se il processo che ha causato il ritorno è
+                             stato riavviato da un
+                             \const{SIGCONT}.\footnotemark  \\ 
     \hline
   \end{tabular}
   \caption{Descrizione delle varie macro di preprocessore utilizzabili per 
@@ -1000,43 +1105,149 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
   \label{tab:proc_status_macro}
 \end{table}
 
-\footnotetext{questa macro non è definita dallo standard POSIX.1, ma è
-    presente come estensione sia in Linux che in altri Unix.}
-
-Entrambe le funzioni di attesa restituiscono lo stato di terminazione del
-processo tramite il puntatore \param{status} (se non interessa memorizzare
-lo stato si può passare un puntatore nullo). Il valore restituito da
-entrambe le funzioni dipende dall'implementazione, e tradizionalmente alcuni
-bit (in genere 8) sono riservati per memorizzare lo stato di uscita, e altri
-per indicare il segnale che ha causato la terminazione (in caso di
-conclusione anomala), uno per indicare se è stato generato un
-\itindex{core~dump} \textit{core dump}, ecc.\footnote{le definizioni esatte
-  si possono trovare in \file{<bits/waitstatus.h>} ma questo file non deve
-  mai essere usato direttamente, esso viene incluso attraverso
-  \file{<sys/wait.h>}.}
+\footnotetext[18]{questa macro non è definita dallo standard POSIX.1-2001, ma è
+  presente come estensione sia in Linux che in altri Unix, deve essere
+  pertanto utilizzata con attenzione (ad esempio è il caso di usarla in un
+  blocco \texttt{\#ifdef WCOREDUMP ... \#endif}.}
 
-Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
-analizzare lo stato di uscita. Esse sono definite sempre in
-\file{<sys/wait.h>} ed elencate in tab.~\ref{tab:proc_status_macro} (si tenga
-presente che queste macro prendono come parametro la variabile di tipo
-\ctyp{int} puntata da \param{status}).
+\footnotetext{è presente solo a partire dal kernel 2.6.10.}
 
 Si tenga conto che nel caso di conclusione anomala il valore restituito da
 \val{WTERMSIG} può essere confrontato con le costanti definite in
 \file{signal.h} ed elencate in tab.~\ref{tab:sig_signal_list}, e stampato
 usando le apposite funzioni trattate in sez.~\ref{sec:sig_strsignal}.
 
+A partire dal kernel 2.6.9, sempre in conformità allo standard POSIX.1-2001, è
+stata introdotta una nuova funzione di attesa che consente di avere un
+controllo molto più preciso sui possibili cambiamenti di stato dei processi
+figli e più dettagli sullo stato di uscita; la funzione è \funcd{waitid} ed il
+suo prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} 
 
-\subsection{Le funzioni \func{wait3} e \func{wait4}}
-\label{sec:proc_wait4}
+  \headdecl{sys/wait.h}
+  
+  \funcdecl{int waitid(idtype\_t idtype, id\_t id, siginfo\_t *infop, int
+    options)}    
+
+  Attende la conclusione di un processo figlio.
 
-Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
-lettura dello stato di terminazione di un processo, analoghe alle precedenti
-ma che prevedono un ulteriore argomento attraverso il quale il kernel può
-restituire al padre informazioni sulle risorse usate dal processo terminato e
-dai vari figli.  Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che
-diventano accessibili definendo la macro \macro{\_USE\_BSD}; i loro prototipi
-sono:
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore,
+    nel qual caso \var{errno} assumerà i valori:
+  \begin{errlist}
+  \item[\errcode{EINTR}] se non è stata specificata l'opzione \const{WNOHANG} e
+    la funzione è stata interrotta da un segnale.
+  \item[\errcode{ECHILD}] il processo specificato da \param{pid} non esiste o
+    non è figlio del processo chiamante.
+  \item[\errcode{EINVAL}] si è specificato un valore non valido per
+    l'argomento \param{options}.
+  \end{errlist}}
+\end{functions}
+
+La funzione prevede che si specifichi quali processi si intendono osservare
+usando i due argomenti \param{idtype} ed \param{id}; il primo indica se si
+vuole porsi in attesa su un singolo processo, un gruppo di processi o un
+processo qualsiasi, e deve essere specificato secondo uno dei valori di
+tab.~\ref{tab:proc_waitid_idtype}; il secondo indica, a seconda del valore del
+primo, quale processo o quale gruppo di processi selezionare.
+
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Macro} & \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{P\_PID} & Indica la richiesta di attendere per un processo figlio
+                     il cui \acr{pid} corrisponda al valore dell'argomento
+                     \param{id}.\\
+    \const{P\_PGID}& Indica la richiesta di attendere per un processo figlio
+                     appartenente al \textit{process group} (vedi
+                     sez.~\ref{sec:sess_proc_group}) il cui \acr{pgid}
+                     corrisponda al valore dell'argomento \param{id}.\\
+    \const{P\_ALL} & Indica la richiesta di attendere per un processo figlio
+                     generico, il valore dell'argomento \param{id} viene
+                     ignorato.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti per i valori dell'argomento \param{idtype} della funzione
+    \func{waitid}.}
+  \label{tab:proc_waitid_idtype}
+\end{table}
+
+Come per \func{waitpid} anche il comportamento di \func{waitid} viene
+controllato dall'argomento \param{options}, da specificare come maschera
+binaria dei valori riportati in tab.~\ref{tab:proc_waitid_options}. Benché
+alcuni di questi siano identici come significato ed effetto ai precedenti di
+tab.~\ref{tab:proc_waitpid_options}, ci sono delle differenze significative:
+in questo caso si dovrà specificare esplicitamente l'attesa della terminazione
+di un processo impostando l'opzione \const{WEXITED}, mentre il precedente
+\const{WUNTRACED} è sostituito da \const{WSTOPPED}.  Infine è stata aggiunta
+l'opzione \const{WNOWAIT} che consente una lettura dello stato mantenendo il
+processo in attesa di ricezione, così che una successiva chiamata possa di
+nuovo riceverne lo stato.
+
+\begin{table}[!htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Macro} & \textbf{Descrizione}\\
+    \hline
+    \hline
+    \const{WEXITED}   & Ritorna quando un processo figlio è terminato.\\
+    \const{WNOHANG}   & Ritorna immediatamente anche se non c'è niente da
+                        notificare.\\ 
+    \const{WSTOPPED} &  Ritorna quando un processo figlio è stato fermato.\\
+    \const{WCONTINUED}& Ritorna quando un processo figlio che era stato
+                        fermato ha ripreso l'esecuzione.\\
+    \const{WNOWAIT}   & Lascia il processo ancora in attesa di ricezione, così
+                        che una successiva chiamata possa di nuovo riceverne
+                        lo stato.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti che identificano i bit dell'argomento \param{options}
+    della funzione \func{waitid}.} 
+  \label{tab:proc_waitid_options}
+\end{table}
+
+La funzione \func{waitid} restituisce un valore nullo in caso di successo, e
+$-1$ in caso di errore; viene restituito un valore nullo anche se è stata
+specificata l'opzione \const{WNOHANG} e la funzione è ritornata immediatamente
+senza che nessun figlio sia terminato. Pertanto per verificare il motivo del
+ritorno della funzione occorre analizzare le informazioni che essa
+restituisce; queste, al contrario delle precedenti \func{wait} e
+\func{waitpid} che usavano un semplice valore numerico, sono ritornate in una
+struttura di tipo \struct{siginfo\_t} (vedi fig.~\ref{fig:sig_siginfo_t})
+all'indirizzo puntato dall'argomento \param{infop}.
+
+Tratteremo nei dettagli la struttura \struct{siginfo\_t} ed il significato dei
+suoi vari campi in sez.~\ref{sec:sig_sigaction}, per quanto ci interessa qui
+basta dire che al ritorno di \func{waitid} verranno avvalorati i seguenti
+campi:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\var{si\_pid}] con il \acr{pid} del figlio.
+\item[\var{si\_uid}] con l'user-ID reale (vedi sez.~\ref{sec:proc_perms}) del
+  figlio.
+\item[\var{si\_signo}] con \const{SIGCHLD}.
+\item[\var{si\_status}] con lo stato di uscita del figlio o con il segnale che
+  lo ha terminato, fermato o riavviato.
+\item[\var{si\_code}] con uno fra \const{CLD\_EXITED}, \const{CLD\_KILLED},
+  \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}).
+\end{basedescript}
+
+%TODO mettere riferimento alla tabella giusta (vedere man credentials e man
+%     waitid)
+
+Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per
+la lettura dello stato di terminazione di un processo, analoghe alle
+precedenti ma che prevedono un ulteriore argomento attraverso il quale il
+kernel può restituire al padre informazioni sulle risorse (vedi
+sez.~\ref{sec:sys_res_limits}) usate dal processo terminato e dai vari figli.
+Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che diventano accessibili
+definendo la macro \macro{\_USE\_BSD}; i loro prototipi sono:
 \begin{functions}
   \headdecl{sys/times.h} \headdecl{sys/types.h} \headdecl{sys/wait.h}
   \headdecl{sys/resource.h} 
@@ -1057,8 +1268,7 @@ utilizzata anche dalla funzione \func{getrusage} (vedi
 sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un
 processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}.
 
-
-\subsection{Le funzioni \func{exec}}
+\subsection{La funzione \func{exec} e le funzioni di esecuzione dei programmi}
 \label{sec:proc_exec}
 
 Abbiamo già detto che una delle modalità principali con cui si utilizzano i
@@ -1217,7 +1427,7 @@ l'ambiente.
 Oltre a mantenere lo stesso \acr{pid}, il nuovo programma fatto partire da
 \func{exec} assume anche una serie di altre proprietà del processo chiamante;
 la lista completa è la seguente:
-\begin{itemize*}
+\begin{itemize}
 \item il \textit{process id} (\acr{pid}) ed il \textit{parent process id}
   (\acr{ppid});
 \item l'\textsl{user-ID reale}, il \textit{group-ID reale} ed i
@@ -1228,7 +1438,7 @@ la lista completa 
 \item il tempo restante ad un allarme (vedi sez.~\ref{sec:sig_alarm_abort});
 \item la directory radice e la directory di lavoro corrente (vedi
   sez.~\ref{sec:file_work_dir});
-\item la maschera di creazione dei file (\var{umask}, vedi
+\item la maschera di creazione dei file \itindex{umask} (\textit{umask}, vedi
   sez.~\ref{sec:file_perm_management}) ed i \textit{lock} sui file (vedi
   sez.~\ref{sec:file_locking});
 \item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
@@ -1236,7 +1446,7 @@ la lista completa 
 \item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
 \item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
   \var{tms\_cutime}, \var{tms\_ustime} (vedi sez.~\ref{sec:sys_cpu_times}).
-\end{itemize*}
+\end{itemize}
 
 Inoltre i segnali che sono stati impostati per essere ignorati nel processo
 chiamante mantengono la stessa impostazione pure nel nuovo programma, tutti
@@ -1251,32 +1461,34 @@ sez.~\ref{sec:file_fcntl}) per ciascun file descriptor. I file per cui 
 impostato vengono chiusi, tutti gli altri file restano aperti. Questo
 significa che il comportamento predefinito è che i file restano aperti
 attraverso una \func{exec}, a meno di una chiamata esplicita a \func{fcntl}
-che imposti il suddetto flag.
-
-Per le directory, lo standard POSIX.1 richiede che esse vengano chiuse
-attraverso una \func{exec}, in genere questo è fatto dalla funzione
-\func{opendir} (vedi sez.~\ref{sec:file_dir_read}) che effettua da sola
-l'impostazione del flag di \itindex{close-on-exec} \textit{close-on-exec}
-sulle directory che apre, in maniera trasparente all'utente.
+che imposti il suddetto flag.  Per le directory, lo standard POSIX.1 richiede
+che esse vengano chiuse attraverso una \func{exec}, in genere questo è fatto
+dalla funzione \func{opendir} (vedi sez.~\ref{sec:file_dir_read}) che effettua
+da sola l'impostazione del flag di \itindex{close-on-exec}
+\textit{close-on-exec} sulle directory che apre, in maniera trasparente
+all'utente.
 
 Abbiamo detto che l'\textsl{user-ID reale} ed il \textsl{group-ID reale}
-restano gli stessi all'esecuzione di \func{exec}; lo stesso vale per
-l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} (il significato
-di questi identificatori è trattato in sez.~\ref{sec:proc_access_id}), tranne
-quando il file che si va ad eseguire abbia o il \itindex{suid~bit} \acr{suid}
-bit o lo \itindex{sgid~bit} \acr{sgid} bit impostato, in questo caso
-l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} vengono
-impostati rispettivamente all'utente o al gruppo cui il file appartiene (per i
-dettagli vedi sez.~\ref{sec:proc_perms}).
+restano gli stessi all'esecuzione di \func{exec}; normalmente vale lo stesso
+anche per l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} (il
+significato di questi identificatori è trattato in
+sez.~\ref{sec:proc_access_id}), tranne quando il file di cui viene chiesta
+l'esecuzione ha o il \itindex{suid~bit} \acr{suid} bit o lo \itindex{sgid~bit}
+\acr{sgid} bit impostato, in questo caso l'\textsl{user-ID effettivo} ed il
+\textsl{group-ID effettivo} vengono impostati rispettivamente all'utente o al
+gruppo cui il file appartiene (per i dettagli di questo comportamento si veda
+sez.~\ref{sec:proc_perms}).
 
 Se il file da eseguire è in formato \emph{a.out} e necessita di librerie
 condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima
 del programma per caricare le librerie necessarie ed effettuare il link
-dell'eseguibile. Se il programma è in formato ELF per caricare le librerie
-dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP},
-in genere questo è \file{/lib/ld-linux.so.1} per programmi collegati con le
-\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi collegati con le
-\acr{glibc}. 
+dell'eseguibile.\footnote{il formato è ormai in completo disuso, per cui è
+  molto probabile che non il relativo supporto non sia disponibile.} Se il
+programma è in formato ELF per caricare le librerie dinamiche viene usato
+l'interprete indicato nel segmento \const{PT\_INTERP} previsto dal formato
+stesso, in genere questo è \sysfile{/lib/ld-linux.so.1} per programmi
+collegati con le \acr{libc5}, e \sysfile{/lib/ld-linux.so.2} per programmi
+collegati con le \acr{glibc}.
 
 Infine nel caso il file sia uno script esso deve iniziare con una linea nella
 forma \cmd{\#!/path/to/interpreter [argomenti]} dove l'interprete indicato
@@ -1291,7 +1503,7 @@ chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti]
   lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
   vari comportamenti si trova su
   \href{http://www.in-ulm.de/~mascheck/various/shebang/}
-  {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
+  {\textsf{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
 
 Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
 basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo
@@ -1319,16 +1531,18 @@ Come accennato in sez.~\ref{sec:intro_multiuser} il modello base\footnote{in
   realtà già esistono estensioni di questo modello base, che lo rendono più
   flessibile e controllabile, come le \itindex{capabilities}
   \textit{capabilities} illustrate in sez.~\ref{sec:proc_capabilities}, le ACL
-  per i file o il \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory
-    Access Control} di SELinux; inoltre basandosi sul lavoro effettuato con
+  per i file (vedi sez.~\ref{sec:file_ACL}) o il
+  \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory Access Control}
+  di \index{SELinux} SELinux; inoltre basandosi sul lavoro effettuato con
   SELinux, a partire dal kernel 2.5.x, è iniziato lo sviluppo di una
-  infrastruttura di sicurezza, il \textit{Linux Security Modules}, o LSM, in
-  grado di fornire diversi agganci a livello del kernel per modularizzare
-  tutti i possibili controlli di accesso.} di sicurezza di un sistema
-unix-like è fondato sui concetti di utente e gruppo, e sulla separazione fra
-l'amministratore (\textsl{root}, detto spesso anche \textit{superuser}) che
-non è sottoposto a restrizioni, ed il resto degli utenti, per i quali invece
-vengono effettuati i vari controlli di accesso.
+  infrastruttura di sicurezza, i \itindex{Linux~Security~Modules}
+  \textit{Linux Security Modules}, o LSM, in grado di fornire diversi agganci
+  a livello del kernel per modularizzare tutti i possibili controlli di
+  accesso.} di sicurezza di un sistema unix-like è fondato sui concetti di
+utente e gruppo, e sulla separazione fra l'amministratore (\textsl{root},
+detto spesso anche \textit{superuser}) che non è sottoposto a restrizioni, ed
+il resto degli utenti, per i quali invece vengono effettuati i vari controlli
+di accesso.
 
 Abbiamo già accennato come il sistema associ ad ogni utente e gruppo due
 identificatori univoci, lo user-ID ed il group-ID; questi servono al kernel per
@@ -1365,27 +1579,27 @@ tab.~\ref{tab:proc_uid_gid}.
     \hline
     \hline
     \acr{uid}   & \textit{real} & \textsl{user-ID reale} 
-                & indica l'utente che ha lanciato il programma\\ 
+                & Indica l'utente che ha lanciato il programma.\\ 
     \acr{gid}   & '' &\textsl{group-ID reale} 
-                & indica il gruppo principale dell'utente che ha lanciato 
-                  il programma \\ 
+                & Indica il gruppo principale dell'utente che ha lanciato 
+                  il programma.\\ 
     \hline
     \acr{euid}  & \textit{effective} &\textsl{user-ID effettivo} 
-                & indica l'utente usato nel controllo di accesso \\ 
+                & Indica l'utente usato nel controllo di accesso.\\ 
     \acr{egid}  & '' & \textsl{group-ID effettivo} 
-                & indica il gruppo usato nel controllo di accesso \\ 
+                & Indica il gruppo usato nel controllo di accesso.\\ 
     --          & -- & \textsl{group-ID supplementari} 
-                & indicano gli ulteriori gruppi cui l'utente appartiene \\ 
+                & Indicano gli ulteriori gruppi cui l'utente appartiene.\\ 
     \hline
     --          & \textit{saved} & \textsl{user-ID salvato} 
-                & è una copia dell'\acr{euid} iniziale\\ 
+                & È una copia dell'\acr{euid} iniziale.\\ 
     --          & '' & \textsl{group-ID salvato} 
-                & è una copia dell'\acr{egid} iniziale \\ 
+                & È una copia dell'\acr{egid} iniziale.\\ 
     \hline
     \acr{fsuid} & \textit{filesystem} &\textsl{user-ID di filesystem} 
-                & indica l'utente effettivo per l'accesso al filesystem \\ 
+                & Indica l'utente effettivo per l'accesso al filesystem. \\ 
     \acr{fsgid} & '' & \textsl{group-ID di filesystem} 
-                & indica il gruppo effettivo per l'accesso al filesystem  \\ 
+                & Indica il gruppo effettivo per l'accesso al filesystem.\\ 
     \hline
   \end{tabular}
   \caption{Identificatori di utente e gruppo associati a ciascun processo con
@@ -1524,12 +1738,12 @@ il programma, effettuare il lavoro che non necessita di privilegi aggiuntivi,
 ed eventualmente tornare indietro.
 
 Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
-viene gestito l'accesso al file \file{/var/log/utmp}.  In questo file viene
+viene gestito l'accesso al file \sysfile{/var/log/utmp}.  In questo file viene
 registrato chi sta usando il sistema al momento corrente; chiaramente non può
 essere lasciato aperto in scrittura a qualunque utente, che potrebbe
 falsificare la registrazione. Per questo motivo questo file (e l'analogo
-\file{/var/log/wtmp} su cui vengono registrati login e logout) appartengono ad
-un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad
+\sysfile{/var/log/wtmp} su cui vengono registrati login e logout) appartengono
+ad un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad
 esempio tutti i programmi di terminale in X, o il programma \cmd{screen} che
 crea terminali multipli su una console) appartengono a questo gruppo ed hanno
 il bit \acr{sgid} impostato.
@@ -1543,8 +1757,8 @@ situazione degli identificatori 
   \textsl{group-ID salvato}    &=& \textrm{\acr{utmp}}
 \end{eqnarray*}
 in questo modo, dato che il \textsl{group-ID effettivo} è quello giusto, il
-programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo. A
-questo punto il programma può eseguire una \code{setgid(getgid())} per
+programma può accedere a \sysfile{/var/log/utmp} in scrittura ed aggiornarlo.
+questo punto il programma può eseguire una \code{setgid(getgid())} per
 impostare il \textsl{group-ID effettivo} a quello dell'utente (e dato che il
 \textsl{group-ID reale} corrisponde la funzione avrà successo), in questo modo
 non sarà possibile lanciare dal terminale programmi che modificano detto file,
@@ -1557,7 +1771,7 @@ in tal caso infatti la situazione degli identificatori sarebbe:
 \end{eqnarray*}
 e ogni processo lanciato dal terminale avrebbe comunque \acr{gid} come
 \textsl{group-ID effettivo}. All'uscita dal terminale, per poter di nuovo
-aggiornare lo stato di \file{/var/log/utmp} il programma eseguirà una
+aggiornare lo stato di \sysfile{/var/log/utmp} il programma eseguirà una
 \code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo
 \acr{utmp}, ottenuto ad esempio con una precedente \func{getegid}), dato che
 in questo caso il valore richiesto corrisponde al \textsl{group-ID salvato} la
@@ -1568,7 +1782,7 @@ funzione avr
   \textsl{group-ID effettivo}  &=& \textrm{\acr{utmp}} \\
   \textsl{group-ID salvato}    &=& \textrm{\acr{utmp} (invariato)}
 \end{eqnarray*}
-consentendo l'accesso a \file{/var/log/utmp}.
+consentendo l'accesso a \sysfile{/var/log/utmp}.
 
 Occorre però tenere conto che tutto questo non è possibile con un processo con
 i privilegi di amministratore, in tal caso infatti l'esecuzione di una
@@ -1858,7 +2072,7 @@ un utente specifico, si pu
 \end{functions}
 
 La funzione esegue la scansione del database dei gruppi (usualmente
-\file{/etc/groups}) cercando i gruppi di cui è membro l'utente \param{user}
+\conffile{/etc/group}) cercando i gruppi di cui è membro l'utente \param{user}
 con cui costruisce una lista di gruppi supplementari, a cui aggiunge anche
 \param{group}, infine imposta questa lista per il processo corrente usando
 \func{setgroups}.  Si tenga presente che sia \func{setgroups} che
@@ -1912,13 +2126,18 @@ eseguibili,\footnote{una descrizione sommaria di questa funzionalit
   ma non essendo implementata non ne tratteremo qui.} in modo da poter
 stabilire quali capacità possono essere utilizzate quando viene messo in
 esecuzione uno specifico programma; attualmente però questa funzionalità non è
-implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
-  finora non è disponibile al momento neanche presente nessuna realizzazione
-  sperimentale delle specifiche POSIX.1e, anche se esistono dei patch di
-  sicurezza del kernel, come LIDS (vedi
-  \href{http://www.lids.org}{\texttt{http://www.lids.org/})} che realizzano
-  qualcosa di simile.}
+implementata.\footnote{per attualmente si intende fino al kernel 2.6.23;
+  benché l'infrastruttura per crearla sia presente (vedi anche
+  sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione
+  delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel,
+  come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})}
+  che realizzano qualcosa di simile.}
+
+% TODO verificare per process capability bounding set, vedi:
+%  http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e
 
+% TODO capire cosa cambia con i patch del 2.6.26, vedi
+% http://lwn.net/Articles/280279/  
 
 \begin{table}[!h!bt]
   \centering
@@ -1931,10 +2150,10 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
 %
 % POSIX-draft defined capabilities.
 %
-    \const{CAP\_CHOWN}      & la capacità di cambiare proprietario e gruppo
+    \const{CAP\_CHOWN}      & La capacità di cambiare proprietario e gruppo
                               proprietario di un file (vedi
                               sez.~\ref{sec:file_ownership_management}).\\
-    \const{CAP\_DAC\_OVERRIDE}& la capacità di evitare il controllo dei
+    \const{CAP\_DAC\_OVERRIDE}& La capacità di evitare il controllo dei
                               permessi di lettura, scrittura ed esecuzione dei
                               file, (vedi sez.~\ref{sec:file_access_control})
                               caratteristici del modello classico del
@@ -1942,11 +2161,11 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
                               \itindex{Discrectionary~Access~Control~(DAC)} 
                               \textit{Discrectionary Access Control} (da cui
                               il nome DAC).\\  
-    \const{CAP\_DAC\_READ\_SEARCH}& la capacità di evitare il controllo dei
+    \const{CAP\_DAC\_READ\_SEARCH}& La capacità di evitare il controllo dei
                               permessi di lettura, scrittura ed esecuzione per
                               le directory (vedi
                               sez.~\ref{sec:file_access_control}).\\
-    \const{CAP\_FOWNER}     & la capacità di evitare il controllo che 
+    \const{CAP\_FOWNER}     & La capacità di evitare il controllo che 
                               l'user-ID effettivo del processo (o meglio il
                               \textit{filesystem user-ID}, vedi
                               sez.~\ref{sec:proc_setuid}) coincida con
@@ -1967,7 +2186,7 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
                               \func{open} e \func{fcntl} (vedi
                               sez.~\ref{sec:file_open} e
                               sez.~\ref{sec:file_fcntl}).\\
-    \const{CAP\_FSETID}     & la capacità di evitare la cancellazione
+    \const{CAP\_FSETID}     & La capacità di evitare la cancellazione
                               automatica dei bit \itindex{suid~bit} \acr{suid}
                               e \itindex{sgid~bit} \acr{sgid} quando un file
                               per i quali sono impostati viene modificato da
@@ -1976,14 +2195,14 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
                               quando questo è relativo ad un gruppo cui non si
                               appartiene (vedi
                               sez.~\ref{sec:file_perm_management}).\\ 
-    \const{CAP\_KILL}       & la capacità di mandare segnali a qualunque
+    \const{CAP\_KILL}       & La capacità di mandare segnali a qualunque
                               processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
-    \const{CAP\_SETGID}     & la capacità di manipolare i group ID dei
+    \const{CAP\_SETGID}     & La capacità di manipolare i group ID dei
                               processi, sia il principale che i supplementari,
                               (vedi sez.~\ref{sec:proc_setgroups} che quelli
                               trasmessi tramite i socket \textit{unix domain}
                               (vedi sez.~\ref{sec:unix_socket}).\\
-    \const{CAP\_SETUID}     & la capacità di manipolare gli user ID del
+    \const{CAP\_SETUID}     & La capacità di manipolare gli user ID del
                               processo (con \func{setuid}, \func{setreuid},
                               \func{setresuid}, \func{setfsuid}) e di
                               trasmettere un valore arbitrario
@@ -1994,80 +2213,80 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
 % Linux specific capabilities
 %
 \hline
-    \const{CAP\_SETPCAP}    & la capacità di impostare o rimuovere una capacità
+    \const{CAP\_SETPCAP}    & La capacità di impostare o rimuovere una capacità
                               (limitatamente a quelle che il processo
                               chiamante ha nel suo insieme di capacità
                               permesse) da qualunque processo.\\
-    \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi
+% TODO cambiata nel 2.4.24 rc1 ?
+    \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare gli attributi
                               \textit{immutable} e \itindex{append~mode}
                               \textit{append only} per i file su un
                               filesystem che supporta questi 
                               attributi estesi.\\ 
-    \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server
+    \const{CAP\_NET\_BIND\_SERVICE}& La capacità di porre in ascolto server
                               su porte riservate (vedi
                               sez.~\ref{sec:TCP_func_bind}).\\ 
-    \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in
+    \const{CAP\_NET\_BROADCAST}& La capacità di consentire l'uso di socket in
                               \itindex{broadcast} \textit{broadcast} e
                               \itindex{multicast} \textit{multicast}.\\ 
-    \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni
+    \const{CAP\_NET\_ADMIN} & La capacità di eseguire alcune operazioni
                               privilegiate sulla rete (impostare le opzioni
                               privilegiate dei socket, abilitare il
                               \itindex{multicast} \textit{multicasting},
                               impostare interfacce di rete e 
                               tabella di instradamento).\\
-    \const{CAP\_NET\_RAW}   & la capacità di usare socket \texttt{RAW} e
+    \const{CAP\_NET\_RAW}   & La capacità di usare socket \texttt{RAW} e
                               \texttt{PACKET} (quelli che permettono di creare
                               pacchetti nei protocolli di basso livello).\\
-    \const{CAP\_IPC\_LOCK}  & la capacità di effettuare il \textit{memory
+    \const{CAP\_IPC\_LOCK}  & La capacità di effettuare il \textit{memory
                               locking} \itindex{memory~locking} con le
                               funzioni \func{mlock}, \func{mlockall},
                               \func{shmctl}, \func{mmap} (vedi
                               sez.~\ref{sec:proc_mem_lock} e 
                               sez.~\ref{sec:file_memory_map}). \\  
-    \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi
+    \const{CAP\_IPC\_OWNER} & La capacità di evitare il controllo dei permessi
                               per le operazioni sugli oggetti di
                               intercomunicazione fra processi (vedi
                               sez.~\ref{sec:ipc_sysv}).\\  
-    \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del
+    \const{CAP\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del
                               kernel. \\ 
-    \const{CAP\_SYS\_RAWIO} & la capacità di eseguire operazioni sulle porte
+    \const{CAP\_SYS\_RAWIO} & La capacità di eseguire operazioni sulle porte
                               di I/O con \func{ioperm} e \func{iopl} (vedi
                               sez.~\ref{sec:file_io_port}).\\
-    \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione
+    \const{CAP\_SYS\_CHROOT}& La capacità di eseguire la funzione
                               \func{chroot} (vedi
                               sez.~\ref{sec:file_chroot}).\\
-    \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con
+    \const{CAP\_SYS\_PTRACE}& Consente di tracciare qualunque processo con
                               \func{ptrace} (vedi 
                               sez.~\ref{sec:xxx_ptrace}).\\
-% TODO documentatare ptrace 
-    \const{CAP\_SYS\_PACCT} & la capacità di usare le funzioni di
+    \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di
                               \textit{accounting} dei processi (vedi
                               sez.~\ref{sec:sys_bsd_accounting}).\\ 
-    \const{CAP\_SYS\_ADMIN} & la capacità di eseguire una serie di compiti
+    \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti
                               amministrativi (come impostare le quote,
                               attivare e disattivare la swap, montare,
                               rimontare e smontare filesystem, ecc.). \\
-    \const{CAP\_SYS\_BOOT}  & la capacità di fare eseguire un riavvio del
+    \const{CAP\_SYS\_BOOT}  & La capacità di fare eseguire un riavvio del
                               sistema.\\
-    \const{CAP\_SYS\_NICE}  & la capacità di modificare le priorità dei
+    \const{CAP\_SYS\_NICE}  & La capacità di modificare le priorità dei
                               processi (vedi sez.~\ref{sec:proc_priority}). \\ 
-    \const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle
+    \const{CAP\_SYS\_RESOURCE}& La capacità di superare le limitazioni sulle
                               risorse, aumentare le quote disco, usare lo
                               spazio disco riservato all'amministratore.\\ 
-    \const{CAP\_SYS\_TIME}  & la capacità di modificare il tempo di sistema
+    \const{CAP\_SYS\_TIME}  & La capacità di modificare il tempo di sistema
                               (vedi sez.~\ref{sec:sys_time}).\\ 
-    \const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup}
+    \const{CAP\_SYS\_TTY\_CONFIG}& La capacità di simulare un \textit{hangup}
                               della console, con la funzione
                               \func{vhangup}.\\
-    \const{CAP\_MKNOD}      & la capacità di creare file di dispositivo con la
+    \const{CAP\_MKNOD}      & La capacità di creare file di dispositivo con la
                               funzione \func{mknod} (vedi
                               sez.~\ref{sec:file_mknod}).\footnotemark\\ 
-    \const{CAP\_LEASE}      & la capacità di creare dei \textit{file lease}
+    \const{CAP\_LEASE}      & La capacità di creare dei \textit{file lease}
                               \index{file!lease} su di un file (vedi
                               sez.~\ref{sec:file_asyncronous_lease})
                               indipendentemente dalla proprietà dello
                               stesso.\footnotemark\\
-    \const{CAP\_SETFCAP}    & la capacità di impostare le
+    \const{CAP\_SETFCAP}    & La capacità di impostare le
                               \textit{capabilities} di un file (non
                               supportata).\\ 
     \hline
@@ -2134,7 +2353,7 @@ un \textsl{AND} binario del contenuto corrente del \textit{capabilities
 capacità in esso elencate.
 
 Il \textit{capabilities bounding set} è un parametro di sistema, accessibile
-attraverso il contenuto del file \file{/proc/sys/kernel/cap-bound}, che per
+attraverso il contenuto del file \procfile{/proc/sys/kernel/cap-bound}, che per
 questa sua caratteristica consente di impostare un limite generale alle
 capacità che possono essere accordate ai vari processi.  Questo valore può
 essere impostato ad un valore arbitrario esclusivamente dal primo processo
@@ -2202,9 +2421,12 @@ fig.~\ref{fig:cap_kernel_struct}, come i prototipi delle due funzioni
 \func{capget} e \func{capset}, sono soggette ad essere modificate con il
 cambiamento del kernel (in particolare i tipi di dati delle strutture) ed
 anche se finora l'interfaccia è risultata stabile, non c'è nessuna
-assicurazione che questa venga mantenuta. Pertanto se si vogliono scrivere
-programmi portabili che possano essere eseguiti su qualunque versione del
-kernel è opportuno utilizzare le interfacce di alto livello.
+assicurazione che questa venga mantenuta.\footnote{anzi, visto lo scarso
+  utilizzo di questa funzionalità ci sono state varie discussioni fra gli
+  sviluppatori del kernel relative all'eliminarla o al modificarla
+  radicalmente.} Pertanto se si vogliono scrivere programmi portabili che
+possano essere eseguiti su qualunque versione del kernel è opportuno
+utilizzare le interfacce di alto livello.
 
 \begin{figure}[!htb]
   \footnotesize
@@ -2272,8 +2494,9 @@ con tutte le \textit{capabilities} azzerate. In caso di errore (cio
 non c'è memoria sufficiente ad allocare i dati) viene restituito \macro{NULL}
 ed \var{errno} viene impostata a \errval{ENOMEM}.  La memoria necessaria a
 mantenere i dati viene automaticamente allocata da \func{cap\_init}, ma dovrà
-essere disallocata esplicitamente quando non più necessaria utilizzando la
-funzione \funcd{cap\_free}, il cui prototipo è:
+essere disallocata esplicitamente quando non è più necessaria utilizzando, per
+questo l'interfaccia fornisce una apposita funzione, \funcd{cap\_free}, il cui
+prototipo è:
 \begin{functions}
   \headdecl{sys/capability.h}
 
@@ -2289,10 +2512,11 @@ La funzione permette di liberare la memoria allocata dalle altre funzioni
 della libreria sia per un \textit{capability state}, nel qual caso l'argomento
 dovrà essere un dato di tipo \type{cap\_t}, che per una descrizione testuale
 dello stesso,\footnote{cioè quanto ottenuto tramite la funzione
-  \func{cap\_to\_text}.} nel qual caso l'argomento dovrà essere di tipo
-\texttt{char *}. L'argomento \param{obj\_d} deve corrispondere ad un oggetto
-ottenuto tramite altre funzioni della libreria, altrimenti la funzione fallirà
-con un errore di \errval{EINVAL}.
+  \func{cap\_to\_text}.} nel qual caso l'argomento dovrà essere un dato di
+tipo \texttt{char *}. Per questo l'argomento \param{obj\_d} è dichiarato come
+\texttt{void *} e deve sempre corrispondere ad un puntatore ottenuto tramite
+le altre funzioni della libreria, altrimenti la funzione fallirà con un errore
+di \errval{EINVAL}.
 
 Infine si può creare una copia di un \textit{capability state} ottenuto in
 precedenza tramite la funzione \funcd{cap\_dup}, il cui prototipo è:
@@ -2313,11 +2537,13 @@ La funzione crea una copia del \textit{capability state} posto all'indirizzo
 copia, che conterrà gli stessi valori delle \textit{capabilities} presenti
 nell'originale. La memoria necessaria viene allocata automaticamente dalla
 funzione. Una volta effettuata la copia i due \textit{capability state}
-potranno essere modificati in maniera completamente indipendente.
+potranno essere modificati in maniera completamente
+indipendente.\footnote{alla fine delle operazioni si ricordi però di
+  disallocare anche la copia, oltre all'originale. }
 
-Una seconda classe di funzioni di servizio sono quelle per la gestione dei
-dati contenuti all'interno di un \textit{capability state}; la prima di esse è
-\funcd{cap\_clear}, il cui prototipo è:
+Una seconda classe di funzioni di servizio previste dall'interfaccia sono
+quelle per la gestione dei dati contenuti all'interno di un \textit{capability
+  state}; la prima di queste è \funcd{cap\_clear}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/capability.h}
 
@@ -2392,10 +2618,12 @@ combinare diversi valori in una maschera binaria, una variabile di tipo
 \type{cap\_value\_t} deve indicare una sola capacità.\footnote{nel file di
   header citato nella nota precedente il tipo \type{cap\_value\_t} è definito
   come \ctyp{int}, ma i valori validi sono soltanto quelli di
-  tab.~\ref{tab:proc_capabilities}.}  Infine lo stato di una capacità è
-descritto ad una variabile di tipo \type{cap\_flag\_value\_t}, che a sua volta
-può assumere soltanto uno\footnote{anche questo è un tipo enumerato.} dei
-valori di tab.~\ref{tab:cap_value_type}.
+  tab.~\ref{tab:proc_capabilities}.}  
+
+Infine lo stato di una capacità è descritto ad una variabile di tipo
+\type{cap\_flag\_value\_t}, che a sua volta può assumere soltanto
+uno\footnote{anche questo è un tipo enumerato.} dei valori di
+tab.~\ref{tab:cap_value_type}.
 
 \begin{table}[htb]
   \centering
@@ -2421,11 +2649,11 @@ puntato dall'argomento \param{value\_p}; 
 stato di una capacità alla volta.
 
 La funzione \func{cap\_set\_flag} può invece impostare in una sola chiamata
-più capacità, anche se solo all'interno dello stesso insieme; per questo essa
-prende un vettore di valori di tipo \type{cap\_value\_t} nell'argomento
-\param{caps}, la cui dimensione è specificata dall'argomento \param{ncap}. Il
-tipo di impostazione da eseguire (cancellazione o impostazione) viene indicato
-dall'argomento \param{value}.
+più \textit{capabilities}, anche se solo all'interno dello stesso insieme. Per
+questo motivo essa prende un vettore di valori di tipo \type{cap\_value\_t}
+nell'argomento \param{caps}, la cui dimensione viene specificata dall'argomento
+\param{ncap}. Il tipo di impostazione da eseguire (cancellazione o
+impostazione) viene indicato dall'argomento \param{value}.
 
 Per la visualizzazione dello stato delle \textit{capabilities} l'interfaccia
 prevede una funzione apposita, \funcd{cap\_to\_text}, il cui prototipo è:
@@ -2448,12 +2676,13 @@ testuale del contenuto del \textit{capabilities state} \param{caps} passato
 come argomento, e, qualora l'argomento \param{length\_p} sia diverso da
 \val{NULL}, restituisce nella variabile intera da questo puntata la lunghezza
 della stringa. La stringa restituita viene allocata automaticamente dalla
-funzione e deve essere liberata con \func{cap\_free}.
+funzione e pertanto dovrà essere liberata con \func{cap\_free}.
 
-Fin quei abbiamo trattato delle funzioni di manipolazione dei
-\textit{capabilities state}; quando si vuole eseguire la lettura delle
-\textit{capabilities} del processo corrente si deve usare la funzione
-\funcd{cap\_get\_proc}, il cui prototipo è:
+Fin quei abbiamo trattato solo le funzioni di servizio relative alla
+manipolazione dei \textit{capabilities state}; l'interfaccia di gestione
+prevede però anche le funzioni per la gestione delle \textit{capabilities}
+stesse. La prima di queste è \funcd{cap\_get\_proc} che consente la lettura
+delle \textit{capabilities} del processo corrente, il suo prototipo è:
 \begin{functions}
   \headdecl{sys/capability.h}
 
@@ -2465,10 +2694,11 @@ Fin quei abbiamo trattato delle funzioni di manipolazione dei
     assumere i valori \errval{EINVAL}, \errval{EPERM} o \errval{ENOMEM}.  }
 \end{functions}
 
-La funzione legge il valore delle \textit{capabilities} del processo corrente
-e restituisce il puntatore ad un \textit{capabilities state} contenente il
-risultato, che provvede ad allocare autonomamente, e che occorrerà liberare
-con \func{cap\_free} quando non sarà più utilizzato.
+La funzione legge il valore delle \textit{capabilities} associate al processo
+da cui viene invocata, restituendo il risultato tramite il puntatore ad un
+\textit{capabilities state} contenente tutti i dati che provvede ad allocare
+autonomamente e che di nuovo occorrerà liberare con \func{cap\_free} quando
+non sarà più utilizzato.
 
 Se invece si vogliono leggere le \textit{capabilities} di un processo
 specifico occorre usare la funzione \funcd{capgetp}, il cui
@@ -2487,19 +2717,23 @@ prototipo\footnote{su alcune pagine di manuale la funzione 
     \errval{EPERM} o \errval{ENOMEM}.  
   }
 \end{functions}
+%TODO controllare e correggere i codici di errore!!!
 
 La funzione legge il valore delle \textit{capabilities} del processo indicato
-con l'argomento \param{pid}, salvando il risultato nel \textit{capabilities
-  state} all'indirizzo \param{cap\_d} che deve essere stato creato in
-precedenza. Qualora il processo non esista si avrà un errore di
-\errval{ESRCH}. Gli stessi valori possono essere letti direttamente nel
-filesystem \textit{proc}, nei file \texttt{/proc/<pid>/status}; ad esempio per
-\texttt{init} si otterrà qualcosa del tipo:
+con l'argomento \param{pid}, e restituisce il risultato nel
+\textit{capabilities state} posto all'indirizzo indicato con l'argomento
+\param{cap\_d}; a differenza della precedente in questo caso il
+\textit{capability state} deve essere stato creato in precedenza. Qualora il
+processo indicato non esista si avrà un errore di \errval{ESRCH}. Gli stessi
+valori possono essere letti direttamente nel filesystem \textit{proc}, nei
+file \texttt{/proc/<pid>/status}; ad esempio per \texttt{init} si otterrà
+qualcosa del tipo:
 \begin{Verbatim}
 ...
 CapInh: 0000000000000000
 CapPrm: 00000000fffffeff
 CapEff: 00000000fffffeff  
+...
 \end{Verbatim}
 
 Infine per impostare le \textit{capabilities} del processo corrente (non
@@ -2571,6 +2805,8 @@ funzione.
 % TODO documentare prctl ...
  
 
+% TODO: rivedere alla luce degli aggiornamenti del 2.6 (man sched_setscheduler)
+
 \section{La gestione della priorità di esecuzione}
 \label{sec:proc_priority}
 
@@ -2593,7 +2829,7 @@ essenziale anche dal tipo di utilizzo che deve essere fatto del sistema, per
 cui non esiste un meccanismo che sia valido per tutti gli usi.
 
 La caratteristica specifica di un sistema multitasking come Linux è quella del
-cosiddetto \itindex{prehemptive~multitasking} \textit{prehemptive
+cosiddetto \itindex{preemptive~multitasking} \textit{preemptive
   multitasking}: questo significa che al contrario di altri sistemi (che usano
 invece il cosiddetto \itindex{cooperative~multitasking} \textit{cooperative
   multitasking}) non sono i singoli processi, ma il kernel stesso a decidere
@@ -2651,6 +2887,11 @@ fintanto che esso si trova in uno qualunque degli altri stati.
     \textbf{Zombie}\index{zombie} & \texttt{Z} & Il processo è terminato ma il
                                     suo stato di terminazione non è ancora
                                     stato letto dal padre. \\
+    \textbf{Killable}& \texttt{D} & Un nuovo stato introdotto con il kernel
+                                    2.6.25, sostanzialmente identico
+                                    all'\textbf{Uninterrutible Sleep} con la
+                                    sola differenza che il processo può
+                                    terminato (con \const{SIGKILL}). \\ 
     \hline
   \end{tabular}
   \caption{Elenco dei possibili stati di un processo in Linux, nella colonna
@@ -2659,6 +2900,8 @@ fintanto che esso si trova in uno qualunque degli altri stati.
   \label{tab:proc_proc_states}
 \end{table}
 
+% TODO nel 2.6.25 è stato aggiunto TASK_KILLABLE, da capire dova va messo.
+
 Si deve quindi tenere presente che l'utilizzo della CPU è soltanto una delle
 risorse che sono necessarie per l'esecuzione di un programma, e a seconda
 dello scopo del programma non è detto neanche che sia la più importante (molti
@@ -2759,8 +3002,9 @@ attraverso la funzione \funcd{nice}, il cui prototipo 
 {int nice(int inc)}
   Aumenta il valore di \var{nice} per il processo corrente.
   
-  \bodydesc{La funzione ritorna zero in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} può assumere i valori:
+  \bodydesc{La funzione ritorna zero o il nuovo valore di \var{nice} in caso
+    di successo e -1 in caso di errore, nel qual caso \var{errno} può assumere
+    i valori:
   \begin{errlist}
   \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha
     specificato un valore di \param{inc} negativo.
@@ -2777,9 +3021,27 @@ priorit
 l'amministratore può specificare valori negativi che permettono di aumentare
 la priorità di un processo.
 
-In SUSv2 la funzione ritorna il nuovo valore di \var{nice}; Linux non segue
-questa convenzione, e per leggere il nuovo valore occorre invece usare la
-funzione \funcd{getpriority}, derivata da BSD, il cui prototipo è:
+Gli standard SUSv2 e POSIX.1 prevedono che la funzione ritorni il nuovo valore
+di \var{nice} del processo; tuttavia la system call di Linux non segue questa
+convenzione e restituisce sempre 0 in caso di successo, questo perché $-1$ è
+un valore di \var{nice} legittimo e questo comporta una confusione con una
+eventuale condizione di errore. 
+
+Fino alle \acr{glibc} 2.2.4 la funzione di libreria riportava direttamente il
+valore ottenuto dalla system call, violando lo standard, per cui per ottenere
+il nuovo valore occorreva una successiva chiamata alla funzione
+\func{getpriority}. A partire dalla \acr{glibc} 2.2.4 \func{nice} è stata
+reimplementata come funzione di libreria, e restituisce il valore di
+\var{nice} come richiesto dallo standard.\footnote{questo viene fatto
+  chiamando al suo interno \func{getpriority}, ed è questo il motivo delle due
+  possibilità per i valori di ritorno citati nella descrizione del prototipo.}
+In questo caso l'unico modo per rilevare in maniera affidabile una condizione
+di errore è quello di azzerare \var{errno} prima della chiamata della funzione
+e verificarne il valore quando \func{nice} restituisce $-1$.
+
+
+Per leggere il valore di nice di un processo occorre usare la funzione
+\funcd{getpriority}, derivata da BSD; il suo prototipo è:
 \begin{prototype}{sys/resource.h}
 {int getpriority(int which, int who)}
   
@@ -2825,12 +3087,12 @@ l'utente correnti.
 \end{table}
 
 La funzione restituisce la priorità più alta (cioè il valore più basso) fra
-quelle dei processi specificati; dato che -1 è un valore possibile, per poter
-rilevare una condizione di errore è necessario cancellare sempre \var{errno}
-prima della chiamata alla funzione, per verificare che essa resti uguale a
-zero.  
+quelle dei processi specificati; di nuovo, dato che $-1$ è un valore
+possibile, per poter rilevare una condizione di errore è necessario cancellare
+sempre \var{errno} prima della chiamata alla funzione per verificare che essa
+resti uguale a zero.
 
-Analoga a \func{getpriority} la funzione \funcd{setpriority} permette di
+Analoga a \func{getpriority} è la funzione \funcd{setpriority} che permette di
 impostare la priorità di uno o più processi; il suo prototipo è:
 \begin{prototype}{sys/resource.h}
 {int setpriority(int which, int who, int prio)}  
@@ -2897,7 +3159,7 @@ tocca al kernel decidere quale deve essere eseguito.  Il meccanismo con cui
 vengono gestiti questi processi dipende dalla politica di scheduling che si è
 scelta; lo standard ne prevede due:
 \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito
+\item[\textsf{FIFO}] \textit{First In First Out}. Il processo viene eseguito
   fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
   blocca, finisce o viene interrotto da un processo a priorità più alta. Se il
   processo viene interrotto da uno a priorità più alta esso resterà in cima
@@ -2905,7 +3167,7 @@ scelta; lo standard ne prevede due:
   più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà
   posto in coda alla lista (ed altri processi con la stessa priorità potranno
   essere eseguiti).
-\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
+\item[\textsf{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
   a quello precedente, con la sola differenza che ciascun processo viene
   eseguito al massimo per un certo periodo di tempo (la cosiddetta
   \textit{time slice}) dopo di che viene automaticamente posto in fondo alla
@@ -2949,10 +3211,12 @@ assolute diverse da zero o politiche \const{SCHED\_FIFO} e \const{SCHED\_RR}.
     \textbf{Policy}  & \textbf{Significato} \\
     \hline
     \hline
-    \const{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO} \\
+    \const{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO}. \\
     \const{SCHED\_RR}   & Scheduling real-time con politica \textit{Round
-    Robin} \\
-    \const{SCHED\_OTHER}& Scheduling ordinario\\
+      Robin}. \\
+    \const{SCHED\_OTHER}& Scheduling ordinario.\\
+    \const{SCHED\_BATCH}& Scheduling ordinario con l'assunzione ulteriore di
+    lavoro \textit{CPU intensive}.\footnotemark\\
     \hline
   \end{tabular}
   \caption{Valori dell'argomento \param{policy} per la funzione
@@ -2960,6 +3224,10 @@ assolute diverse da zero o politiche \const{SCHED\_FIFO} e \const{SCHED\_RR}.
   \label{tab:proc_sched_policy}
 \end{table}
 
+\footnotetext{introdotto con il kernel 2.6.16.}
+
+% TODO manca SCHED_IDLE
+
 Il valore della priorità è passato attraverso la struttura
 \struct{sched\_param} (riportata in fig.~\ref{fig:sig_sched_param}), il cui
 solo campo attualmente definito è \var{sched\_priority}, che nel caso delle
@@ -3099,7 +3367,6 @@ dato che in Linux questo intervallo di tempo 
 questa funzione ritorna sempre un valore di 150 millisecondi, e non importa
 specificare il PID di un processo reale.
 
-
 Come accennato ogni processo che usa lo scheduling real-time può rilasciare
 volontariamente la CPU; questo viene fatto attraverso la funzione
 \funcd{sched\_yield}, il cui prototipo è:
@@ -3119,17 +3386,25 @@ l'esecuzione non sar
 in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi
 con pari priorità quando la sezione più urgente è finita.
 
+% TODO: con il 2.6.23 il comportamento è stato leggermente modificato ed è
+% stato introdotto /proc/sys/kernel/sched_compat_yield da mettere a 1 per aver
+% la compatibilità con il precedente.
+
+\subsection{Il controllo dello \textit{scheduler} per i sistemi
+  multiprocessore}
+\label{sec:proc_sched_multiprocess}
+
 Infine con il supporto dei sistemi multiprocessore sono state introdotte delle
 funzioni che permettono di controllare in maniera più dettagliata la scelta di
 quale processore utilizzare per eseguire un certo programma. Uno dei problemi
-che si pongono nei sistemi multiprocessore è infatti quello
-\index{effetto~ping-pong} dell'\textsl{effetto ping-pong}. Può accadere cioè
-che lo scheduler, quando riavvia un processo precedentemente interrotto,
-scegliendo il primo processore disponibile lo faccia eseguire da un processore
-diverso rispetto a quello su cui era stato eseguito in precedenza. Se il
-processo passa da un processore all'altro in questo modo (cosa che avveniva
-abbastanza di frequente con i kernel della seria 2.4.x) si ha
-l'\textsl{effetto ping-pong}.
+che si pongono nei sistemi multiprocessore è infatti quello del cosiddetto
+\index{effetto~ping-pong} \textsl{effetto ping-pong}. Può accadere cioè che lo
+scheduler, quando riavvia un processo precedentemente interrotto scegliendo il
+primo processore disponibile, lo faccia eseguire da un processore diverso
+rispetto a quello su cui era stato eseguito in precedenza. Se il processo
+passa da un processore all'altro in questo modo (cosa che avveniva abbastanza
+di frequente con i kernel della seria 2.4.x) si ha l'\textsl{effetto
+  ping-pong}.
 
 Questo tipo di comportamento può generare dei seri problemi di prestazioni;
 infatti tutti i processori moderni utilizzano una memoria interna (la
@@ -3152,13 +3427,13 @@ disponibile.
 \itindbeg{CPU~affinity}
 
 Per ovviare a questo tipo di problemi è nato il concetto di \textsl{affinità
-  di processore} (o \textit{CPU affinity}); la
-possibilità cioè di far sì che un processo possa essere assegnato per
-l'esecuzione sempre allo stesso processore. Lo scheduler dei kernel della
-serie 2.4.x aveva una scarsa \textit{CPU affinity}, e
-\index{effetto~ping-pong} l'effetto ping-pong era comune; con il nuovo
-scheduler dei kernel della 2.6.x questo problema è stato risolto ed esso cerca
-di mantenere il più possibile ciascun processo sullo stesso processore.
+  di processore} (o \textit{CPU affinity}); la possibilità cioè di far sì che
+un processo possa essere assegnato per l'esecuzione sempre allo stesso
+processore. Lo scheduler dei kernel della serie 2.4.x aveva una scarsa
+\textit{CPU affinity}, e \index{effetto~ping-pong} l'effetto ping-pong era
+comune; con il nuovo scheduler dei kernel della 2.6.x questo problema è stato
+risolto ed esso cerca di mantenere il più possibile ciascun processo sullo
+stesso processore.
 
 In certi casi però resta l'esigenza di poter essere sicuri che un processo sia
 sempre eseguito dallo stesso processore,\footnote{quella che viene detta
@@ -3171,18 +3446,10 @@ problematiche nei nuovi kernel\footnote{le due system call per la gestione
 l'opportuna infrastruttura ed una nuova system call che permette di impostare
 su quali processori far eseguire un determinato processo attraverso una
 \textsl{maschera di affinità}. La corrispondente funzione di libreria è
-\funcd{sched\_setaffinity} ed il suo prototipo\footnote{di questa funzione (e
-  della corrispondente \func{sched\_setaffinity}) esistono versioni diverse
-  per gli argomenti successivi a \param{pid}: la prima (quella riportata nella
-  pagina di manuale) prevedeva due ulteriori argomenti di tipo
-  \texttt{unsigned int len} e \texttt{unsigned long *mask}, poi l'argomento
-  \texttt{len} è stato eliminato, successivamente si è introdotta la versione
-  riportata con però un secondo argomento di tipo \texttt{size\_t cpusetsize}
-  (anche questa citata nella pagina di manuale); la versione citata è quella
-  riportata nel manuale delle \textsl{glibc} e corrispondente alla definizione
-  presente in \file{sched.h}.} è:
+\funcd{sched\_setaffinity} ed il suo prototipo è:
 \begin{prototype}{sched.h}
-  {int sched\_setaffinity (pid\_t pid, const cpu\_set\_t *cpuset)} 
+  {int sched\_setaffinity (pid\_t pid, unsigned int cpusetsize, const
+    cpu\_set\_t *cpuset)} 
   Imposta la maschera di affinità del processo \param{pid}.
   
   \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore,
@@ -3197,6 +3464,21 @@ su quali processori far eseguire un determinato processo attraverso una
   ed inoltre anche \errval{EFAULT}.}
 \end{prototype}
 
+
+Questa funzione e la corrispondente \func{sched\_setaffinity} hanno una storia
+abbastanza complessa, la system call prevede l'uso di due ulteriori argomenti
+di tipo \texttt{unsigned int len} e \texttt{unsigned long *mask}, che
+corrispondono al fatto che la implementazione effettiva usa una semplice
+maschera binaria. Quando le funzioni vennero incluse nelle \acr{glibc}
+assunsero invece il prototipo appena mostrato. A complicare la cosa si
+aggiunge il fatto che nella versione 2.3.3 delle \acr{glibc} l'argomento
+\param{cpusetsize} è stato eliminato, per poi essere ripristinato nella
+versione 2.3.4.\footnote{pertanto se la vostra pagina di manuale non è
+  aggiornata, o usate quella particolare versione delle \acr{glibc}, potrete
+  trovare indicazioni diverse, il prototipo illustrato è quello riportato
+  nella versione corrente (maggio 2008) delle pagine di manuale e
+  corrispondente alla definizione presente in \file{sched.h}.}
+
 La funzione imposta, con l'uso del valore contenuto all'indirizzo
 \param{cpuset}, l'insieme dei processori sui quali deve essere eseguito il
 processo identificato tramite il valore passato in \param{pid}. Come in
@@ -3220,10 +3502,11 @@ o periferiche) pu
 avviene nelle architetture NUMA).
 
 Infine se un gruppo di processi accede alle stesse risorse condivise (ad
-esempio una applicazione con più thread) può avere senso usare lo stesso
-processore in modo da sfruttare meglio l'uso della sua cache; questo
-ovviamente riduce i benefici di un sistema multiprocessore nell'esecuzione
-contemporanea dei thread, ma in certi casi (quando i thread sono inerentemente
+esempio una applicazione con più \itindex{thread} \textit{thread}) può avere
+senso usare lo stesso processore in modo da sfruttare meglio l'uso della sua
+cache; questo ovviamente riduce i benefici di un sistema multiprocessore
+nell'esecuzione contemporanea dei \itindex{thread} \textit{thread}, ma in
+certi casi (quando i \itindex{thread} \textit{thread} sono inerentemente
 serializzati nell'accesso ad una risorsa) possono esserci sufficienti vantaggi
 nell'evitare la perdita della cache da rendere conveniente l'uso dell'affinità
 di processore.
@@ -3271,7 +3554,8 @@ possa essere eseguito su qualunque processore, se pu
 valore per un processo specifico usando la funzione
 \funcd{sched\_getaffinity}, il suo prototipo è:
 \begin{prototype}{sched.h}
-  {int sched\_getaffinity (pid\_t pid, const cpu\_set\_t *cpuset)} 
+  {int sched\_getaffinity (pid\_t pid, unsigned int cpusetsize, 
+    const cpu\_set\_t *cpuset)} 
   Legge la maschera di affinità del processo \param{pid}.
   
   \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore,
@@ -3345,7 +3629,7 @@ qualunque momento, e le operazioni di un eventuale \textit{signal handler}
 sono compiute nello stesso spazio di indirizzi del processo. Per questo, anche
 il solo accesso o l'assegnazione di una variabile possono non essere più
 operazioni atomiche (torneremo su questi aspetti in
-sez.~\ref{sec:sig_control}).
+sez.~\ref{sec:sig_adv_control}).
 
 In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t},
 il cui accesso è assicurato essere atomico.  In pratica comunque si può
@@ -3421,19 +3705,22 @@ eseguire in maniera atomica le operazioni necessarie.
 \subsection{Le funzioni rientranti}
 \label{sec:proc_reentrant}
 
+\index{funzioni!rientranti|(}
+
 Si dice \textsl{rientrante} una funzione che può essere interrotta in
 qualunque punto della sua esecuzione ed essere chiamata una seconda volta da
-un altro thread di esecuzione senza che questo comporti nessun problema
-nell'esecuzione della stessa. La problematica è comune nella programmazione
-multi-thread, ma si hanno gli stessi problemi quando si vogliono chiamare
-delle funzioni all'interno dei gestori dei segnali.
+un altro \itindex{thread} \textit{thread} di esecuzione senza che questo
+comporti nessun problema nell'esecuzione della stessa. La problematica è
+comune nella programmazione \itindex{thread} \textit{multi-thread}, ma si
+hanno gli stessi problemi quando si vogliono chiamare delle funzioni
+all'interno dei gestori dei segnali.
 
 Fintanto che una funzione opera soltanto con le variabili locali è rientrante;
-queste infatti vengono allocate nello \itindex{stack} stack, ed un'altra
-invocazione non fa altro che allocarne un'altra copia. Una funzione può non
-essere rientrante quando opera su memoria che non è nello \itindex{stack}
-stack.  Ad esempio una funzione non è mai rientrante se usa una variabile
-globale o statica.
+queste infatti vengono allocate nello \itindex{stack} \textit{stack}, ed
+un'altra invocazione non fa altro che allocarne un'altra copia. Una funzione
+può non essere rientrante quando opera su memoria che non è nello
+\itindex{stack} \textit{stack}.  Ad esempio una funzione non è mai rientrante
+se usa una variabile globale o statica.
 
 Nel caso invece la funzione operi su un oggetto allocato dinamicamente, la
 cosa viene a dipendere da come avvengono le operazioni: se l'oggetto è creato
@@ -3447,16 +3734,20 @@ parte del programmatore.
 
 In genere le funzioni di libreria non sono rientranti, molte di esse ad
 esempio utilizzano variabili statiche, le \acr{glibc} però mettono a
-disposizione due macro di compilatore, \macro{\_REENTRANT} e
+disposizione due macro di compilatore,\footnote{si ricordi quanto illustrato
+  in sez.~\ref{sec:intro_gcc_glibc_std}.} \macro{\_REENTRANT} e
 \macro{\_THREAD\_SAFE}, la cui definizione attiva le versioni rientranti di
 varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 \code{\_r} al nome della versione normale.
 
+\index{funzioni!rientranti|)}
+
+
 % LocalWords:  multitasking like VMS child process identifier pid sez shell fig
 % LocalWords:  parent kernel init pstree keventd kswapd table struct linux call
 % LocalWords:  nell'header scheduler system interrupt timer HZ asm Hertz clock
 % LocalWords:  l'alpha tick fork wait waitpid exit exec image glibc int pgid ps
-% LocalWords:  sid threads thread Ingo Molnar ppid getpid getppid sys unistd LD
+% LocalWords:  sid thread Ingo Molnar ppid getpid getppid sys unistd LD
 % LocalWords:  void ForkTest tempnam pathname sibling cap errno EAGAIN ENOMEM
 % LocalWords:  stack read only copy write tab client spawn forktest sleep PATH
 % LocalWords:  source LIBRARY scheduling race condition printf descriptor dup
@@ -3481,7 +3772,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  shmctl ioperm iopl chroot ptrace accounting swap reboot hangup
 % LocalWords:  vhangup mknod lease permitted inherited inheritable bounding AND
 % LocalWords:  capability capget capset header ESRCH undef version obj clear PT
-% LocalWords:  pag ssize length proc capgetp prehemptive cache runnable Stopped
+% LocalWords:  pag ssize length proc capgetp preemptive cache runnable Stopped
 % LocalWords:  Uninterrutible SIGSTOP soft slice nice niceness counter which SC
 % LocalWords:  getpriority who setpriority RTLinux RTAI Adeos fault FIFO First
 % LocalWords:  yield Robin setscheduler policy param OTHER priority setparam to
@@ -3494,9 +3785,13 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  PACCT RESOURCE TTY CONFIG SETFCAP hdrp datap libcap lcap text tp
 % LocalWords:  get ncap caps CapInh CapPrm fffffeff CapEff getcap STAT dall'I
 % LocalWords:  inc PRIO SUSv PRGR prio SysV SunOS Ultrix sched timespec len sig
-% LocalWords:  cpusetsize cpuset atomic
+% LocalWords:  cpusetsize cpuset atomic tickless redirezione WCONTINUED stopped
+% LocalWords:  waitid NOCLDSTOP ENOCHLD WIFCONTINUED ifdef endif idtype siginfo
+% LocalWords:  infop ALL WEXITED WSTOPPED WNOWAIT signo CLD EXITED KILLED page
+% LocalWords:  CONTINUED sources forking Spawned successfully executing exiting
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  next cat for COMMAND pts bash defunct