Aggiornamento anno note di copyright, dimenticato da gennaio...
[gapil.git] / prochand.tex
index 6a4b923ebf120cf15b895953c58d83fd439fa912..9f7b0d937a132cad4f443deb521e463a2e2e00d3 100644 (file)
@@ -1,6 +1,6 @@
 %% prochand.tex
 %%
-%% Copyright (C) 2000-2005 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",
@@ -8,6 +8,7 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{La gestione dei processi}
 \label{cha:process_handling}
 
@@ -43,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
@@ -137,29 +138,38 @@ 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}
 \end{figure}
 
-Come accennato in sez.~\ref{sec:intro_unix_struct} è lo
-\textit{scheduler}\itindex{scheduler} che decide quale processo mettere in
-esecuzione; esso viene eseguito ad ogni system call ed ad ogni
-interrupt,\footnote{più in una serie di altre occasioni.} 
-% TODO completare questa parte.
+Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \itindex{scheduler}
+\textit{scheduler} che decide quale processo mettere in esecuzione; esso viene
+eseguito ad ogni system call ed ad ogni interrupt,\footnote{più in una serie
+  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.
-
-Ogni volta che viene eseguito, lo \textit{scheduler}\itindex{scheduler}
+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
 questo in sez.~\ref{sec:proc_priority}) e stabilisce quale di essi debba
 essere posto in esecuzione fino alla successiva invocazione.
@@ -184,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
@@ -208,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}
 
@@ -239,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
@@ -270,8 +281,8 @@ Il fatto che il \acr{pid} sia un numero univoco per il sistema lo rende un
 candidato per generare ulteriori indicatori associati al processo di cui
 diventa possibile garantire l'unicità: ad esempio in alcune implementazioni la
 funzione \func{tempnam} (si veda sez.~\ref{sec:file_temp_file}) usa il
-\acr{pid} per generare un \itindex{pathname}\textit{pathname} univoco, che non
-potrà essere replicato da un altro processo che usi la stessa funzione.
+\acr{pid} per generare un \itindex{pathname} \textit{pathname} univoco, che
+non potrà essere replicato da un altro processo che usi la stessa funzione.
 
 Tutti i processi figli dello stesso processo padre sono detti
 \textit{sibling}, questa è una delle relazioni usate nel \textsl{controllo di
@@ -290,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
@@ -319,22 +330,23 @@ prototipo della funzione 
 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 segmenti di testo, \itindex{stack} 
-stack e 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.
-
-Per quanto riguarda la gestione della memoria, in generale
-il\index{segmento!testo} segmento di testo, che è identico per i due processi,
-è condiviso e tenuto in read-only per il padre e per i figli. Per gli altri
-segmenti Linux utilizza la tecnica del \textit{copy on write}
-\itindex{copy~on~write}; questa tecnica comporta che una pagina di memoria
-viene effettivamente copiata per il nuovo processo solo quando ci viene
-effettuata sopra una scrittura (e si ha quindi una reale differenza fra padre
-e figlio). In questo modo si rende molto più efficiente il meccanismo della
-creazione di un nuovo processo, non essendo più necessaria la copia di tutto
-lo spazio degli indirizzi virtuali del padre, ma solo delle pagine di memoria
-che sono state modificate, e solo al momento della modifica stessa.
+copia del padre, e riceve una copia dei \index{segmento!testo} segmenti di
+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.
+
+Per quanto riguarda la gestione della memoria, in generale il
+\index{segmento!testo} segmento di testo, che è identico per i due processi, è
+condiviso e tenuto in read-only per il padre e per i figli. Per gli altri
+segmenti Linux utilizza la tecnica del \itindex{copy~on~write} \textit{copy on
+  write}; questa tecnica comporta che una pagina di memoria viene
+effettivamente copiata per il nuovo processo solo quando ci viene effettuata
+sopra una scrittura (e si ha quindi una reale differenza fra padre e figlio).
+In questo modo si rende molto più efficiente il meccanismo della creazione di
+un nuovo processo, non essendo più necessaria la copia di tutto lo spazio
+degli indirizzi virtuali del padre, ma solo delle pagine di memoria che sono
+state modificate, e solo al momento della modifica stessa.
 
 La differenza che si ha nei due processi è che nel processo padre il valore di
 ritorno della funzione \func{fork} è il \acr{pid} del processo figlio, mentre
@@ -420,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 
@@ -437,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
-  scheduler\itindex{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
@@ -465,8 +472,26 @@ Pertanto non si pu
 istruzioni del codice fra padre e figli, né sull'ordine in cui questi potranno
 essere messi in esecuzione. Se è necessaria una qualche forma di precedenza
 occorrerà provvedere ad espliciti meccanismi di sincronizzazione, pena il
-rischio di incorrere nelle cosiddette \textit{race condition}
-\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond}).
+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
@@ -479,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
@@ -506,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
@@ -527,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,
@@ -538,40 +560,40 @@ 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 \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 \textit{file table}, e tutti gli altri processi, che vedono la stessa
-\textit{file table}, vedranno il nuovo valore. In questo modo si evita, in
-casi come quello appena mostrato in cui diversi processi scrivono sullo stesso
-file, che l'output successivo di un processo vada a sovrapporsi a quello dei
-precedenti: l'output potrà risultare mescolato, ma non ci saranno parti
-perdute per via di una sovrascrittura.
+sulla \itindex{file~table} \textit{file table}, e tutti gli altri processi,
+che vedono la stessa \itindex{file~table} \textit{file table}, vedranno il
+nuovo valore. In questo modo si evita, in casi come quello appena mostrato in
+cui diversi processi scrivono sullo stesso file, che l'output successivo di un
+processo vada a sovrapporsi a quello dei precedenti: l'output potrà risultare
+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
@@ -579,32 +601,33 @@ 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
 comune dopo l'esecuzione di una \func{fork} è la seguente:
 \begin{itemize*}
-\item i file aperti e gli eventuali flag di
-  \textit{close-on-exec}\itindex{close-on-exec} impostati (vedi
-  sez.~\ref{sec:proc_exec} e sez.~\ref{sec:file_fcntl});
+\item i file aperti e gli eventuali flag di \itindex{close-on-exec}
+  \textit{close-on-exec} impostati (vedi sez.~\ref{sec:proc_exec} e
+  sez.~\ref{sec:file_fcntl});
 \item gli identificatori per il controllo di accesso: l'\textsl{user-ID
     reale}, il \textsl{group-ID reale}, l'\textsl{user-ID effettivo}, il
   \textsl{group-ID effettivo} ed i \textit{group-ID supplementari} (vedi
   sez.~\ref{sec:proc_access_id});
-\item gli identificatori per il controllo di sessione: il \textit{process
-    group-ID} e il \textit{session id} ed il terminale di controllo (vedi
-  sez.~\ref{sec:sess_proc_group});
+\item gli identificatori per il controllo di sessione: il
+  \itindex{process~group} \textit{process group-ID} e il \textit{session id}
+  ed il terminale di controllo (vedi sez.~\ref{sec:sess_proc_group});
 \item la directory di lavoro e la directory radice (vedi
   sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot});
-\item la maschera dei permessi di creazione (vedi sez.~\ref{sec:file_umask});
+\item la maschera dei permessi di creazione (vedi
+  sez.~\ref{sec:file_perm_management});
 \item la maschera dei segnali bloccati (vedi sez.~\ref{sec:sig_sigmask}) e le
   azioni installate (vedi sez.~\ref{sec:sig_gen_beha});
 \item i segmenti di memoria condivisa agganciati al processo (vedi
   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:
@@ -622,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
@@ -639,7 +660,7 @@ padre, che costituiva un inutile appesantimento in tutti quei casi in cui la
 \func{fork} veniva fatta solo per poi eseguire una \func{exec}. La funzione
 venne introdotta in BSD per migliorare le prestazioni.
 
-Dato che Linux supporta il \textit{copy on write} \itindex{copy~on~write} la
+Dato che Linux supporta il \itindex{copy~on~write} \textit{copy on write} la
 perdita di prestazioni è assolutamente trascurabile, e l'uso di questa
 funzione (che resta un caso speciale della system call \func{\_\_clone}) è
 deprecato; per questo eviteremo di trattarla ulteriormente.
@@ -663,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
@@ -686,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
@@ -717,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
@@ -726,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 
@@ -743,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
@@ -761,7 +781,7 @@ memorizzando alcuni dati essenziali, come il \acr{pid}, i tempi di CPU usati
 dal processo (vedi sez.~\ref{sec:sys_unix_time}) e lo stato di terminazione,
 mentre la memoria in uso ed i file aperti vengono rilasciati immediatamente. I
 processi che sono terminati, ma il cui stato di terminazione non è stato
-ancora ricevuto dal padre sono chiamati \textit{zombie}\index{zombie}, essi
+ancora ricevuto dal padre sono chiamati \index{zombie} \textit{zombie}, essi
 restano presenti nella tabella dei processi ed in genere possono essere
 identificati dall'output di \cmd{ps} per la presenza di una \texttt{Z} nella
 colonna che ne indica lo stato (vedi tab.~\ref{tab:proc_proc_states}). Quando
@@ -774,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
@@ -785,40 +803,43 @@ 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 zombie \index{zombie} e l'indicazione che sono stati
-terminati.
-
-La possibilità di avere degli zombie \index{zombie} deve essere tenuta sempre
-presente quando si scrive un programma che deve essere mantenuto in esecuzione
-a lungo e creare molti figli. In questo caso si deve sempre avere cura di far
-leggere l'eventuale stato di uscita di tutti i figli (in genere questo si fa
-attraverso un apposito \textit{signal handler}, che chiama la funzione
-\func{wait}, vedi sez.~\ref{sec:sig_sigchld} e sez.~\ref{sec:proc_wait}).
-Questa operazione è necessaria perché anche se gli \textit{zombie}
-\index{zombie} non consumano risorse di memoria o processore, occupano
-comunque una voce nella tabella dei processi, che a lungo andare potrebbe
-esaurirsi.
+conclusi, con lo stato di \index{zombie} \textit{zombie} e l'indicazione che
+sono stati terminati.
+
+La possibilità di avere degli \index{zombie} \textit{zombie} deve essere
+tenuta sempre presente quando si scrive un programma che deve essere mantenuto
+in esecuzione a lungo e creare molti figli. In questo caso si deve sempre
+avere cura di far leggere l'eventuale stato di uscita di tutti i figli (in
+genere questo si fa attraverso un apposito \textit{signal handler}, che chiama
+la funzione \func{wait}, vedi sez.~\ref{sec:sig_sigchld} e
+sez.~\ref{sec:proc_wait}).  Questa operazione è necessaria perché anche se gli
+\index{zombie} \textit{zombie} non consumano risorse di memoria o processore,
+occupano comunque una voce nella tabella dei processi, che a lungo andare
+potrebbe esaurirsi.
 
 Si noti che quando un processo adottato da \cmd{init} termina, esso non
-diviene uno \textit{zombie}\index{zombie}; questo perché una delle funzioni di
-\cmd{init} è appunto quella di chiamare la funzione \func{wait} per i processi
-cui fa da padre, completandone la terminazione. Questo è quanto avviene anche
-quando, come nel caso del precedente esempio con \cmd{forktest}, il padre
-termina con dei figli in stato di zombie\index{zombie}: alla sua terminazione
-infatti tutti i suoi figli (compresi gli zombie\index{zombie}) verranno
-adottati da \cmd{init}, il quale provvederà a completarne la terminazione.
-
-Si tenga presente infine che siccome gli zombie\index{zombie} sono processi
-già usciti, non c'è modo di eliminarli con il comando \cmd{kill}; l'unica
-possibilità di cancellarli dalla tabella dei processi è quella di 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}}
+diviene uno \index{zombie} \textit{zombie}; questo perché una delle funzioni
+di \cmd{init} è appunto quella di chiamare la funzione \func{wait} per i
+processi cui fa da padre, completandone la terminazione. Questo è quanto
+avviene anche quando, come nel caso del precedente esempio con \cmd{forktest},
+il padre termina con dei figli in stato di \index{zombie} \textit{zombie}:
+alla sua terminazione infatti tutti i suoi figli (compresi gli \index{zombie}
+\textit{zombie}) verranno adottati da \cmd{init}, il quale provvederà a
+completarne la terminazione.
+
+Si tenga presente infine che siccome gli \index{zombie} \textit{zombie} sono
+processi già usciti, non c'è modo di eliminarli con il comando \cmd{kill};
+l'unica possibilità di cancellarli dalla tabella dei processi è quella di
+terminare il processo che li ha generati, in modo che \cmd{init} possa
+adottarli e provvedere a concluderne la terminazione.
+
+
+\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
@@ -826,8 +847,8 @@ consiste nella creazione di programmi di tipo server, in cui un processo
 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 \textit{zombie}\index{zombie} la tabella dei processi;
-le funzioni deputate a questo compito sono sostanzialmente due, \funcd{wait} e
+evitare di riempire di \index{zombie} \textit{zombie} la tabella dei processi;
+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}
@@ -866,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}
@@ -878,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}
@@ -918,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
-\textit{zombie}\index{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
@@ -966,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
+                             file di \itindex{core~dump} \textit{core
+                               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 
@@ -996,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} 
+
+  \headdecl{sys/wait.h}
+  
+  \funcdecl{int waitid(idtype\_t idtype, id\_t id, siginfo\_t *infop, int
+    options)}    
 
-\subsection{Le funzioni \func{wait3} e \func{wait4}}
-\label{sec:proc_wait4}
+  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} 
@@ -1053,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
@@ -1063,7 +1277,8 @@ fatto attraverso una delle funzioni della famiglia \func{exec}. Quando un
 processo chiama una di queste funzioni esso viene completamente sostituito dal
 nuovo programma; il \acr{pid} del processo non cambia, dato che non viene
 creato un nuovo processo, la funzione semplicemente rimpiazza lo
-\itindex{stack} stack, lo \itindex{heap} heap, i dati ed il testo del processo
+\itindex{stack} \textit{stack}, lo \itindex{heap} \textit{heap}, i
+\index{segmento!dati} dati ed il \index{segmento!testo} testo del processo
 corrente con un nuovo programma letto da disco.
 
 Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
@@ -1192,7 +1407,7 @@ non viene trovato nessun altro file viene finalmente restituito
 
 Le altre quattro funzioni si limitano invece a cercare di eseguire il file
 indicato dall'argomento \param{path}, che viene interpretato come il
-\itindex{pathname}\textit{pathname} del programma.
+\itindex{pathname} \textit{pathname} del programma.
 
 \begin{figure}[htb]
   \centering
@@ -1212,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
@@ -1223,15 +1438,15 @@ 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
-  sez.~\ref{sec:file_umask}) ed i \textit{lock} sui file (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
   sez.~\ref{sec:sig_sigmask});
 \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
@@ -1241,37 +1456,39 @@ speciale 
 sez.~\ref{sec:sig_gen_beha}).
 
 La gestione dei file aperti dipende dal valore che ha il flag di
-\textit{close-on-exec}\itindex{close-on-exec} (vedi anche
+\itindex{close-on-exec} \textit{close-on-exec} (vedi anche
 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 \textit{close-on-exec}\itindex{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 linkati con le
-\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi linkati 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
@@ -1286,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
@@ -1314,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 \textit{Mandatory Access Control}
-  \itindex{Mandatory~Access~Control~(MAC)} di 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.
+  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, 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
@@ -1360,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
@@ -1411,7 +1630,7 @@ Questi identificatori normalmente sono identici ai corrispondenti del gruppo
 sez.~\ref{sec:proc_exec}, il programma che si è posto in esecuzione abbia i
 bit \itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid} impostati
 (il significato di questi bit è affrontato in dettaglio in
-sez.~\ref{sec:file_suid_sgid}). In questo caso essi saranno impostati
+sez.~\ref{sec:file_special_perm}). In questo caso essi saranno impostati
 all'utente e al gruppo proprietari del file. Questo consente, per programmi in
 cui ci sia necessità, di dare a qualunque utente normale privilegi o permessi
 di un altro (o dell'amministratore).
@@ -1459,7 +1678,7 @@ dell'\textsl{user-ID effettivo} e del \textsl{group-ID effettivo} del processo
 padre, e vengono impostati dalla funzione \func{exec} all'avvio del processo,
 come copie dell'\textsl{user-ID effettivo} e del \textsl{group-ID effettivo}
 dopo che questi sono stati impostati tenendo conto di eventuali
-\itindex{suid~bit}\acr{suid} o \itindex{sgid~bit} \acr{sgid}.  Essi quindi
+\itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid}.  Essi quindi
 consentono di tenere traccia di quale fossero utente e gruppo effettivi
 all'inizio dell'esecuzione di un nuovo programma.
 
@@ -1513,18 +1732,18 @@ all'\textsl{user-ID salvato}. Negli altri casi viene segnalato un errore (con
 
 Come accennato l'uso principale di queste funzioni è quello di poter
 consentire ad un programma con i bit \itindex{suid~bit} \acr{suid} o
-\itindex{sgid~bit} \acr{sgid} impostati (vedi sez.~\ref{sec:file_suid_sgid})
+\itindex{sgid~bit} \acr{sgid} impostati (vedi sez.~\ref{sec:file_special_perm})
 di riportare l'\textsl{user-ID effettivo} a quello dell'utente che ha lanciato
 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.
@@ -1538,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,
@@ -1552,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
@@ -1563,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
@@ -1703,7 +1922,7 @@ corrente.
 Anche queste funzioni sono un'estensione specifica di Linux, e non richiedono
 nessun privilegio. I valori sono restituiti negli argomenti, che vanno
 specificati come puntatori (è un altro esempio di
-\itindex{value~result~argument}\textit{value result argument}). Si noti che
+\itindex{value~result~argument} \textit{value result argument}). Si noti che
 queste funzioni sono le uniche in grado di leggere gli identificatori del
 gruppo \textit{saved}.
 
@@ -1853,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
@@ -1907,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
@@ -1926,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_chown}).\\
-    \const{CAP\_DAC\_OVERRIDE}& la capacità di evitare il controllo dei
+                              sez.~\ref{sec:file_ownership_management}).\\
+    \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
@@ -1937,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
@@ -1950,117 +2174,119 @@ implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
                               precedenti \const{CAP\_DAC\_OVERRIDE} e
                               \const{CAP\_DAC\_READ\_SEARCH}. Queste
                               comprendono i cambiamenti dei permessi e dei
-                              tempi del file (vedi sez.~\ref{sec:file_chmod} e
-                              sez.~\ref{sec:file_utime}), le impostazioni degli
-                              attributi estesi (con il comando \cmd{chattr}) e
-                              delle ACL, poter ignorare lo
+                              tempi del file (vedi
+                              sez.~\ref{sec:file_perm_management} e 
+                              sez.~\ref{sec:file_file_times}), le impostazioni 
+                              degli attributi estesi (con il comando 
+                              \cmd{chattr}) e delle ACL, poter ignorare lo
                               \itindex{sticky~bit} \textit{sticky bit} nella
                               cancellazione dei file (vedi
-                              sez.~\ref{sec:file_sticky}), la possibilità di
-                              impostare il flag di \const{O\_NOATIME} con
+                              sez.~\ref{sec:file_special_perm}), la possibilità
+                              di impostare il flag di \const{O\_NOATIME} con
                               \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
                               un processo senza questa capacità e la capacità
                               di impostare il bit \acr{sgid} su un file anche
                               quando questo è relativo ad un gruppo cui non si
-                              appartiene (vedi sez.~\ref{sec:file_chmod}).\\ 
-    \const{CAP\_KILL}       & la capacità di mandare segnali a qualunque
+                              appartiene (vedi
+                              sez.~\ref{sec:file_perm_management}).\\ 
+    \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 \index{socket} socket
-                              \textit{unix domain} (vedi
-                              sez.~\ref{sec:unix_socket}).\\
-    \const{CAP\_SETUID}     & la capacità di manipolare gli user ID del
+                              trasmessi tramite i socket \textit{unix domain}
+                              (vedi sez.~\ref{sec:unix_socket}).\\
+    \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
                               dell'\textsl{uid} nel passaggio delle
-                              credenziali coi socket unix domain (vedi
+                              credenziali coi socket \textit{unix domain} (vedi
                               sez.~\ref{sec:unix_socket}).\\ 
 %
 % 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
-                              \textit{immutable} e \textit{append only} per i
-                              file su un filesystem che supporta questi
+% 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
@@ -2127,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
@@ -2195,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
@@ -2265,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}
 
@@ -2282,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 è:
@@ -2306,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}
 
@@ -2385,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
@@ -2414,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 è:
@@ -2441,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}
 
@@ -2458,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
@@ -2480,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
@@ -2559,14 +2800,18 @@ funzione.
 
 \itindend{capabilities}
 
+% TODO vedi http://lwn.net/Articles/198557/ e 
+% http://www.madore.org/~david/linux/newcaps/
+% 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}
 
 In questa sezione tratteremo più approfonditamente i meccanismi con il quale
-lo \textit{scheduler}\itindex{scheduler} assegna la CPU ai vari processi
+lo \itindex{scheduler} \textit{scheduler} assegna la CPU ai vari processi
 attivi.  In particolare prenderemo in esame i vari meccanismi con cui viene
 gestita l'assegnazione del tempo di CPU, ed illustreremo le varie funzioni di
 gestione.
@@ -2576,6 +2821,7 @@ gestione.
 \label{sec:proc_sched}
 
 \itindbeg{scheduler}
+
 La scelta di un meccanismo che sia in grado di distribuire in maniera efficace
 il tempo di CPU per l'esecuzione dei processi è sempre una questione delicata,
 ed oggetto di numerose ricerche; in generale essa dipende in maniera
@@ -2583,9 +2829,9 @@ 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
+invece il cosiddetto \itindex{cooperative~multitasking} \textit{cooperative
   multitasking}) non sono i singoli processi, ma il kernel stesso a decidere
 quando la CPU deve essere passata ad un altro processo. Come accennato in
 sez.~\ref{sec:proc_hierarchy} questa scelta viene eseguita da una sezione
@@ -2641,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
@@ -2649,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
@@ -2749,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.
@@ -2767,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)}
   
@@ -2815,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)}  
@@ -2864,11 +3136,11 @@ processo qualsiasi sia la sua priorit
   Adeos gestiti dalle code del nano-kernel), in modo da poterli controllare
   direttamente qualora ci sia la necessità di avere un processo con priorità
   più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un
-\textit{page fault}\itindex{page~fault} si possono avere ritardi non previsti.
-Se l'ultimo problema può essere aggirato attraverso l'uso delle funzioni di
-controllo della memoria virtuale (vedi sez.~\ref{sec:proc_mem_lock}), il primo
-non è superabile e può comportare ritardi non prevedibili riguardo ai tempi di
-esecuzione di qualunque processo.
+\itindex{page~fault} \textit{page fault} si possono avere ritardi non
+previsti.  Se l'ultimo problema può essere aggirato attraverso l'uso delle
+funzioni di controllo della memoria virtuale (vedi
+sez.~\ref{sec:proc_mem_lock}), il primo non è superabile e può comportare
+ritardi non prevedibili riguardo ai tempi di esecuzione di qualunque processo.
 
 Occorre usare le priorità assolute con molta attenzione: se si dà ad un
 processo una priorità assoluta e questo finisce in un loop infinito, nessun
@@ -2887,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
@@ -2895,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
@@ -2939,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
@@ -2950,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
@@ -3089,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 è:
@@ -3109,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
-dell'\textsl{effetto ping-pong}.\index{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
@@ -3140,14 +3425,15 @@ e si ha una continua invalidazione della cache, che non diventa mai
 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
@@ -3160,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,
@@ -3186,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
@@ -3209,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.
@@ -3260,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,
@@ -3281,6 +3576,7 @@ particolari.
 soltanto su un sistema multiprocessore, esse possono comunque essere
 utilizzate anche in un sistema con un processore singolo, nel qual caso però
 non avranno alcun risultato effettivo.
+
 \itindend{scheduler}
 \itindend{CPU~affinity}
 
@@ -3313,10 +3609,9 @@ di interruzione in una fase intermedia.
 In un ambiente multitasking il concetto è essenziale, dato che un processo può
 essere interrotto in qualunque momento dal kernel che mette in esecuzione un
 altro processo o dalla ricezione di un segnale; occorre pertanto essere
-accorti nei confronti delle possibili \textit{race
-  condition}\itindex{race~condition} (vedi sez.~\ref{sec:proc_race_cond})
-derivanti da operazioni interrotte in una fase in cui non erano ancora state
-completate.
+accorti nei confronti delle possibili \itindex{race~condition} \textit{race
+  condition} (vedi sez.~\ref{sec:proc_race_cond}) derivanti da operazioni
+interrotte in una fase in cui non erano ancora state completate.
 
 Nel caso dell'interazione fra processi la situazione è molto più semplice, ed
 occorre preoccuparsi della atomicità delle operazioni solo quando si ha a che
@@ -3334,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ò
@@ -3352,6 +3647,7 @@ condiviso, onde evitare problemi con le ottimizzazioni del codice.
 \label{sec:proc_race_cond}
 
 \itindbeg{race~condition}
+
 Si definiscono \textit{race condition} tutte quelle situazioni in cui processi
 diversi operano su una risorsa comune, ed in cui il risultato viene a
 dipendere dall'ordine in cui essi effettuano le loro operazioni. Il caso
@@ -3376,7 +3672,7 @@ file, o nell'accesso a meccanismi di intercomunicazione come la memoria
 condivisa. In questi casi, se non si dispone della possibilità di eseguire
 atomicamente le operazioni necessarie, occorre che quelle parti di codice in
 cui si compiono le operazioni sulle risorse condivise (le cosiddette
-\textsl{sezioni critiche}\index{sezione~critica}) del programma, siano
+\index{sezione~critica} \textsl{sezioni critiche}) del programma, siano
 opportunamente protette da meccanismi di sincronizzazione (torneremo su queste
 problematiche di questo tipo in cap.~\ref{cha:IPC}).
 
@@ -3409,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, e 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
@@ -3435,23 +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|)}
 
 
-%%% Local Variables: 
-%%% mode: latex
-%%% TeX-master: "gapil"
-%%% End: 
-
 % 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
+% 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
@@ -3470,16 +3766,32 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  setreuid setregid FIXME ruid rgid seteuid setegid setresuid size
 % LocalWords:  setresgid getresuid getresgid value result argument setfsuid DAC
 % LocalWords:  setfsgid NGROUPS sysconf getgroups getgrouplist groups ngroups
-% LocalWords:  setgroups initgroups patch LIDS CHOWN OVERRIDE Discrectionary
+% LocalWords:  setgroups initgroups patch LIDS CHOWN OVERRIDE Discrectionary PF
 % LocalWords:  SEARCH chattr sticky NOATIME socket domain immutable append mmap
 % LocalWords:  broadcast multicast multicasting memory locking mlock mlockall
 % 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
-% LocalWords:  pag ssize length proc capgetp prehemptive cache runnable Stopped
-% LocalWords:  Uninterrutible SIGSTOP soft slice nice niceness counter which
+% LocalWords:  capability capget capset header ESRCH undef version obj clear PT
+% 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
+% LocalWords:  yield Robin setscheduler policy param OTHER priority setparam to
 % LocalWords:  min getparam getscheduler interval robin ENOSYS fifo ping long
-% LocalWords:  affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE
-% LocalWords:  getaffinity assembler deadlock REENTRANT SAFE
+% LocalWords:  affinity setaffinity unsigned mask cpu NUMA CLR ISSET SETSIZE RR
+% LocalWords:  getaffinity assembler deadlock REENTRANT SAFE tgz MYPGRP l'OR rr
+% LocalWords:  WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WCOREDUMP WIFSTOPPED
+% LocalWords:  WSTOPSIG opt char INTERP arg SIG IGN DFL mascheck grp FOWNER RAW
+% LocalWords:  FSETID SETPCAP BIND SERVICE ADMIN PACKET IPC OWNER MODULE RAWIO
+% 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 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