Revisione, uniformato l'uso di glibc al singolare.
[gapil.git] / prochand.tex
index fc5e47746ad46a1fbb237faa2d368bee530d915c..16c51de94a0fd6fb69ff199b94eeaf5a0d346948 100644 (file)
@@ -39,12 +39,12 @@ terminazione dei processi, e per la messa in esecuzione degli altri programmi.
 \subsection{L'architettura della gestione dei processi}
 \label{sec:proc_hierarchy}
 
-A differenza di quanto avviene in altri sistemi, ad esempio nel VMS la
+A differenza di quanto avviene in altri sistemi, ad esempio nel VMS, dove la
 generazione di nuovi processi è un'operazione privilegiata, una delle
 caratteristiche fondanti di Unix, che esamineremo in dettaglio più avanti, è
 che qualunque processo può a sua volta generarne altri. Ogni processo è
 identificato presso il sistema da un numero univoco, il cosiddetto
-\textit{Process ID} o, più brevemente, \ids{PID}, assegnato in forma
+\textit{Process ID}, o più brevemente \ids{PID}, assegnato in forma
 progressiva (vedi sez.~\ref{sec:proc_pid}) quando il processo viene creato.
 
 Una seconda caratteristica di un sistema unix-like è che la generazione di un
@@ -57,16 +57,16 @@ indichiamo nella linea di comando.
 Una terza caratteristica del sistema è che ogni processo è sempre stato
 generato da un altro processo, il processo generato viene chiamato
 \textit{processo figlio} (\textit{child process}) mentre quello che lo ha
-viene chiamato \textsl{processo padre} (\textit{parent process}). Questo vale
-per tutti i processi, con una sola eccezione, dato che ci deve essere un punto
-di partenza esiste un processo speciale (che normalmente è \cmd{/sbin/init}),
-che come abbiamo accennato in sez.~\ref{sec:intro_kern_and_sys} viene lanciato
-dal kernel alla conclusione della fase di avvio. Essendo questo il primo
-processo lanciato dal sistema ha sempre il \ids{PID} uguale a 1 e non è figlio
-di nessun altro processo.
-
-Ovviamente \cmd{init} è un processo speciale che in genere si occupa di far
-partire tutti gli altri processi necessari al funzionamento del sistema,
+generato viene chiamato \textsl{processo padre} (\textit{parent
+  process}). Questo vale per tutti i processi, con una sola eccezione; dato
+che ci deve essere un punto di partenza esiste un processo iniziale (che
+normalmente è \cmd{/sbin/init}), che come accennato in
+sez.~\ref{sec:intro_kern_and_sys} viene lanciato dal kernel alla conclusione
+della fase di avvio. Essendo questo il primo processo lanciato dal sistema ha
+sempre \ids{PID} uguale a 1 e non è figlio di nessun altro processo.
+
+Ovviamente \cmd{init} è un processo particolare che in genere si occupa di
+lanciare tutti gli altri processi necessari al funzionamento del sistema,
 inoltre \cmd{init} è essenziale per svolgere una serie di compiti
 amministrativi nelle operazioni ordinarie del sistema (torneremo su alcuni di
 essi in sez.~\ref{sec:proc_termination}) e non può mai essere terminato. La
@@ -138,10 +138,10 @@ Il kernel mantiene una tabella dei processi attivi, la cosiddetta
 questa tabella, costituita da una struttura \kstruct{task\_struct}, che
 contiene tutte le informazioni rilevanti per quel processo. Tutte le strutture
 usate a questo scopo sono dichiarate nell'\textit{header file}
-\file{linux/sched.h}, ed uno schema semplificato, che riporta la struttura
-delle principali informazioni contenute nella \texttt{task\_struct} (che in
-seguito incontreremo a più riprese), è mostrato in
-fig.~\ref{fig:proc_task_struct}.
+\file{linux/sched.h}, ed in fig.~\ref{fig:proc_task_struct} si è riportato uno
+schema semplificato che mostra la struttura delle principali informazioni
+contenute nella \texttt{task\_struct}, che in seguito incontreremo a più
+riprese.
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=14cm]{img/task_struct}
@@ -179,7 +179,7 @@ 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.
 
-Indipendentemente dalle motivazioni per cui questo avviene, ogni volta che
+Ma, indipendentemente dalle motivazioni per cui questo avviene, ogni volta che
 viene eseguito lo \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
@@ -194,7 +194,7 @@ invocazione.
 
 Come accennato nella sezione precedente ogni processo viene identificato dal
 sistema da un numero identificativo univoco, il \textit{process ID} o
-\ids{PID}. Questo è un tipo di dato standard, \type{pid\_t} che in genere è un
+\ids{PID}. Questo è un tipo di dato standard, \type{pid\_t}, che in genere è un
 intero con segno (nel caso di Linux e della \acr{glibc} il tipo usato è
 \ctyp{int}).
 
@@ -272,7 +272,7 @@ sez.~\ref{sec:proc_perms}.
 \subsection{La funzione \func{fork} e le funzioni di creazione dei processi}
 \label{sec:proc_fork}
 
-La funzione di sistema \funcd{fork} è la funzione fondamentale della gestione
+La funzione di sistema \func{fork} è la funzione fondamentale della gestione
 dei processi: come si è detto tradizionalmente l'unico modo di creare un nuovo
 processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la
   \textit{system call} usata da Linux per creare nuovi processi è \func{clone}
@@ -282,18 +282,19 @@ processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la
   migliore interazione coi \textit{thread}.} essa quindi riveste un ruolo
 centrale tutte le volte che si devono scrivere programmi che usano il
 multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei
-  \textit{thread} che tratteremo al cap.~\ref{cha:threads}, è in parte minore,
-  ma \func{fork} resta comunque la funzione principale per la creazione di
-  processi.} Il prototipo della funzione è:
+  \textit{thread}\unavref{ che tratteremo al cap.~\ref{cha:threads}}, è in
+  parte minore, ma \func{fork} resta comunque la funzione principale per la
+  creazione di processi.} Il prototipo di \funcd{fork} è:
 
 \begin{funcproto}{ 
 \fhead{unistd.h}
 \fdecl{pid\_t fork(void)}
 \fdesc{Crea un nuovo processo.} 
 }
-{La funzione ritorna il \ids{PID} del figlio al padre e $0$ al figlio in caso 
-  di successo e $-1$ al padre senza creare il figlio per un errore,
-  nel qual caso \var{errno} assumerà uno dei valori: 
+
+{La funzione ritorna in caso di successo il \ids{PID} del figlio nel padre e
+  $0$ nel figlio mentre ritorna $-1$ nel padre, senza creare il figlio, per un
+  errore, al caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EAGAIN}] non ci sono risorse sufficienti per creare un altro
     processo (per allocare la tabella delle pagine e le strutture del task) o
@@ -304,7 +305,7 @@ multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei
 \end{funcproto}
 
 Dopo il successo dell'esecuzione di una \func{fork} sia il processo padre che
-il processo figlio continuano ad essere eseguiti normalmente a partire
+il processo figlio continuano ad essere eseguiti normalmente, a partire
 dall'istruzione successiva alla \func{fork}. Il processo figlio è una copia
 del padre, e riceve una copia dei segmenti di testo, dati e dello
 \textit{stack} (vedi sez.~\ref{sec:proc_mem_layout}), ed esegue esattamente lo
@@ -334,11 +335,11 @@ eseguito dal padre o dal figlio.  Si noti come la funzione \func{fork} ritorni
 due volte, una nel padre e una nel figlio.
 
 La scelta di questi valori di ritorno non è casuale, un processo infatti può
-avere più figli, ed il valore di ritorno di \func{fork} è l'unico modo che gli
-permette di identificare quello appena creato. Al contrario un figlio ha
-sempre un solo padre, il cui \ids{PID} può sempre essere ottenuto con
-\func{getppid}, come spiegato in sez.~\ref{sec:proc_pid}, per cui si usa il
-valore nullo, che non è il \ids{PID} di nessun processo.
+avere più figli, ed il valore di ritorno di \func{fork} è l'unico che gli
+permette di identificare qual è quello appena creato. Al contrario un figlio
+ha sempre un solo padre il cui \ids{PID}, come spiegato in
+sez.~\ref{sec:proc_pid}, può sempre essere ottenuto con \func{getppid}; per
+questo si ritorna un valore nullo, che non è il \ids{PID} di nessun processo.
 
 Normalmente la chiamata a \func{fork} può fallire solo per due ragioni: o ci
 sono già troppi processi nel sistema, il che di solito è sintomo che
@@ -353,7 +354,7 @@ ne esegue un'altra. È il caso tipico dei programmi server (il modello
 \textit{client-server} è illustrato in sez.~\ref{sec:net_cliserv}) in cui il
 padre riceve ed accetta le richieste da parte dei programmi client, per
 ciascuna delle quali pone in esecuzione un figlio che è incaricato di fornire
-il servizio.
+le risposte associate al servizio.
 
 La seconda modalità è quella in cui il processo vuole eseguire un altro
 programma; questo è ad esempio il caso della shell. In questo caso il processo
@@ -393,8 +394,8 @@ degli eventuali tempi di attesa in secondi (eseguiti tramite la funzione
 \func{sleep}) per il padre ed il figlio (con \cmd{forktest -h} si ottiene la
 descrizione delle opzioni). Il codice completo, compresa la parte che gestisce
 le opzioni a riga di comando, è disponibile nel file \file{fork\_test.c},
-distribuito insieme agli altri sorgenti degli esempi su
-\url{http://gapil.truelite.it/gapil_source.tgz}.
+distribuito insieme agli altri sorgenti degli esempi della guida su
+\url{http://gapil.gnulinux.it}.
 
 Decifrato il numero di figli da creare, il ciclo principale del programma
 (\texttt{\small 24-40}) esegue in successione la creazione dei processi figli
@@ -460,36 +461,36 @@ In realtà con l'introduzione dei kernel della serie 2.6 lo \textit{scheduler}
   risultati precedenti infatti sono stati ottenuti usando un kernel della
   serie 2.4.}  Questa è una ottimizzazione adottata per evitare che il padre,
 effettuando per primo una operazione di scrittura in memoria, attivasse il
-meccanismo del \textit{copy on write}, operazione inutile qualora il figlio
-venga creato solo per eseguire una \func{exec} su altro programma che scarta
-completamente lo spazio degli indirizzi e rende superflua la copia della
-memoria modificata dal padre. Eseguendo sempre per primo il figlio la
-\func{exec} verrebbe effettuata subito, con la certezza di utilizzare
+meccanismo del \textit{copy on write}, operazione inutile quando il figlio
+viene creato solo per eseguire una \func{exec} per lanciare un altro programma
+che scarta completamente lo spazio degli indirizzi e rende superflua la copia
+della memoria modificata dal padre. Eseguendo sempre per primo il figlio la
+\func{exec} verrebbe effettuata subito, con la certezza di utilizzare il
 \textit{copy on write} solo quando necessario.
 
 Con il kernel 2.6.32 però il comportamento è stato nuovamente cambiato,
 stavolta facendo eseguire per primo sempre il padre. Si è realizzato infatti
-che l'eventualità prospettata per la scelta precedente era comunque molto
-improbabile, mentre l'esecuzione immediata del padre presenta sempre il
+che l'eventualità prospettata per la scelta precedente era comunque poco
+probabile, mentre l'esecuzione immediata del padre presenta sempre il
 vantaggio di poter utilizzare immediatamente tutti i dati che sono nella cache
-della CPU e nella unità di gestione della memoria virtuale senza doverli
+della CPU e nell'unità di gestione della memoria virtuale, senza doverli
 invalidare, cosa che per i processori moderni, che hanno linee di cache
 interne molto profonde, avrebbe un forte impatto sulle prestazioni.
 
-Allora anche se quanto detto in precedenza vale come comportamento effettivo
-dei programmi soltanto per i kernel fino alla serie 2.4, per mantenere la
-portabilità con altri kernel unix-like, e con i diversi comportamenti adottati
-dalle Linux nelle versioni successive, è opportuno non fare affidamento su
-nessun tipo comportamento predefinito e non dare per assunta l'esecuzione
-preventiva del padre o del figlio.
-
-Si noti poi come dopo la \func{fork}, essendo i segmenti di memoria utilizzati
-dai singoli processi completamente indipendenti, le modifiche delle variabili
-nei processi figli, come l'incremento di \var{i} in (\texttt{\small 31}), sono
-visibili solo a loro, (ogni processo vede solo la propria copia della
-memoria), e non hanno alcun effetto sul valore che le stesse variabili hanno
-nel processo padre ed in eventuali altri processi figli che eseguano lo stesso
-codice.
+Allora anche se quanto detto in precedenza si verifica nel comportamento
+effettivo dei programmi soltanto per i kernel fino alla serie 2.4, per
+mantenere la portabilità con altri kernel unix-like e con i diversi
+comportamenti adottati dalle Linux nella sua evoluzione, è comunque opportuno
+non fare nessuna assunzione sull'ordine di esecuzione di padre e figlio dopo
+la chiamata a \func{fork}.
+
+Si noti infine come dopo la \func{fork}, essendo i segmenti di memoria
+utilizzati dai singoli processi completamente indipendenti, le modifiche delle
+variabili nei processi figli, come l'incremento di \var{i} in (\texttt{\small
+  31}), sono visibili solo a loro, (ogni processo vede solo la propria copia
+della memoria), e non hanno alcun effetto sul valore che le stesse variabili
+hanno nel processo padre ed in eventuali altri processi figli che eseguano lo
+stesso codice.
 
 Un secondo aspetto molto importante nella creazione dei processi figli è
 quello dell'interazione dei vari processi con i file. Ne parleremo qui anche
@@ -528,15 +529,15 @@ che come si vede è completamente diverso da quanto ottenevamo sul terminale.
 Il comportamento delle varie funzioni di interfaccia con i file è analizzato
 in gran dettaglio in sez.~\ref{sec:file_unix_interface} per l'interfaccia
 nativa Unix ed in sez.~\ref{sec:files_std_interface} per la standardizzazione
-adottata nelle librerie del linguaggio C e valida per qualunque sistema
-operativo. 
+adottata nelle librerie del linguaggio C, valida per qualunque sistema
+operativo.
 
 Qui basta accennare che si sono usate le funzioni standard della libreria del
 C che prevedono l'output bufferizzato. Il punto è che questa bufferizzazione
 (che tratteremo in dettaglio in sez.~\ref{sec:file_buffering}) varia a seconda
 che si tratti di un file su disco, in cui il buffer viene scaricato su disco
 solo quando necessario, o di un terminale, in cui il buffer viene scaricato ad
-ogni carattere di a capo.
+ogni carattere di ``a capo''.
 
 Nel primo esempio allora avevamo che, essendovi un a capo nella stringa
 stampata, ad ogni chiamata a \func{printf} il buffer veniva scaricato, per cui
@@ -566,19 +567,19 @@ 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 \textit{file descriptor} (vedi
 sez.~\ref{sec:file_fd}) dei file 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 \textit{file
-  table} (tratteremo in dettaglio questi termini in sez.~\ref{sec:file_fd} e
-sez.~\ref{sec:file_shared_access}) fra cui c'è anche la posizione corrente nel
-file.
-
-In questo modo se un processo scrive su un 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.
+in cui lo fa la funzione \func{dup}, trattata in sez.~\ref{sec:file_dup}). Ciò
+fa si che padre e figli condividano le stesse voci della \textit{file table}
+(tratteremo in dettaglio questi termini in sez.~\ref{sec:file_fd} e
+sez.~\ref{sec:file_shared_access}) fra le quali c'è anche la posizione
+corrente nel file.
+
+Quando un processo scrive su un file la posizione corrente viene aggiornata
+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 figli scrivono sullo stesso
+file usato dal padre, che una scrittura eseguita in un secondo tempo da un
+processo vada a sovrapporsi a quelle 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
@@ -586,9 +587,9 @@ scrivono sullo stesso file. Un caso tipico di questo comportamento è la shell
 quando lancia un programma.  In questo modo, anche se lo standard 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.
+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
@@ -771,10 +772,12 @@ terminato; si potrebbe avere cioè quello che si chiama un processo
 \textsl{orfano}.
 
 Questa complicazione viene superata facendo in modo che il processo orfano
-venga \textsl{adottato} da \cmd{init}, o meglio dal processo con \ids{PID} 1,
-cioè quello lanciato direttamente dal kernel all'avvio, che sta alla base
-dell'albero dei processi visto in sez.~\ref{sec:proc_hierarchy} e che anche
-per questo motivo ha un ruolo essenziale nel sistema e non può mai
+venga \textsl{adottato} da \cmd{init}, o meglio dal processo con \ids{PID}
+1,\footnote{anche se, come vedremo in sez.~\ref{sec:process_prctl}, a partire
+  dal kernel 3.4 è diventato possibile delegare questo compito anche ad un
+  altro processo.} cioè quello lanciato direttamente dal kernel all'avvio, che
+sta alla base dell'albero dei processi visto in sez.~\ref{sec:proc_hierarchy}
+e che anche per questo motivo ha un ruolo essenziale nel sistema e non può mai
 terminare.\footnote{almeno non senza un blocco completo del sistema, in caso
   di terminazione o di non esecuzione di \cmd{init} infatti il kernel si
   blocca con un cosiddetto \textit{kernel panic}, dato che questo è un errore
@@ -814,9 +817,10 @@ terminano, e come si può notare in questo caso, al contrario di quanto visto
 in precedenza, essi riportano 1 come \ids{PPID}.
 
 Altrettanto rilevante è il caso in cui il figlio termina prima del padre,
-perché non è detto che il padre possa ricevere immediatamente lo stato di
-terminazione, quindi il kernel deve comunque conservare una certa quantità di
-informazioni riguardo ai processi che sta terminando.
+perché non è detto che il padre sia in esecuzione e possa ricevere
+immediatamente lo stato di terminazione, quindi il kernel deve comunque
+conservare una certa quantità di informazioni riguardo ai processi che sta
+terminando.
 
 Questo viene fatto mantenendo attiva la voce nella tabella dei processi, e
 memorizzando alcuni dati essenziali, come il \ids{PID}, i tempi di CPU usati
@@ -985,9 +989,9 @@ sistema, \funcd{waitpid}, il cui prototipo è:
 
 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,
+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. 
+sono riportate anche le costanti definite per indicare alcuni di essi.
 
 \begin{table}[!htb]
   \centering
@@ -1024,8 +1028,8 @@ tabella si sono riportati anche alcune opzioni non standard specifiche di
 Linux, che consentono un controllo più dettagliato per i processi creati con
 la \textit{system call} generica \func{clone} (vedi
 sez.~\ref{sec:process_clone}) e che vengono usati principalmente per la
-gestione della terminazione dei \textit{thread} (vedi
-sez.~\ref{sec:thread_xxx}).
+gestione della terminazione dei \textit{thread}\unavref{ (vedi
+sez.~\ref{sec:thread_xxx})}.
 
 \begin{table}[!htb]
   \centering
@@ -1040,8 +1044,7 @@ sez.~\ref{sec:thread_xxx}).
     \const{WUNTRACED} & Ritorna anche quando un processo figlio è stato
                         fermato.\\ 
     \const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato
-                        fermato ha ripreso l'esecuzione (disponibile solo a
-                        partire dal kernel 2.6.10).\\
+                        fermato ha ripreso l'esecuzione (dal kernel 2.6.10).\\
     \hline
     \constd{\_\_WCLONE}& Attende solo per i figli creati con \func{clone} 
                         (vedi sez.~\ref{sec:process_clone}), vale a dire
@@ -1051,7 +1054,7 @@ sez.~\ref{sec:thread_xxx}).
                         processi figli ordinari ignorando quelli creati da
                         \func{clone}.\\
     \constd{\_\_WALL}  & Attende per qualunque figlio, sia ordinario che creato
-                        con  \func{clone}, se specificata insieme a
+                        con \func{clone}, se specificata con
                         \const{\_\_WCLONE} quest'ultima viene ignorata. \\
     \constd{\_\_WNOTHREAD}& Non attende per i figli di altri \textit{thread}
                         dello stesso \textit{thread group}, questo era il
@@ -1087,12 +1090,12 @@ Nel caso di \const{WUNTRACED} la funzione ritorna, restituendone il \ids{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:process_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
-\signal{SIGCONT} (l'uso di questi segnali per il controllo di sessione è
-trattato in sez.~\ref{sec:sess_ctrl_term}).
+  cui lo stato \textit{stopped} è dovuto all'uso di \func{ptrace}\unavref{
+    (vedi sez.~\ref{sec:process_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 \signal{SIGCONT} (l'uso di questi segnali per il
+controllo di sessione è trattato in sez.~\ref{sec:sess_ctrl_term}).
 
 \constend{WUNTRACED}
 \constend{WCONTINUED}
@@ -1102,10 +1105,10 @@ 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
-\signal{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.
+\signal{SIGCHLD} al padre. L'azione predefinita per questo segnale (si veda
+sez.~\ref{sec:sig_base}) è 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.
 
 Il comportamento delle funzioni è però cambiato nel passaggio dal kernel 2.4
 al kernel 2.6, quest'ultimo infatti si è adeguato alle prescrizioni dello
@@ -1139,15 +1142,15 @@ 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}, e se non
-interessa memorizzare lo stato si può passare un puntatore nullo. Il valore
-restituito da entrambe le funzioni dipende dall'implementazione, ma
-tradizionalmente gli 8 bit meno significativi sono riservati per memorizzare
-lo stato di uscita del processo, e gli altri per indicare il segnale che ha
-causato la terminazione (in caso di conclusione anomala), uno per indicare se
-è stato generato un \textit{core dump} (vedi sez.~\ref{sec:sig_standard}),
-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>}.}
+interessa memorizzarlo si può passare un puntatore nullo. Il valore restituito
+da entrambe le funzioni dipende dall'implementazione, ma tradizionalmente gli
+8 bit meno significativi sono riservati per memorizzare lo stato di uscita del
+processo, e gli altri per indicare il segnale che ha causato la terminazione
+(in caso di conclusione anomala), uno per indicare se è stato generato un
+\textit{core dump} (vedi sez.~\ref{sec:sig_standard}), 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>}.}
 
 \begin{table}[!htb]
   \centering
@@ -1391,6 +1394,12 @@ creato un nuovo processo, la funzione semplicemente rimpiazza lo
 programma letto da disco, eseguendo il \textit{link-loader} con gli effetti
 illustrati in sez.~\ref{sec:proc_main}.
 
+\begin{figure}[!htb]
+  \centering \includegraphics[width=8cm]{img/exec_rel}
+  \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
+  \label{fig:proc_exec_relat}
+\end{figure}
+
 Ci sono sei diverse versioni di \func{exec} (per questo la si è chiamata
 famiglia di funzioni) che possono essere usate per questo compito, in realtà
 (come mostrato in fig.~\ref{fig:proc_exec_relat}), tutte queste funzioni sono
@@ -1398,7 +1407,7 @@ tutte varianti che consentono di invocare in modi diversi, semplificando il
 passaggio degli argomenti, la funzione di sistema \funcd{execve}, il cui
 prototipo è:
 
-\begin{funcproto}{ 
+\begin{funcproto}{
 \fhead{unistd.h}
 \fdecl{int execve(const char *filename, char *const argv[], char *const envp[])}
 \fdesc{Esegue un programma.} 
@@ -1410,15 +1419,18 @@ prototipo è:
     eseguibili, o il file è su un filesystem montato con l'opzione
     \cmd{noexec}, o manca  il permesso di attraversamento di una delle
     directory del \textit{pathname}.
+  \item[\errcode{EAGAIN}] dopo un cambio di \ids{UID} si è ancora  sopra il
+    numero massimo di processi consentiti per l'utente (dal kernel 3.1, per i
+    dettagli vedi sez.~\ref{sec:proc_setuid}).
   \item[\errcode{EINVAL}] l'eseguibile ELF ha più di un segmento
     \const{PT\_INTERP}, cioè chiede di essere eseguito da più di un
     interprete.
   \item[\errcode{ELIBBAD}] un interprete ELF non è in un formato
     riconoscibile.
-  \item[\errcode{ENOEXEC}] il file è in un formato non eseguibile o non
-    riconosciuto come tale, o compilato per un'altra architettura.
   \item[\errcode{ENOENT}] il file o una delle librerie dinamiche o l'interprete
     necessari per eseguirlo non esistono.
+  \item[\errcode{ENOEXEC}] il file è in un formato non eseguibile o non
+    riconosciuto come tale, o compilato per un'altra architettura.
   \item[\errcode{EPERM}] il file ha i bit \acr{suid} o \acr{sgid} e l'utente
     non è root, ed il processo viene tracciato, oppure il filesystem è montato
     con l'opzione \cmd{nosuid}. 
@@ -1444,8 +1456,8 @@ torneremo in sez.~\ref{sec:sys_res_limits}).
 
 In caso di successo la funzione non ritorna, in quanto al posto del programma
 chiamante viene eseguito il nuovo programma indicato da \param{filename}. Se
-il processo corrente è tracciato con \func{ptrace} (vedi
-sez.~\ref{sec:process_ptrace}) in caso di successo viene emesso il segnale
+il processo corrente è tracciato con \func{ptrace}\unavref{ (vedi
+sez.~\ref{sec:process_ptrace})} in caso di successo viene emesso il segnale
 \signal{SIGTRAP}.
 
 Le altre funzioni della famiglia (\funcd{execl}, \funcd{execv},
@@ -1519,12 +1531,6 @@ che deve essere terminata da un puntatore nullo.  In entrambi i casi vale la
 convenzione che il primo argomento (\var{arg0} o \var{argv[0]}) viene usato
 per indicare il nome del file che contiene il programma che verrà eseguito.
 
-\begin{figure}[!htb]
-  \centering \includegraphics[width=9cm]{img/exec_rel}
-  \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
-  \label{fig:proc_exec_relat}
-\end{figure}
-
 La seconda differenza fra le funzioni riguarda le modalità con cui si
 specifica il programma che si vuole eseguire. Con lo mnemonico ``\texttt{p}''
 si indicano le due funzioni che replicano il comportamento della shell nello
@@ -1573,10 +1579,8 @@ seguente:
 \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});
-% TODO ===========Importante=============
-% TODO questo sotto è incerto, verificare
-% TODO ===========Importante=============
-\item la maschera dei segnali (si veda sez.~\ref{sec:sig_sigmask}).
+\item la maschera dei segnali (si veda sez.~\ref{sec:sig_sigmask});
+\item l'insieme dei segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}).
 \end{itemize*}
 
 Una serie di proprietà del processo originale, che non avrebbe senso mantenere
@@ -1585,8 +1589,6 @@ indirizzi totalmente indipendente e ricreato da zero, vengono perse con
 l'esecuzione di una \func{exec}. Lo standard POSIX.1-2001 prevede che le
 seguenti proprietà non vengano preservate:
 \begin{itemize*}
-\item l'insieme dei segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che
-  viene cancellato;
 \item gli eventuali stack alternativi per i segnali (vedi
   sez.~\ref{sec:sig_specific_features});
 \item i \textit{directory stream} (vedi sez.~\ref{sec:file_dir_read}), che
@@ -1620,9 +1622,9 @@ nell'esecuzione della funzione \func{exec}, queste sono:
   pendenti vengono cancellate;
 \item le \textit{capabilities} vengono modificate come
   illustrato in sez.~\ref{sec:proc_capabilities};
-\item tutti i \textit{thread} tranne il chiamante (vedi
-  sez.~\ref{sec:thread_xxx}) sono cancellati e tutti gli oggetti ad essi
-  relativi (vedi sez.~\ref{sec:thread_xxx}) rimossi;
+\item tutti i \textit{thread} tranne il chiamante\unavref{ (vedi
+    sez.~\ref{sec:thread_xxx})} vengono cancellati e tutti gli oggetti ad essi
+  relativi\unavref{ (vedi sez.~\ref{sec:thread_xxx})} sono rimossi;
 \item viene impostato il flag \const{PR\_SET\_DUMPABLE} di \func{prctl} (vedi
   sez.~\ref{sec:process_prctl}) a meno che il programma da eseguire non sia
   \acr{suid} o \acr{sgid} (vedi sez.~\ref{sec:proc_access_id} e
@@ -1898,31 +1900,74 @@ sez.~\ref{sec:proc_access_id} seguono la semantica POSIX che prevede
 l'esistenza dell'\ids{UID} salvato e del \ids{GID} salvato, sono
 rispettivamente \funcd{setuid} e \funcd{setgid}; i loro prototipi sono:
 
-\begin{funcproto}{ 
+\begin{funcproto}{
 \fhead{unistd.h}
 \fhead{sys/types.h}
 \fdecl{int setuid(uid\_t uid)}
-\fdesc{Imposta l'\ids{UID} del processo corrente.} 
+\fdesc{Imposta l'\ids{UID} del processo corrente.}
 \fdecl{int setgid(gid\_t gid)}
-\fdesc{Imposta il \ids{GID} del processo corrente.} 
+\fdesc{Imposta il \ids{GID} del processo corrente.}
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} uno dei valori: 
+\begin{errlist}
+\item[\errcode{EAGAIN}] (solo per \func{setuid}) la chiamata cambierebbe
+  l'\ids{UID} reale ma il kernel non dispone temporaneamente delle risorse per
+  farlo, oppure, per i kernel precendenti il 3.1, il cambiamento
+  dell'\ids{UID} reale farebbe superare il limite per il numero dei processi
+  \const{RLIMIT\_NPROC} (vedi sez.~\ref{sec:sys_resource_limit}).
+\item[\errcode{EINVAL}] il valore di dell'argomento non è valido per il
+    \textit{namespace} corrente (vedi sez.~\ref{sec:process_namespaces}).
+\item[\errcode{EPERM}] non si hanno i permessi per l'operazione richiesta.
+\end{errlist} 
 }
 \end{funcproto}
 
 Il funzionamento di queste due funzioni è analogo, per cui considereremo solo
 la prima, la seconda si comporta esattamente allo stesso modo facendo
-riferimento al \ids{GID} invece che all'\ids{UID}.  Gli eventuali \ids{GID}
+riferimento al \ids{GID} invece che all'\ids{UID}. Gli eventuali \ids{GID}
 supplementari non vengono modificati.
 
 L'effetto della chiamata è diverso a seconda dei privilegi del processo; se
-l'\ids{UID} effettivo è zero (cioè è quello dell'amministratore di sistema)
-allora tutti gli identificatori (\textit{real}, \textit{effective} e
-\textit{saved}) vengono impostati al valore specificato da \param{uid},
-altrimenti viene impostato solo l'\ids{UID} effettivo, e soltanto se il valore
-specificato corrisponde o all'\ids{UID} reale o all'\ids{UID} salvato. Negli
-altri casi viene segnalato un errore con \errcode{EPERM}.
+l'\ids{UID} effettivo è zero (cioè è quello dell'amministratore di sistema o
+il processo ha la la capacità \const{CAP\_SETUID}) allora tutti gli
+identificatori (\textit{real}, \textit{effective} e \textit{saved}) vengono
+impostati al valore specificato da \param{uid}, altrimenti viene impostato
+solo l'\ids{UID} effettivo, e soltanto se il valore specificato corrisponde o
+all'\ids{UID} reale o all'\ids{UID} salvato, ottenendo un errore di
+\errcode{EPERM} negli altri casi.
+
+E' importante notare che la funzione può fallire, con
+\errval{EAGAIN},\footnote{non affronteremo qui l'altro caso di errore, che può
+  avvenire solo quando si esegue la funzione all'interno di un diverso
+  \textit{user namespace}, argomento su cui torneremo in
+  sez.~\ref{sec:process_namespaces} ma la considerazione di controllare sempre
+  lo stato di uscita si applica allo stesso modo.} anche quando viene invocata
+da un processo con privilegi di amministratore per cambiare il proprio
+l'\ids{UID} reale, sia per una temporanea indisponibilità di risorse del
+kernel, sia perché l'utente di cui si vuole assumere l'\ids{UID} andrebbe a
+superare un eventuale limite sul numero di processi (il limite
+\const{RLIMIT\_NPROC}, che tratteremo in sez.~\ref{sec:sys_resource_limit}),
+pertanto occorre sempre verificare lo stato di uscita della funzione.
+
+Non controllare questo tipo di errori perché si presume che la funzione abbia
+sempre successo quando si hanno i privilegi di amministratore può avere
+conseguente devastanti per la sicurezza, in particolare quando la si usa per
+cedere i suddetti privilegi ed eseguire un programma per conto di un utente
+non privilegiato.
+
+E' per diminuire l'impatto di questo tipo di disattenzioni che a partire dal
+kernel 3.1 il comportamento di \func{setuid} e di tutte le analoghe funzioni
+che tratteremo nel seguito di questa sezione è stato modificato e nel caso di
+superamento del limite sulle risorse esse hanno comunque successo. Quando
+questo avviene il processo assume comunque il nuovo \ids{UID} ed il controllo
+sul superamento di \const{RLIMIT\_NPROC} viene posticipato ad una eventuale
+successiva invocazione di \func{execve} (essendo questo poi il caso d'uso più
+comune). In tal caso, se alla chiamata ancora sussiste la situazione di
+superamento del limite, sarà \func{execve} a fallire con un errore di
+\const{EAGAIN}.\footnote{che pertanto, a partire dal kernel 3.1, può
+  restituire anche questo errore, non presente in altri sistemi
+  \textit{unix-like}.}
 
 Come accennato l'uso principale di queste funzioni è quello di poter
 consentire ad un programma con i bit \acr{suid} o \acr{sgid} impostati (vedi
@@ -1934,12 +1979,14 @@ Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
 viene gestito l'accesso al file \sysfiled{/var/run/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
-\sysfiled{/var/log/wtmp} su cui vengono registrati login e logout) appartengono
-ad un gruppo dedicato (in genere \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.
+falsificare la registrazione.
+
+Per questo motivo questo file (e l'analogo \sysfiled{/var/log/wtmp} su cui
+vengono registrati login e logout) appartengono ad un gruppo dedicato (in
+genere \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.
 
 Quando uno di questi programmi (ad esempio \cmd{xterm}) viene lanciato, la
 situazione degli identificatori è la seguente:
@@ -1981,10 +2028,10 @@ 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
 \func{setuid} comporta il cambiamento di tutti gli identificatori associati al
 processo, rendendo impossibile riguadagnare i privilegi di amministratore.
-Questo comportamento è corretto per l'uso che ne fa \cmd{login} una volta che
-crea una nuova shell per l'utente, ma quando si vuole cambiare soltanto
-l'\ids{UID} effettivo del processo per cedere i privilegi occorre
-ricorrere ad altre funzioni.
+Questo comportamento è corretto per l'uso che ne fa un programma come
+\cmd{login} una volta che crea una nuova shell per l'utente, ma quando si
+vuole cambiare soltanto l'\ids{UID} effettivo del processo per cedere i
+privilegi occorre ricorrere ad altre funzioni.
 
 Le due funzioni di sistema \funcd{setreuid} e \funcd{setregid} derivano da BSD
 che, non supportando (almeno fino alla versione 4.3+BSD) gli identificatori
@@ -2000,7 +2047,7 @@ del gruppo \textit{saved}, le usa per poter scambiare fra di loro
 \fdesc{Imposta \ids{GID} reale e \ids{GID} effettivo del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} assume i valori visti per \func{setuid}/\func{setgid}.
 }
 \end{funcproto}
 
@@ -2008,12 +2055,13 @@ Le due funzioni sono identiche, quanto diremo per la prima riguardo gli
 \ids{UID} si applica alla seconda per i \ids{GID}.  La funzione
 \func{setreuid} imposta rispettivamente l'\ids{UID} reale e l'\ids{UID}
 effettivo del processo corrente ai valori specificati da \param{ruid}
-e \param{euid}.  I processi non privilegiati possono impostare solo valori che
-corrispondano o al loro \ids{UID} effettivo o a quello reale o a quello
-salvato, valori diversi comportano il fallimento della chiamata.
-L'amministratore invece può specificare un valore qualunque.  Specificando un
-argomento di valore $-1$ l'identificatore corrispondente verrà lasciato
-inalterato.
+e \param{euid}.
+
+I processi non privilegiati possono impostare solo valori che corrispondano o
+al loro \ids{UID} effettivo o a quello reale o a quello salvato, valori
+diversi comportano il fallimento della chiamata.  L'amministratore invece può
+specificare un valore qualunque.  Specificando un argomento di valore $-1$
+l'identificatore corrispondente verrà lasciato inalterato.
 
 Con queste funzioni si possono scambiare fra loro gli \ids{UID} reale ed
 effettivo, e pertanto è possibile implementare un comportamento simile a
@@ -2052,7 +2100,8 @@ del gruppo \textit{effective} ed i loro prototipi sono:
 \fdesc{Imposta il \ids{GID} effettivo del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+  caso \var{errno} assume i valori visti per \func{setuid}/\func{setgid}
+  tranne \errval{EAGAIN}. 
 }
 \end{funcproto}
 
@@ -2079,7 +2128,7 @@ un completo controllo su tutti e tre i gruppi di identificatori
 \fdesc{Imposta il \ids{GID} reale, effettivo e salvato del processo corrente.} 
 }
 {Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual
-caso \var{errno} può assumere solo il valore \errcode{EPERM}.
+caso \var{errno} assume i valori visti per \func{setuid}/\func{setgid}.
 }
 \end{funcproto}
 
@@ -2088,7 +2137,7 @@ gli \ids{UID} si applica alla seconda per i \ids{GID}.  La funzione
 \func{setresuid} imposta l'\ids{UID} reale, l'\ids{UID} effettivo e
 l'\ids{UID} salvato del processo corrente ai valori specificati
 rispettivamente dagli argomenti \param{ruid}, \param{euid} e \param{suid}.  I
-processi non privilegiati possono cambiare uno qualunque degli\ids{UID} solo
+processi non privilegiati possono cambiare uno qualunque degli \ids{UID} solo
 ad un valore corrispondente o all'\ids{UID} reale, o a quello effettivo o a
 quello salvato, l'amministratore può specificare i valori che vuole. Un valore
 di $-1$ per un qualunque argomento lascia inalterato l'identificatore
@@ -2154,9 +2203,10 @@ programmi portabili; i loro prototipi sono:
 \fdecl{int setfsgid(gid\_t fsgid)}
 \fdesc{Legge il \ids{GID} di filesystem del processo corrente.} 
 }
-{Le funzioni restituiscono il nuovo valore dell'identificativo in caso di
-  successo e quello corrente per un errore, in questo caso non viene però
-  impostato nessun codice di errore in \var{errno}.}
+
+{Le funzioni restituiscono sia in caso di successo che di errore il valore
+  corrente dell'identificativo, e in caso di errore non viene impostato nessun
+  codice in \var{errno}.}
 \end{funcproto}
 
 Le due funzioni sono analoghe ed usano il valore passato come argomento per
@@ -2165,6 +2215,12 @@ solo se il processo chiamante ha i privilegi di amministratore o, per gli
 altri utenti, se il valore specificato coincide con uno dei di quelli del
 gruppo \textit{real}, \textit{effective} o \textit{saved}.
 
+Il problema di queste funzioni è che non restituiscono un codice di errore e
+non c'è modo di sapere (con una singola chiamata) di sapere se hanno avuto
+successo o meno, per verificarlo occorre eseguire una chiamata aggiuntiva
+passando come argomento $-1$ (un valore impossibile per un identificativo),
+così fallendo si può di ottenere il valore corrente e verificare se è
+cambiato.
 
 \subsection{Le funzioni per la gestione dei gruppi associati a un processo}
 \label{sec:proc_setgroups}
@@ -2200,8 +2256,8 @@ La funzione legge gli identificatori dei gruppi supplementari del processo sul
 vettore \param{list} che deve essere di dimensione pari a \param{size}. Non è
 specificato se la funzione inserisca o meno nella lista il \ids{GID} effettivo
 del processo. Se si specifica un valore di \param{size} uguale a $0$ allora
-l'argomento \param{list} non viene modificato, ma si ottiene il numero di
-gruppi supplementari.
+l'argomento \param{list} non viene modificato, ma si ottiene dal valore di
+ritorno il numero di gruppi supplementari.
 
 Una seconda funzione, \funcd{getgrouplist}, può invece essere usata per
 ottenere tutti i gruppi a cui appartiene utente identificato per nome; il suo
@@ -2342,7 +2398,7 @@ tempo.  In tutti questi casi la CPU diventa disponibile ed è compito dello
 kernel provvedere a mettere in esecuzione un altro processo.
 
 Tutte queste possibilità sono caratterizzate da un diverso \textsl{stato} del
-processo, in Linux un processo può trovarsi in uno degli stati riportati in
+processo; in Linux un processo può trovarsi in uno degli stati riportati in
 tab.~\ref{tab:proc_proc_states}; ma soltanto i processi che sono nello stato
 \textit{runnable} concorrono per l'esecuzione. Questo vuol dire che, qualunque
 sia la sua priorità, un processo non potrà mai essere messo in esecuzione
@@ -2357,7 +2413,7 @@ fintanto che esso si trova in uno qualunque degli altri stati.
     \hline
     \hline
     \textit{runnable}& \texttt{R} & Il processo è in esecuzione o è pronto ad
-                                    essere eseguito (cioè è in attesa che gli
+                                    essere eseguito (in attesa che gli
                                     venga assegnata la CPU).\\
     \textit{sleep}   & \texttt{S} & Il processo  è in attesa di un
                                     risposta dal sistema, ma può essere 
@@ -2441,9 +2497,9 @@ prevede solo priorità dinamiche. È di questo che, di norma, ci si dovrà
 preoccupare nella programmazione.  Come accennato in Linux i processi ordinari
 hanno tutti una priorità assoluta nulla; quello che determina quale, fra tutti
 i processi in attesa di esecuzione, sarà eseguito per primo, è la cosiddetta
-\textsl{priorità dinamica},\footnote{quella che viene mostrata nella colonna
-  \texttt{PR} del comando \texttt{top}.} che è chiamata così proprio perché
-varia nel corso dell'esecuzione di un processo.
+\textsl{priorità dinamica}, quella che viene mostrata nella colonna
+\texttt{PR} del comando \texttt{top}, che è chiamata così proprio perché varia
+nel corso dell'esecuzione di un processo.
 
 Il meccanismo usato da Linux è in realtà piuttosto complesso,\footnote{e
   dipende strettamente dalla versione di kernel; in particolare a partire
@@ -2463,18 +2519,19 @@ in stato \textit{runnable} ma non viene posto in esecuzione.\footnote{in
   processo mettere in esecuzione avviene con un algoritmo molto più
   complicato, che tiene conto anche della \textsl{interattività} del processo,
   utilizzando diversi fattori, questa è una brutale semplificazione per
-  rendere l'idea del funzionamento, per una trattazione più dettagliata, anche
-  se non aggiornatissima, dei meccanismi di funzionamento dello
-  \textit{scheduler} si legga il quarto capitolo di \cite{LinKernDev}.} Lo
-\textit{scheduler} infatti mette sempre in esecuzione, fra tutti i processi in
-stato \textit{runnable}, quello che ha il valore di priorità dinamica più
-basso.\footnote{con le priorità dinamiche il significato del valore numerico
-  ad esse associato è infatti invertito, un valore più basso significa una
-  priorità maggiore.} Il fatto che questo valore venga diminuito quando un
-processo non viene posto in esecuzione pur essendo pronto, significa che la
-priorità dei processi che non ottengono l'uso del processore viene
-progressivamente incrementata, così che anche questi alla fine hanno la
-possibilità di essere eseguiti.
+  rendere l'idea del funzionamento, per una trattazione più dettagliata dei
+  meccanismi di funzionamento dello \textit{scheduler}, anche se non
+  aggiornatissima, si legga il quarto capitolo di \cite{LinKernDev}.}
+
+Lo \textit{scheduler} infatti mette sempre in esecuzione, fra tutti i processi
+in stato \textit{runnable}, quello che ha il valore di priorità dinamica più
+basso; con le priorità dinamiche il significato del valore numerico ad esse
+associato è infatti invertito, un valore più basso significa una priorità
+maggiore. Il fatto che questo valore venga diminuito quando un processo non
+viene posto in esecuzione pur essendo pronto, significa che la priorità dei
+processi che non ottengono l'uso del processore viene progressivamente
+incrementata, così che anche questi alla fine hanno la possibilità di essere
+eseguiti.
 
 Sia la dimensione della \textit{time-slice} che il valore di partenza della
 priorità dinamica sono determinate dalla cosiddetta \textit{nice} (o
@@ -2573,19 +2630,18 @@ caso \var{errno} assumerà uno dei valori:
 \end{errlist}}
 \end{funcproto}
 
-La funzione permette, a seconda di quanto specificato
-nell'argomento \param{which}, di leggere il valore di \textit{nice} di un
-processo, di un gruppo di processi (vedi sez.~\ref{sec:sess_proc_group}) o di
-un utente indicato dall'argomento \param{who}. Nelle vecchie versioni può
-essere necessario includere anche \headfiled{sys/time.h}, questo non è più
-necessario con versioni recenti delle librerie, ma è comunque utile per
-portabilità.
+La funzione permette, a seconda di quanto specificato nell'argomento
+\param{which}, di leggere il valore di \textit{nice} o di un processo, o di un
+gruppo di processi (vedi sez.~\ref{sec:sess_proc_group}) o di un utente,
+indicati con l'argomento \param{who}. Nelle vecchie versioni può essere
+necessario includere anche \headfiled{sys/time.h}, questo non è più necessario
+con versioni recenti delle librerie, ma è comunque utile per portabilità.
 
 I valori possibili per \param{which}, ed il tipo di valore che occorre usare
-in corrispondenza per \param{who} solo elencati nella legenda di
+in corrispondenza per \param{who}, solo elencati nella legenda di
 tab.~\ref{tab:proc_getpriority} insieme ai relativi significati. Usare un
 valore nullo per \param{who} indica, a seconda della corrispondente
-indicazione usata per \param{which} il processo, il gruppo di processi o
+indicazione usata per \param{which}, il processo, il gruppo di processi o
 l'utente correnti.
 
 \begin{table}[htb]
@@ -2610,7 +2666,7 @@ l'utente correnti.
 
 In caso di una indicazione che faccia riferimento a più processi, la funzione
 restituisce la priorità più alta (cioè il valore più basso) fra quelle dei
-processi corrispondenti. Come per \func{nice} $-1$ è un valore possibile
+processi corrispondenti. Come per \func{nice}, $-1$ è un possibile valore
 corretto, per cui di nuovo per poter rilevare una condizione di errore è
 necessario cancellare sempre \var{errno} prima della chiamata alla funzione e
 quando si ottiene un valore di ritorno uguale a $-1$ per verificare che essa
@@ -2645,9 +2701,9 @@ i quali valgono le stesse considerazioni fatte per \func{getpriority} e lo
 specchietto di tab.~\ref{tab:proc_getpriority}. 
 
 In questo caso come valore di \param{prio} deve essere specificato il valore
-di \textit{nice} da assegnare, e non un incremento (positivo o negativo) come
-nel caso di \func{nice}, nell'intervallo fra \const{PRIO\_MIN} ($-20$) e
-\const{PRIO\_MAX} ($19$). La funzione restituisce il valore di \textit{nice}
+di \textit{nice} da assegnare nell'intervallo fra \const{PRIO\_MIN} ($-20$) e
+\const{PRIO\_MAX} ($19$), e non un incremento (positivo o negativo) come nel
+caso di \func{nice}. La funzione restituisce il valore di \textit{nice}
 assegnato in caso di successo e $-1$ in caso di errore, e come per \func{nice}
 anche in questo caso per rilevare un errore occorre sempre porre a zero
 \var{errno} prima della chiamata della funzione, essendo $-1$ un valore di
@@ -2679,33 +2735,33 @@ valore di \textit{nice} è cambiato parecchio nelle progressive riscritture
 dello \textit{scheduler} di Linux, ed in particolare a partire dal kernel
 2.6.23 l'uso di diversi valori di \textit{nice} ha un impatto molto più forte
 nella distribuzione della CPU ai processi. Infatti se viene comunque calcolata
-una priorità dinamica per i processi che non ricevono la CPU così che anche
+una priorità dinamica per i processi che non ricevono la CPU, così che anche
 essi possano essere messi in esecuzione, un alto valore di \textit{nice}
 corrisponde comunque ad una \textit{time-slice} molto piccola che non cresce
 comunque, per cui un processo a bassa priorità avrà davvero scarse possibilità
 di essere eseguito in presenza di processi attivi a priorità più alta.
 
 
-
 \subsection{Il meccanismo di \textit{scheduling real-time}}
 \label{sec:proc_real_time}
 
 Come spiegato in sez.~\ref{sec:proc_sched} lo standard POSIX.1b ha introdotto
-le priorità assolute per permettere la gestione di processi real-time. In
-realtà nel caso di Linux non si tratta di un vero \textit{hard real-time}, in
-quanto in presenza di eventuali interrupt il kernel interrompe l'esecuzione di
-un processo qualsiasi sia la sua priorità,\footnote{questo a meno che non si
-  siano installate le patch di RTLinux, RTAI o Adeos, con i quali è possibile
-  ottenere un sistema effettivamente \textit{hard real-time}. In tal caso
-  infatti gli interrupt vengono intercettati dall'interfaccia
-  \textit{real-time} (o nel caso di 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} 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.
+le priorità assolute per permettere la gestione di processi
+\textit{real-time}. In realtà nel caso di Linux non si tratta di un vero
+\textit{hard real-time}, in quanto in presenza di eventuali interrupt il
+kernel interrompe l'esecuzione di un processo, qualsiasi sia la sua
+priorità,\footnote{questo a meno che non si siano installate le patch di
+  RTLinux, RTAI o Adeos, con i quali è possibile ottenere un sistema
+  effettivamente \textit{hard real-time}. In tal caso infatti gli interrupt
+  vengono intercettati dall'interfaccia \textit{real-time} (o nel caso di
+  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} 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.
 
 Nonostante questo, ed in particolare con una serie di miglioramenti che sono
 stati introdotti nello sviluppo del kernel,\footnote{in particolare a partire
@@ -2768,15 +2824,15 @@ ordinarie o viceversa, che di specificare, in caso di politiche
 caso \var{errno} assumerà uno dei valori:
 \begin{errlist}
     \item[\errcode{EINVAL}] il valore di \param{policy} non esiste o il
-      relativo valore di \param{p} non è valido per la politica scelta.
+      valore di \param{p} non è valido per la politica scelta.
     \item[\errcode{EPERM}] il processo non ha i privilegi per attivare la
       politica richiesta.
     \item[\errcode{ESRCH}] il processo \param{pid} non esiste.
- \end{errlist}}
   \end{errlist}}
 \end{funcproto}
 
 La funzione esegue l'impostazione per il processo specificato dall'argomento
-\param{pid}, un valore nullo di questo argomento esegue l'impostazione per il
+\param{pid}; un valore nullo di questo argomento esegue l'impostazione per il
 processo corrente.  La politica di \textit{scheduling} è specificata
 dall'argomento \param{policy} i cui possibili valori sono riportati in
 tab.~\ref{tab:proc_sched_policy}; la parte alta della tabella indica le
@@ -2813,6 +2869,7 @@ corrente.
 % TODO Aggiungere SCHED_DEADLINE, sulla nuova politica di scheduling aggiunta
 % con il kernel 3.14, vedi anche Documentation/scheduler/sched-deadline.txt e
 % http://lwn.net/Articles/575497/
+% vedi anche man 7 sched, man sched_setattr
 
 Con le versioni più recenti del kernel sono state introdotte anche delle
 varianti sulla politica di \textit{scheduling} tradizionale per alcuni carichi
@@ -2827,9 +2884,9 @@ di \textit{sleep}.\footnote{cosa che accade con grande frequenza per i
   processi interattivi, dato che essi sono per la maggior parte del tempo in
   attesa di dati in ingresso da parte dell'utente.} La si usa pertanto, come
 indica il nome, per processi che usano molta CPU (come programmi di calcolo)
-che in questo modo sono leggermente sfavoriti rispetto ai processi interattivi
-che devono rispondere a dei dati in ingresso, pur non perdendo il loro valore
-di \textit{nice}.
+che in questo modo, pur non perdendo il loro valore di \textit{nice}, sono
+leggermente sfavoriti rispetto ai processi interattivi che devono rispondere a
+dei dati in ingresso.
 
 La politica \const{SCHED\_IDLE} invece è una politica dedicata ai processi che
 si desidera siano eseguiti con la più bassa priorità possibile, ancora più
@@ -2848,7 +2905,7 @@ standard prevede che questo debba essere assegnato all'interno di un
 intervallo fra un massimo ed un minimo che nel caso di Linux sono
 rispettivamente 1 e 99.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{0.5\textwidth}
     \includestruct{listati/sched_param.c}
@@ -2883,9 +2940,9 @@ prototipi sono:
 \end{errlist}}
 \end{funcproto}
 
-Le funzioni ritornano rispettivamente i due valori della massima e minima
-priorità statica possano essere ottenuti per una delle politiche di
-\textit{scheduling} \textit{real-time} indicata dall'argomento \param{policy}.
+Le funzioni ritornano rispettivamente il valore massimo e minimo usabile per
+la priorità statica di una delle politiche di \textit{scheduling}
+\textit{real-time} indicata dall'argomento \param{policy}.
 
 Si tenga presente che quando si imposta una politica di \textit{scheduling}
 real-time per un processo o se ne cambia la priorità statica questo viene
@@ -2900,8 +2957,8 @@ politica scelta è \const{SCHED\_FIFO} quando il processo viene eseguito viene
 automaticamente rimesso in coda alla lista, e la sua esecuzione continua
 fintanto che non viene bloccato da una richiesta di I/O, o non rilascia
 volontariamente la CPU (in tal caso, tornando nello stato \textit{runnable}
-sarà reinserito in coda alla lista); l'esecuzione viene ripresa subito solo
-nel caso che esso sia stato interrotto da un processo a priorità più alta.
+sarà in coda alla lista); l'esecuzione viene ripresa subito solo nel caso che
+esso sia stato interrotto da un processo a priorità più alta.
 
 Solo un processo con i privilegi di amministratore\footnote{più precisamente
   con la capacità \const{CAP\_SYS\_NICE}, vedi
@@ -3055,7 +3112,7 @@ comportava che i processi venissero messi in fondo alla coda di quelli attivi,
 con la possibilità di essere rimessi in esecuzione entro breve tempo, con
 l'introduzione del \textit{Completely Fair Scheduler} questo comportamento è
 cambiato ed un processo che chiama la funzione viene inserito nella lista dei
-processi inattivo, con un tempo molto maggiore.\footnote{è comunque possibile
+processi inattivi, con un tempo molto maggiore.\footnote{è comunque possibile
   ripristinare un comportamento analogo al precedente scrivendo il valore 1
   nel file \sysctlfiled{kernel/sched\_compat\_yield}.}
 
@@ -3175,13 +3232,13 @@ questa viene ereditata attraverso una \func{fork}, in questo modo diventa
 possibile legare automaticamente un gruppo di processi ad un singolo
 processore.
 
-Nell'uso comune, almeno con i kernel successivi alla serie 2.6.x, l'uso di
+Nell'uso comune, almeno con i kernel successivi alla serie 2.6.x, utilizzare
 questa funzione non è necessario, in quanto è lo \textit{scheduler} stesso che
 provvede a mantenere al meglio l'affinità di processore. Esistono però
 esigenze particolari, ad esempio quando un processo (o un gruppo di processi)
 è utilizzato per un compito importante (ad esempio per applicazioni
 \textit{real-time} o la cui risposta è critica) e si vuole la massima
-velocità, e con questa interfaccia diventa possibile selezionare gruppi di
+velocità; con questa interfaccia diventa possibile selezionare gruppi di
 processori utilizzabili in maniera esclusiva.  Lo stesso dicasi quando
 l'accesso a certe risorse (memoria o periferiche) può avere un costo diverso a
 seconda del processore, come avviene nelle architetture NUMA
@@ -3208,10 +3265,10 @@ cui ogni bit corrisponde ad un processore, ma oggi esistono architetture in
 cui questo numero può non essere sufficiente, e per questo è stato creato
 questo tipo opaco e una interfaccia di gestione che permette di usare a basso
 livello un tipo di dato qualunque rendendosi indipendenti dal numero di bit e
-dalla loro disposizione.  Per questo le funzioni richiedono anche che oltre
-all'insieme di processori si indichi anche la dimensione dello stesso con
-l'argomento \param{setsize}, per il quale, se non si usa l'allocazione
-dinamica che vedremo a breve, ed è in genere sufficiente passare il valore
+dalla loro disposizione.  Per questo le funzioni di libreria richiedono che
+oltre all'insieme di processori si indichi anche la dimensione dello stesso
+con l'argomento \param{setsize}, per il quale, se non si usa l'allocazione
+dinamica che vedremo a breve, è in genere sufficiente passare il valore
 \code{sizeof(cpu\_set\_t)}.
 
 L'interfaccia di gestione degli insiemi di processori, oltre alla definizione
@@ -3250,7 +3307,7 @@ presente, diverso da zero se è presente).
 Si tenga presente che trattandosi di macro l'argomento \param{cpu} può essere
 valutato più volte. Questo significa ad esempio che non si può usare al suo
 posto una funzione o un'altra macro, altrimenti queste verrebbero eseguite più
-volte, l'argomento cioè non deve avere \textsl{effetti collaterali} (in gergo
+volte; l'argomento cioè non deve avere \textsl{effetti collaterali} (in gergo
  \textit{side effects}).\footnote{nel linguaggio C si
   parla appunto di \textit{side effects} quando si usano istruzioni la cui
   valutazione comporta effetti al di fuori dell'istruzione stessa, come il
@@ -3261,13 +3318,13 @@ volte, l'argomento cioè non deve avere \textsl{effetti collaterali} (in gergo
 \itindend{side~effects}
 
 
-Le CPU sono numerate da zero (che indica la prima disponibile) fino ad
-un numero massimo che dipende dalla architettura hardware. La costante
+Le CPU sono numerate da zero (che indica la prima disponibile) fino ad un
+numero massimo che dipende dall'architettura hardware. La costante
 \constd{CPU\_SETSIZE} indica il numero massimo di processori che possono far
 parte di un insieme (al momento vale sempre 1024), e costituisce un limite
-massimo al valore dell'argomento \param{cpu}.
-Dalla versione 2.6 della \acr{glibc} alle precedenti macro è stata aggiunta,
-per contare il numero di processori in un insieme, l'ulteriore:
+massimo al valore dell'argomento \param{cpu}.  Dalla versione 2.6 della
+\acr{glibc} alle precedenti macro è stata aggiunta, per contare il numero di
+processori in un insieme, l'ulteriore:
 
 {\centering
 \vspace{3pt}
@@ -4234,6 +4291,10 @@ elenco, che illustra quelle attualmente disponibili:\footnote{si fa
 \end{basedescript}
 
 
+\subsection{I \textit{namespace} ed i \textit{container}}
+\label{sec:process_namespaces}
+
+
 %TODO sezione separata sui namespace 
 
 %TODO trattare unshare, vedi anche http://lwn.net/Articles/532748/
@@ -4503,7 +4564,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % 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 thread Ingo Molnar ppid getpid getppid sys unistd LD threads
-% LocalWords:  void tempnam pathname sibling cap errno EAGAIN ENOMEM
+% LocalWords:  void tempnam pathname sibling cap errno EAGAIN ENOMEM context
 % LocalWords:  stack read only copy write tab client spawn forktest sleep PATH
 % LocalWords:  source LIBRARY scheduling race condition printf descriptor dup
 % LocalWords:  close group session tms lock vfork execve BSD stream main abort
@@ -4513,7 +4574,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  filesystem noexec EPERM suid sgid root nosuid ENOEXEC ENOENT ELF
 % LocalWords:  ETXTBSY EINVAL ELIBBAD BIG EFAULT EIO ENAMETOOLONG ELOOP ENOTDIR
 % LocalWords:  ENFILE EMFILE argc execl path execv execle execlp execvp vector
-% LocalWords:  list environ NULL umask utime cutime ustime fcntl linker
+% LocalWords:  list environ NULL umask utime cutime ustime fcntl linker Posix
 % LocalWords:  opendir libc interpreter FreeBSD capabilities mandatory access
 % LocalWords:  control MAC SELinux security modules LSM superuser uid gid saved
 % LocalWords:  effective euid egid dell' fsuid fsgid getuid geteuid getgid SVr
@@ -4527,7 +4588,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  shmctl ioperm iopl chroot ptrace accounting swap reboot hangup
 % LocalWords:  vhangup mknod lease permitted inherited inheritable bounding AND
 % LocalWords:  capability capget capset header ESRCH undef version obj clear PT
-% LocalWords:  pag ssize length proc capgetp preemptive cache runnable  contest
+% LocalWords:  pag ssize length proc capgetp preemptive cache runnable
 % LocalWords:  SIGSTOP soft slice nice niceness counter which SC switch side
 % LocalWords:  getpriority who setpriority RTLinux RTAI Adeos fault FIFO  COUNT
 % LocalWords:  yield Robin setscheduler policy param OTHER priority setparam to
@@ -4559,6 +4620,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  NEWUTS SETTLS SIGHAND SYSVSEM UNTRACED tls ctid CLEARTID panic
 % LocalWords:  loader EISDIR SIGTRAP uninterrutible killable EQUAL sizeof XOR
 % LocalWords:  destset srcset ALLOC num cpus setsize emacs pager getty TID
+%  LocalWords:  reaper SUBREAPER Library futex
  
 %%% Local Variables: 
 %%% mode: latex