Correzioni varie
[gapil.git] / process.tex
index ca92e15b19cc3bbd7ce829c8e53493e1b91fd719..bf022ee9174a6f9bd9ba5416d5ab48028aa042cf 100644 (file)
@@ -1,3 +1,13 @@
+%% process.tex
+%%
+%% Copyright (C) 2000-2002 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 "Prefazione",
+%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
 \chapter{L'interfaccia base con i processi}
 \label{cha:process_interface}
 
@@ -63,7 +73,7 @@ se si vogliono scrivere programmi portabili 
 \subsection{Come chiudere un programma}
 \label{sec:proc_conclusion}
 
-Normalmente un programma finisce è quando la funzione \func{main} ritorna, una
+Normalmente un programma finisce quando la funzione \func{main} ritorna, una
 modalità equivalente di chiudere il programma è quella di chiamare
 direttamente la funzione \func{exit} (che viene comunque chiamata
 automaticamente quando \func{main} ritorna).  Una forma alternativa è quella
@@ -105,8 +115,8 @@ valore dello stato di uscita 
 incorrere nel caso in cui restituendo un codice di errore 256, si otterrebbe
 uno stato di uscita uguale a zero, che verrebbe interpretato come un successo.
 
-In \file{stdlib.h} sono definite, seguendo lo standard POSIX, le due macro
-\macro{EXIT\_SUCCESS} e \macro{EXIT\_FAILURE}, da usare sempre per specificare
+In \file{stdlib.h} sono definite, seguendo lo standard POSIX, le due costanti
+\const{EXIT\_SUCCESS} e \const{EXIT\_FAILURE}, da usare sempre per specificare
 lo stato di uscita di un processo. In Linux esse sono poste rispettivamente ai
 valori di tipo \ctyp{int} 0 e 1.
 
@@ -146,7 +156,7 @@ non vengono salvati e le eventuali funzioni registrate con \func{atexit} e
 La funzione chiude tutti i file descriptor appartenenti al processo (si tenga
 presente che questo non comporta il salvataggio dei dati bufferizzati degli
 stream), fa sì che ogni figlio del processo sia ereditato da \cmd{init} (vedi
-\secref{cha:process_handling}), manda un segnale \macro{SIGCHLD} al processo
+\secref{cha:process_handling}), manda un segnale \const{SIGCHLD} al processo
 padre (vedi \secref{sec:sig_job_control}) ed infine ritorna lo stato di uscita
 specificato in \param{status} che può essere raccolto usando la funzione
 \func{wait} (vedi \secref{sec:proc_wait}).
@@ -175,7 +185,7 @@ pu
   programma. 
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, \var{errno} non viene impostata.}
+    fallimento, \var{errno} non viene modificata.}
 \end{prototype}
 \noindent la funzione richiede come argomento l'indirizzo della opportuna
 funzione di pulizia da chiamare all'uscita, che non deve prendere argomenti e
@@ -192,7 +202,7 @@ definita su altri sistemi; il suo prototipo 
   rispetto a quello di registrazione.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, \var{errno} non viene impostata.}
+    fallimento, \var{errno} non viene modificata.}
 \end{prototype}
 
 In questo caso la funzione da chiamare prende due parametri, il primo dei
@@ -222,7 +232,7 @@ volontariamente la sua esecuzione 
 \func{exit} o il ritorno di \func{main}.
 
 Uno schema riassuntivo che illustra le modalità con cui si avvia e conclude
-normalmente un programma è riportato in \nfig.
+normalmente un programma è riportato in \figref{fig:proc_prog_start_stop}.
 
 \begin{figure}[htb]
   \centering
@@ -233,7 +243,8 @@ normalmente un programma 
 
 Si ricordi infine che un programma può anche essere interrotto dall'esterno
 attraverso l'uso di un segnale (modalità di conclusione non mostrata in
-\curfig); torneremo su questo aspetto in \capref{cha:signals}.
+\figref{fig:proc_prog_start_stop}); torneremo su questo aspetto in
+\capref{cha:signals}.
 
 
 
@@ -321,7 +332,7 @@ commette quando si 
 chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
 scrivere da un indirizzo per il quale non esiste un'associazione della pagina
 virtuale, il kernel risponde al relativo \textit{page fault}\index{page fault}
-mandando un segnale \macro{SIGSEGV} al processo, che normalmente ne causa la
+mandando un segnale \const{SIGSEGV} al processo, che normalmente ne causa la
 terminazione immediata.
 
 È pertanto importante capire come viene strutturata \textsl{la memoria
@@ -364,7 +375,7 @@ seguenti segmenti:
   \end{lstlisting}
   questo vettore sarà immagazzinato in questo segmento. Anch'esso viene
   allocato all'avvio, e tutte le variabili vengono inizializzate a zero (ed i
-  puntatori a \macro{NULL}).\footnote{si ricordi che questo vale solo per le
+  puntatori a \val{NULL}).\footnote{si ricordi che questo vale solo per le
     variabili che vanno nel segmento dati, e non è affatto vero in generale.}
    
   Storicamente questo segmento viene chiamato BBS (da \textit{block started by
@@ -383,10 +394,10 @@ seguenti segmenti:
   del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la
   funzione chiamata alloca qui lo spazio per le sue variabili locali: in
   questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
-  della funzione lo spazio è automaticamente rilasciato. Al ritorno della
-  funzione lo spazio è automaticamente ripulito. La pulizia in C e C++ viene
-  fatta dal chiamante.\footnote{a meno che non sia stato specificato
-    l'utilizzo di una calling convention diversa da quella standard.}
+  della funzione lo spazio è automaticamente rilasciato e ``ripulito''. La
+  pulizia in C e C++ viene fatta dal chiamante.\footnote{a meno che non sia
+    stato specificato l'utilizzo di una calling convention diversa da quella
+    standard.}
   
   La dimensione di questo segmento aumenta seguendo la crescita dello stack
   del programma, ma non viene ridotta quando quest'ultimo si restringe.
@@ -455,21 +466,21 @@ prototipi sono i seguenti:
   Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0.
   
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene impostata a \macro{ENOMEM}.
+  di successo e \val{NULL} in caso di fallimento, nel qual caso
+  \var{errno} assumerà il valore \errval{ENOMEM}.
 \funcdecl{void *malloc(size\_t size)}
   Alloca \var{size} byte nello heap. La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene impostata a \macro{ENOMEM}.
+  di successo e \val{NULL} in caso di fallimento, nel qual caso
+  \var{errno} assumerà il valore \errval{ENOMEM}.
 \funcdecl{void *realloc(void *ptr, size\_t size)}
   Cambia la dimensione del blocco allocato all'indirizzo \var{ptr}
   portandola a \var{size}.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene impostata a \macro{ENOMEM}.
+  di successo e \val{NULL} in caso di fallimento, nel qual caso
+  \var{errno} assumerà il valore \errval{ENOMEM}.
 \funcdecl{void free(void *ptr)}
   Disalloca lo spazio di memoria puntato da \var{ptr}.
 
@@ -480,11 +491,16 @@ allineato correttamente per tutti i tipi di dati; ad esempio sulle macchine a
 32 bit in genere è allineato a multipli di 4 byte e sulle macchine a 64 bit a
 multipli di 8 byte.
 
-In genere su usano le funzioni \func{malloc} e \func{calloc} per allocare
-dinamicamente la memoria necessaria al programma, e siccome i puntatori
-ritornati sono di tipo generico non è necessario effettuare un cast per
-assegnarli a puntatori al tipo di variabile per la quale si effettua
-l'allocazione.
+In genere si usano le funzioni \func{malloc} e \func{calloc} per allocare
+dinamicamente la quantità di memoria necessaria al programma indicata da
+\param{size},\footnote{queste funzioni presentano un comportamento diverso fra
+  le \acr{glibc} e le \acr{uClib} quando il valore di \param{size} è nullo.
+  Nel primo caso viene comunque restituito un puntatore valido, anche se non è
+  chiaro a cosa esso possa fare riferimento, nel secondo caso viene restituito
+  \val{NULL}. Il comportamento è analogo con \code{realloc(NULL, 0)}.} e
+siccome i puntatori ritornati sono di tipo generico non è necessario
+effettuare un cast per assegnarli a puntatori al tipo di variabile per la
+quale si effettua l'allocazione.
 
 La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando
 \func{free}\footnote{le glibc provvedono anche una funzione \func{cfree}
@@ -497,14 +513,14 @@ in caso contrario il comportamento della funzione 
 La funzione \func{realloc} si usa invece per cambiare (in genere aumentare) la
 dimensione di un'area di memoria precedentemente allocata, la funzione vuole
 in ingresso il puntatore restituito dalla precedente chiamata ad una
-\func{malloc} (se è passato un valore \macro{NULL} allora la funzione si
-comporta come \func{malloc},\footnote{questo è vero per Linux e
+\func{malloc} (se è passato un valore \val{NULL} allora la funzione si
+comporta come \func{malloc})\footnote{questo è vero per Linux e
   l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
   vecchie implementazioni, inoltre alcune versioni delle librerie del C
   consentivano di usare \func{realloc} anche per un puntatore liberato con
   \func{free} purché non ci fossero state nel frattempo altre chiamate a
   funzioni di allocazione, questa funzionalità è totalmente deprecata e non è
-  consentita sotto Linux.}) ad esempio quando si deve far crescere la
+  consentita sotto Linux.} ad esempio quando si deve far crescere la
 dimensione di un vettore. In questo caso se è disponibile dello spazio
 adiacente al precedente la funzione lo utilizza, altrimenti rialloca altrove
 un blocco della dimensione voluta, copiandoci automaticamente il contenuto; lo
@@ -520,36 +536,36 @@ blocco di dati ridimensionato.
 Un errore abbastanza frequente (specie se si ha a che fare con array di
 puntatori) è quello di chiamare \func{free} più di una volta sullo stesso
 puntatore; per evitare questo problema una soluzione di ripiego è quella di
-assegnare sempre a \macro{NULL} ogni puntatore liberato con \func{free}, dato
+assegnare sempre a \val{NULL} ogni puntatore liberato con \func{free}, dato
 che, quando il parametro è un puntatore nullo, \func{free} non esegue nessuna
 operazione.
 
 Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è
 controllabile dall'utente attraverso alcune variabili di ambiente, in
 particolare diventa possibile tracciare questo tipo di errori usando la
-variabile \macro{MALLOC\_CHECK\_} che quando viene definita mette in uso una
-versione meno efficiente delle funzioni suddette, che però è più tollerante
-nei confronti di piccoli errori come quello di chiamate doppie a \func{free}.
-In particolare:
-\begin{itemize*}
+variabile d'ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in
+uso una versione meno efficiente delle funzioni suddette, che però è più
+tollerante nei confronti di piccoli errori come quello di chiamate doppie a
+\func{free}.  In particolare:
+\begin{itemize}
 \item se la variabile è posta a zero gli errori vengono ignorati.
 \item se è posta ad 1 viene stampato un avviso sullo \textit{standard error}
   (vedi \secref{sec:file_std_stream}).
 \item se è posta a 2 viene chiamata \func{abort}, che in genere causa
   l'immediata conclusione del programma.
-\end{itemize*}
+\end{itemize}
 
 Il problema più comune e più difficile da risolvere che si incontra con le
 routine di allocazione è quando non viene opportunamente liberata la memoria
 non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak},
-(cioè \textsl{perdita di memoria}).
+cioè una \textsl{perdita di memoria}.
 
 Un caso tipico che illustra il problema è quello in cui in una subroutine si
 alloca della memoria per uso locale senza liberarla prima di uscire. La
 memoria resta così allocata fino alla terminazione del processo.  Chiamate
 ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni,
 causando a lungo andare un esaurimento della memoria disponibile (e la
-probabile l'impossibilità di proseguire l'esecuzione programma).
+probabile impossibilità di proseguire l'esecuzione del programma).
 
 Il problema è che l'esaurimento della memoria può avvenire in qualunque
 momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
@@ -557,29 +573,61 @@ essere in una sezione del codice che non ha alcuna relazione con la subroutine
 che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
 \textit{memory leak}.
 
-Per ovviare a questi problemi l'implementazione delle routine di allocazione
-delle \acr{glibc} mette a disposizione una serie di funzionalità che
-permettono di tracciare le allocazioni e le disallocazione, e definisce anche
-una serie di possibili \textit{hook} (\textsl{ganci}) che permettono di
-sostituire alle funzioni di libreria una propria versione (che può essere più
-o meno specializzata per il debugging).
+In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
+programmazione ad oggetti, il problema dei \textit{memory leak} è notevolmente
+ridimensionato attraverso l'uso accurato di appositi oggetti come gli
+\textit{smartpointers}.  Questo però va a scapito delle performance
+dell'applicazione in esecuzione.
+
+In altri linguaggi come il java e recentemente il C\# il problema non si pone
+nemmeno perché la gestione della memoria viene fatta totalmente in maniera
+automatica, ovvero il programmatore non deve minimamente preoccuparsi di
+liberare la memoria allocata precedentemente quando non serve più, poiché il
+framework gestisce automaticamente la cosiddetta \textit{garbage collection}.
+In tal caso, attraverso meccanismi simili a quelli del \textit{reference
+  counting}, quando una zona di memoria precedentemente allocata non è più
+riferita da nessuna parte del codice in esecuzione, può essere deallocata
+automaticamente in qualunque momento dall'infrastruttura.
+
+Anche questo va a scapito delle performance dell'applicazione in esecuzione
+(inoltre le applicazioni sviluppate con tali linguaggi di solito non sono
+eseguibili compilati, come avviene invece per il C ed il C++, ed è necessaria
+la presenza di una infrastruttura per la loro interpretazione e pertanto hanno
+di per sé delle performance più scadenti rispetto alle stesse applicazioni
+compilate direttamente).  Questo comporta però il problema della non
+predicibilità del momento in cui viene deallocata la memoria precedentemente
+allocata da un oggetto.
+
+Per limitare l'impatto di questi problemi, e semplificare la ricerca di
+eventuali errori, l'implementazione delle routine di allocazione delle
+\acr{glibc} mette a disposizione una serie di funzionalità che permettono di
+tracciare le allocazioni e le disallocazione, e definisce anche una serie di
+possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
+funzioni di libreria una propria versione (che può essere più o meno
+specializzata per il debugging). Esistono varie librerie che forniscono dei
+sostituti opportuni delle routine di allocazione in grado, senza neanche
+ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
+  \href{http://dmalloc.com/}{http://dmalloc.com/} di Gray Watson ed
+  \textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche
+molto complesse riguardo l'allocazione della memoria.
+
 
 
 \subsection{La funzione \func{alloca}}  
 \label{sec:proc_mem_alloca}
 
 Una possibile alternativa all'uso di \func{malloc}, che non soffre dei
-problemi di memory leak descritti in precedenza, è la funzione \func{alloca},
-che invece di allocare la memoria nello heap usa il segmento di stack della
-funzione corrente. La sintassi è identica a quella di \func{malloc}, il suo
-prototipo è:
+problemi di \textit{memory leak} descritti in precedenza, è la funzione
+\func{alloca}, che invece di allocare la memoria nello heap usa il segmento di
+stack della funzione corrente. La sintassi è identica a quella di
+\func{malloc}, il suo prototipo è:
 \begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
   Alloca \var{size} byte nel segmento di stack della funzione chiamante.
   La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
-  di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene impostata a \macro{ENOMEM}.
+  di successo e \val{NULL} in caso di fallimento, nel qual caso
+  \var{errno} assumerà il valore \errval{ENOMEM}.
 \end{prototype}
 \noindent ma in questo caso non è più necessario liberare la memoria (e quindi
 non esiste un analogo della \func{free}) in quanto essa viene rilasciata 
@@ -631,15 +679,15 @@ analoghe system call a cui fanno da interfaccia. I loro prototipi sono:
   \var{end\_data\_segment}.
   
   La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, nel qual caso \var{errno} viene impostata a \macro{ENOMEM}.
+    fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.
 
   \funcdecl{void *sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un
   programma di \var{increment}. Un valore zero restituisce l'attuale posizione
   della fine del segmento dati.
   
   La funzione restituisce il puntatore all'inizio della nuova zona di memoria
-  allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual
-  caso \macro{errno} viene impostata a \macro{ENOMEM}.
+  allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual
+  caso \var{errno} assumerà il valore \errval{ENOMEM}.
 \end{functions}
 \noindent in genere si usa \func{sbrk} con un valore zero per ottenere
 l'attuale posizione della fine del segmento dati.
@@ -647,7 +695,7 @@ l'attuale posizione della fine del segmento dati.
 Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e
 per i programmi normali è sempre opportuno usare le funzioni di allocazione
 standard descritte in precedenza, che sono costruite su di esse.  L'uso di
-queste funzione è ristretto alle specifiche necessità di chi debba
+queste funzioni è ristretto alle specifiche necessità di chi debba
 implementare una sua versione delle routine di allocazione.  
 
 
@@ -686,11 +734,11 @@ motivi per cui si possono avere di queste necessit
 \item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro
   in memoria queste possono essere portate su disco dal meccanismo della
   paginazione. Questo rende più lungo il periodo di tempo in cui detti segreti
-  sono presenti in chiaro e più complessa la loro cancellazione (ad un
-  processo è possibile cancellare la memoria su cui scrive le sue variabili,
-  ma non può toccare lo spazio disco su cui una pagina di memoria può essere
-  stata salvata). Per questo motivo di solito i programmi di crittografia
-  richiedono il blocco di alcune pagine di memoria.
+  sono presenti in chiaro e più complessa la loro cancellazione (un processo
+  può cancellare la memoria su cui scrive le sue variabili, ma non può toccare
+  lo spazio disco su cui una pagina di memoria può essere stata salvata). Per
+  questo motivo di solito i programmi di crittografia richiedono il blocco di
+  alcune pagine di memoria.
 \end{itemize}
 
 Il meccanismo che previene la paginazione di parte della memoria virtuale di
@@ -706,23 +754,25 @@ sbloccarla due volte, una pagina o 
 Il \textit{memory lock} persiste fintanto che il processo che detiene la
 memoria bloccata non la sblocca. Chiaramente la terminazione del processo
 comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
-tutti i suoi \textit{memory lock}.
-
-I \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma
-  siccome Linux usa il \textit{copy on write}\index{copy on write} (vedi
-  \secref{sec:proc_fork}) gli indirizzi virtuali del figlio sono mantenuti
-  sullo stesso segmento di RAM del padre, quindi fintanto che un figlio non
-  scrive su un segmento, può usufruire del memory lock del padre.}  Siccome la
-presenza di un \textit{memory lock} riduce la memoria disponibile al sistema,
-con un impatto su tutti gli altri processi, solo l'amministratore ha la
-capacità di bloccare una pagina. Ogni processo può però sbloccare le pagine
+tutti i suoi \textit{memory lock}.  Infine \textit{memory lock} non sono
+ereditati dai processi figli.\footnote{ma siccome Linux usa il \textit{copy on
+    write}\index{copy on write} (vedi \secref{sec:proc_fork}) gli indirizzi
+  virtuali del figlio sono mantenuti sullo stesso segmento di RAM del padre,
+  quindi fintanto che un figlio non scrive su un segmento, può usufruire del
+  memory lock del padre.}
+
+Siccome la richiesta di un \textit{memory lock} da parte di un processo riduce
+la memoria fisica disponibile nel sistema, questo ha un evidente impatto su
+tutti gli altri processi, per cui solo un processo con i privilegi di
+amministratore (vedremo in \secref{sec:proc_perms} cosa significa) ha la
+capacità di bloccare una pagina.  Ogni processo può però sbloccare le pagine
 relative alla propria memoria.
 
 Il sistema pone dei limiti all'ammontare di memoria di un processo che può
-essere bloccata e al totale di memoria fisica che può dedicare a questo, lo
-standard POSIX.1 richiede che sia definita in \file{unistd.h} la costante
+essere bloccata e al totale di memoria fisica che si può dedicare a questo, lo
+standard POSIX.1 richiede che sia definita in \file{unistd.h} la macro
 \macro{\_POSIX\_MEMLOCK\_RANGE} per indicare la capacità di eseguire il
-\textit{memory locking} e la costante \macro{PAGESIZE} in \file{limits.h} per
+\textit{memory locking} e la costante \const{PAGESIZE} in \file{limits.h} per
 indicare la dimensione di una pagina in byte.
 
 Le funzioni per bloccare e sbloccare singole sezioni di memoria sono
@@ -740,15 +790,15 @@ Le funzioni per bloccare e sbloccare singole sezioni di memoria sono
 
   
   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in
-    caso di errore, nel qual caso \var{errno} è impostata ad uno dei
+    caso di errore, nel qual caso \var{errno} assumerà uno dei
     valori seguenti:
   \begin{errlist}
-  \item[\macro{ENOMEM}] alcuni indirizzi dell'intervallo specificato non
+  \item[\errcode{ENOMEM}] alcuni indirizzi dell'intervallo specificato non
     corrispondono allo spazio di indirizzi del processo o si è ecceduto
     il numero massimo consentito di pagine bloccate.
-  \item[\macro{EINVAL}] \var{len} non è un valore positivo.
+  \item[\errcode{EINVAL}] \var{len} non è un valore positivo.
   \end{errlist}
-  e, per \func{mlock}, anche \macro{EPERM} quando il processo non ha i
+  e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i
   privilegi richiesti per l'operazione.}
 \end{functions}
 
@@ -773,9 +823,9 @@ Il parametro \var{flags} di \func{mlockall} permette di controllarne il
 comportamento; esso può essere specificato come l'OR aritmetico delle due
 costanti: 
 \begin{basedescript}{\desclabelwidth{2.5cm}}
-\item[\macro{MCL\_CURRENT}] blocca tutte le pagine correntemente mappate nello
+\item[\const{MCL\_CURRENT}] blocca tutte le pagine correntemente mappate nello
   spazio di indirizzi del processo.
-\item[\macro{MCL\_FUTURE}] blocca tutte le pagine che saranno mappate nello
+\item[\const{MCL\_FUTURE}] blocca tutte le pagine che saranno mappate nello
   spazio di indirizzi del processo.
 \end{basedescript}
 
@@ -816,7 +866,7 @@ Oltre al passaggio dei parametri, un'altra modalit
 delle informazioni che modifichino il comportamento di un programma è quello
 dell'uso del cosiddetto \textit{environment} (cioè l'uso delle
 \textsl{variabili di ambiente}). In questa sezione esamineremo le funzioni che
-permettono di gestire parametri e opzioni, e quelle che consentono di
+permettono di gestire parametri ed opzioni, e quelle che consentono di
 manipolare ed utilizzare le variabili di ambiente.
 
 
@@ -842,7 +892,7 @@ Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
 in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
 variabile \var{argc} viene inizializzata al numero di parametri trovati, in
 questo modo il primo parametro è sempre il nome del programma; un esempio di
-questo meccanismo è mostrato in \curfig.
+questo meccanismo è mostrato in \figref{fig:proc_argv_argc}.
 
 
 \subsection{La gestione delle opzioni}
@@ -850,14 +900,14 @@ questo meccanismo 
 
 In generale un programma Unix riceve da linea di comando sia gli argomenti che
 le opzioni, queste ultime sono standardizzate per essere riconosciute come
-tali: un elemento di \var{argv} che inizia con \texttt{-} e che non sia un
-singolo \texttt{-} o un \texttt{--} viene considerato un'opzione.  In genere
-le opzioni sono costituite da una lettera singola (preceduta dal \cmd{-}) e
-possono avere o no un parametro associato; un comando tipico può essere quello
-mostrato in \figref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r}
-ed \cmd{-m} e la prima vuole un parametro mentre la seconda no
-(\cmd{questofile.txt} è un argomento del programma, non un parametro di
-\cmd{-m}).
+tali: un elemento di \var{argv} che inizia con il carattere \texttt{'-'} e che
+non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato
+un'opzione.  In genere le opzioni sono costituite da una lettera singola
+(preceduta dal carattere \cmd{'-'}) e possono avere o no un parametro
+associato; un comando tipico può essere quello mostrato in
+\figref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r} e \cmd{-m}
+e la prima vuole un parametro mentre la seconda no (\cmd{questofile.txt} è un
+argomento del programma, non un parametro di \cmd{-m}).
 
 Per gestire le opzioni all'interno dei argomenti a linea di comando passati in
 \var{argv} le librerie standard del C forniscono la funzione \func{getopt}
@@ -881,8 +931,8 @@ valida.
 La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
 costituita da tutti i caratteri usati per identificare le singole opzioni, se
 l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
-due punti \var{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
-stringa di opzioni avrebbe dovuto contenere \var{"r:m"}.
+due punti \texttt{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
+stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}.
 
 La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la
 funzione all'interno di un ciclo, fintanto che essa non ritorna il valore -1
@@ -890,7 +940,7 @@ che indica che non ci sono pi
 dichiarata in \var{optstring} viene ritornato il carattere \texttt{'?'}
 mentre se un opzione che lo richiede non è seguita da un parametro viene
 ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
-\cmd{--} la scansione viene considerata conclusa, anche se vi sono altri
+\texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri
 elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
 
 \begin{figure}[htb]
@@ -947,22 +997,21 @@ In \figref{fig:proc_options_code} 
 sulla creazione dei processi) deputata alla decodifica delle opzioni a riga di
 comando. 
 
-Anzitutto si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la
-stampa di messaggi di errore per opzioni non riconosciute, per poi passare al
-ciclo per la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle
-opzioni possibili si è poi provveduto ad un'azione opportuna, ad esempio per
-le tre opzioni che prevedono un parametro si è effettuata la decodifica del
-medesimo (il cui indirizzo è contenuto nella variabile \var{optarg})
-avvalorando la relativa variabile (\texttt{\small 12-14}, \texttt{\small
-  15-17} e \texttt{\small 18-20}). Completato il ciclo troveremo in
-\var{optind} l'indice in \var{argv[]} del primo degli argomenti rimanenti
-nella linea di comando.
+Si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la stampa di
+messaggi di errore per opzioni non riconosciute, per poi passare al ciclo per
+la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle opzioni
+possibili si è poi provveduto ad un'azione opportuna, ad esempio per le tre
+opzioni che prevedono un parametro si è effettuata la decodifica del medesimo
+(il cui indirizzo è contenuto nella variabile \var{optarg}) avvalorando la
+relativa variabile (\texttt{\small 12-14}, \texttt{\small 15-17} e
+\texttt{\small 18-20}). Completato il ciclo troveremo in \var{optind} l'indice
+in \var{argv[]} del primo degli argomenti rimanenti nella linea di comando.
 
 Normalmente \func{getopt} compie una permutazione degli elementi di \var{argv}
-così che alla fine della scansione gli elementi che non sono opzioni sono
+cosicché alla fine della scansione gli elementi che non sono opzioni sono
 spostati in coda al vettore. Oltre a questa esistono altre due modalità di
 gestire gli elementi di \var{argv}; se \var{optstring} inizia con il carattere
-\texttt{'+'} (o è impostata la variabile di ambiente \macro{POSIXLY\_CORRECT})
+\texttt{'+'} (o è impostata la variabile di ambiente \val{POSIXLY\_CORRECT})
 la scansione viene fermata non appena si incontra un elemento che non è
 un'opzione. L'ultima modalità, usata quando un programma può gestire la
 mescolanza fra opzioni e argomenti, ma se li aspetta in un ordine definito, si
@@ -994,7 +1043,7 @@ nella chiamata alla funzione \func{exec} quando questo viene lanciato.
 
 Come per la lista dei parametri anche questa lista è un array di puntatori a
 caratteri, ciascuno dei quali punta ad una stringa, terminata da un
-\macro{NULL}. A differenza di \var{argv[]} in questo caso non si ha una
+\val{NULL}. A differenza di \var{argv[]} in questo caso non si ha una
 lunghezza dell'array data da un equivalente di \var{argc}, ma la lista è
 terminata da un puntatore nullo.
 
@@ -1004,8 +1053,9 @@ dichiarazione del tipo:
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 extern char ** environ;
 \end{lstlisting}
-un esempio del contenuto dell'ambiente, in si è riportato un estratto delle
-variabili che normalmente sono definite dal sistema, è riportato in \nfig.
+un esempio della struttura di questa lista, contenente alcune delle variabili
+più comuni che normalmente sono definite dal sistema, è riportato in
+\figref{fig:proc_envirno_list}.
 \begin{figure}[htb]
   \centering
   \includegraphics[width=11cm]{img/environ_var}
@@ -1014,66 +1064,77 @@ variabili che normalmente sono definite dal sistema, 
 \end{figure}
 
 Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo
-\textsl{\texttt{nome=valore}}. Inoltre alcune variabili, come quelle elencate
-in \curfig, sono definite dal sistema per essere usate da diversi programmi e
-funzioni: per queste c'è l'ulteriore convenzione di usare nomi espressi in
-caratteri maiuscoli.
+\textsl{\texttt{nome=valore}}.  Inoltre alcune variabili, come quelle elencate
+in \figref{fig:proc_envirno_list}, sono definite dal sistema per essere usate
+da diversi programmi e funzioni: per queste c'è l'ulteriore convenzione di
+usare nomi espressi in caratteri maiuscoli.\footnote{la convenzione vuole che
+  si usino dei nomi maiuscoli per le variabili di ambiente di uso generico, i
+  nomi minuscoli sono in genere riservati alle variabili interne degli script
+  di shell.}
 
 Il kernel non usa mai queste variabili, il loro uso e la loro interpretazione è
 riservata alle applicazioni e ad alcune funzioni di libreria; in genere esse
 costituiscono un modo comodo per definire un comportamento specifico senza
 dover ricorrere all'uso di opzioni a linea di comando o di file di
-configurazione. 
+configurazione. É di norma cura della shell, quando esegue un comando, passare
+queste variabili al programma messo in esecuzione attraverso un uso opportuno
+delle relative chiamate (si veda \secref{sec:proc_exec}).
 
 La shell ad esempio ne usa molte per il suo funzionamento (come \var{PATH} per
 la ricerca dei comandi, o \cmd{IFS} per la scansione degli argomenti), e
-alcune di esse (come \var{HOME}, \var{USER}, etc.)  sono definite al login. In
-genere è cura dell'amministratore definire le opportune variabili di ambiente
-in uno script di avvio. Alcune servono poi come riferimento generico per molti
-programmi (come \var{EDITOR} che indica l'editor preferito da invocare in caso
-di necessità).
+alcune di esse (come \var{HOME}, \var{USER}, etc.) sono definite al login (per
+i dettagli si veda \secref{sec:sess_login}). In genere è cura
+dell'amministratore definire le opportune variabili di ambiente in uno script
+di avvio. Alcune servono poi come riferimento generico per molti programmi
+(come \var{EDITOR} che indica l'editor preferito da invocare in caso di
+necessità).
 
 Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più
-comuni), come riportato in \ntab. GNU/Linux le supporta tutte e ne definisce
-anche altre: per una lista più completa si può controllare \cmd{man environ}.
+comuni), come riportato in \tabref{tab:proc_env_var}. GNU/Linux le supporta
+tutte e ne definisce anche altre: per una lista più completa si può
+controllare \cmd{man environ}.
 
 \begin{table}[htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|l|c|c|c|p{7cm}|}
     \hline
     \textbf{Variabile} & \textbf{POSIX} & \textbf{XPG3} 
     & \textbf{Linux} & \textbf{Descrizione} \\
     \hline
     \hline
-    \macro{USER} & $\bullet$ & $\bullet$ & $\bullet$ & Nome utente\\
-    \macro{LOGNAME} & $\bullet$ & $\bullet$ & $\bullet$ & Nome di login\\
-    \macro{HOME} & $\bullet$ & $\bullet$ & $\bullet$ & 
+    \val{USER} & $\bullet$ & $\bullet$ & $\bullet$ & Nome utente\\
+    \val{LOGNAME} & $\bullet$ & $\bullet$ & $\bullet$ & Nome di login\\
+    \val{HOME} & $\bullet$ & $\bullet$ & $\bullet$ & 
     Directory base dell'utente\\
-    \macro{LANG} & $\bullet$ & $\bullet$ & $\bullet$ & Localizzazione\\
-    \macro{PATH} & $\bullet$ & $\bullet$ & $\bullet$ & Elenco delle directory
-    dei programmi\\
-    \macro{PWD} & $\bullet$ & $\bullet$ & $\bullet$ & Directory corrente\\
-    \macro{SHELL} & $\bullet$ & $\bullet$ & $\bullet$ & Shell in uso\\
-    \macro{TERM} & $\bullet$ & $\bullet$ & $\bullet$ & Tipo di terminale\\
-    \macro{PAGER} & $\bullet$ & $\bullet$ & $\bullet$ & Programma per vedere i
-    testi\\
-    \macro{EDITOR} & $\bullet$ & $\bullet$ & $\bullet$ & Editor preferito\\
-    \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser preferito\\
+    \val{LANG} & $\bullet$ & $\bullet$ & $\bullet$ & Localizzazione\\
+    \val{PATH} & $\bullet$ & $\bullet$ & $\bullet$ & Elenco delle directory
+                                                     dei programmi\\
+    \val{PWD} & $\bullet$ & $\bullet$ & $\bullet$ & Directory corrente\\
+    \val{SHELL} & $\bullet$ & $\bullet$ & $\bullet$ & Shell in uso\\
+    \val{TERM} & $\bullet$ & $\bullet$ & $\bullet$ & Tipo di terminale\\
+    \val{PAGER} & $\bullet$ & $\bullet$ & $\bullet$ & Programma per vedere i
+                                                      testi\\
+    \val{EDITOR} & $\bullet$ & $\bullet$ & $\bullet$ & Editor preferito\\
+    \val{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser preferito\\
+    \val{TMPDIR} & $\bullet$ & $\bullet$ & $\bullet$ & Directory dei file
+                                                       temporanei\\
     \hline
   \end{tabular}
-  \caption{Variabili di ambiente più comuni definite da vari standard.}
+  \caption{Esempi di variabili di ambiente più comuni definite da vari
+    standard.} 
   \label{tab:proc_env_var}
 \end{table}
 
-Lo standard ANSI C prevede l'esistenza di un ambiente, pur non entrando nelle
-specifiche di come sono strutturati i contenuti, e definisce la funzione
-\func{getenv} che permette di ottenere i valori delle variabili di ambiente,
-il cui prototipo è:
+Lo standard ANSI C prevede l'esistenza di un ambiente, e pur non entrando
+nelle specifiche di come sono strutturati i contenuti, definisce la funzione
+\func{getenv} che permette di ottenere i valori delle variabili di ambiente;
+il suo prototipo è:
 \begin{prototype}{stdlib.h}{char *getenv(const char *name)}
   Esamina l'ambiente del processo cercando una stringa che corrisponda a
   quella specificata da \param{name}. 
   
-  \bodydesc{La funzione ritorna \macro{NULL} se non trova nulla, o il
+  \bodydesc{La funzione ritorna \val{NULL} se non trova nulla, o il
     puntatore alla stringa che corrisponde (di solito nella forma
     \cmd{NOME=valore}).}
 \end{prototype}
@@ -1082,10 +1143,11 @@ Oltre a questa funzione di lettura, che 
 C, nell'evoluzione dei sistemi Unix ne sono state proposte altre, da
 utilizzare per impostare e per cancellare le variabili di ambiente. Uno schema
 delle funzioni previste nei vari standard e disponibili in Linux è riportato
-in \ntab.
+in \tabref{tab:proc_env_func}.
 
 \begin{table}[htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|l|c|c|c|c|c|c|}
     \hline
     \textbf{Funzione} & \textbf{ANSI C} & \textbf{POSIX.1} & \textbf{XPG3} & 
@@ -1108,10 +1170,11 @@ in \ntab.
   \label{tab:proc_env_func}
 \end{table}
 
-In Linux solo le prime quattro funzioni di \curtab\ sono definite,
-\func{getenv} l'abbiamo già esaminata; delle tre restanti le prime due,
-\func{putenv} e \func{setenv}, servono per assegnare nuove variabili di
-ambiente, i loro prototipi sono i seguenti:
+In Linux sono definite solo le prime quattro delle funzioni elencate in
+\tabref{tab:proc_env_func}. La prima, \func{getenv}, l'abbiamo appena
+esaminata; delle tre restanti le prime due, \func{putenv} e \func{setenv},
+servono per assegnare nuove variabili di ambiente, i loro prototipi sono i
+seguenti:
 \begin{functions}
   \headdecl{stdlib.h} 
   
@@ -1122,7 +1185,7 @@ ambiente, i loro prototipi sono i seguenti:
   all'ambiente.
   
   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 per un
-    errore, che è sempre \macro{ENOMEM}.}
+    errore, che è sempre \errval{ENOMEM}.}
 \end{functions}
 \noindent la terza, \func{unsetenv}, serve a cancellare una variabile di
 ambiente; il suo prototipo è:
@@ -1162,12 +1225,12 @@ questa funzione una variabile automatica (per evitare i problemi esposti in
 
 Si tenga infine presente che se si passa a \func{putenv} solo il nome di una
 variabile (cioè \param{string} è nella forma \texttt{NAME} e non contiene un
-\texttt{=}) allora questa viene cancellata dall'ambiente. Infine se la
-chiamata di \func{putenv} comporta la necessità di allocare una nuova versione
-del vettore \var{environ} questo sarà allocato, ma la versione corrente sarà
-deallocata solo se anch'essa è risultante da un'allocazione fatta in
-precedenza da un'altra \func{putenv}. Questo perché il vettore delle variabili
-di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
+carattere \texttt{'='}) allora questa viene cancellata dall'ambiente. Infine
+se la chiamata di \func{putenv} comporta la necessità di allocare una nuova
+versione del vettore \var{environ} questo sarà allocato, ma la versione
+corrente sarà deallocata solo se anch'essa è risultante da un'allocazione
+fatta in precedenza da un'altra \func{putenv}. Questo perché il vettore delle
+variabili di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
 \secref{sec:proc_exec}) è piazzato al di sopra dello stack, (vedi
 \figref{fig:proc_mem_layout}) e non nello heap e non può essere deallocato.
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
@@ -1281,7 +1344,7 @@ stati scritti. Per fare questo in \file{stdarg.h} sono definite delle apposite
 macro; la procedura da seguire è la seguente:
 \begin{enumerate*}
 \item Inizializzare un puntatore alla lista degli argomenti di tipo
-  \type{va\_list} attraverso la macro \macro{va\_start}.
+  \macro{va\_list} attraverso la macro \macro{va\_start}.
 \item Accedere ai vari argomenti opzionali con chiamate successive alla macro
   \macro{va\_arg}, la prima chiamata restituirà il primo argomento, la seconda
   il secondo e così via.
@@ -1339,7 +1402,7 @@ normale pensare di poter effettuare questa operazione.
 
 In generale però possono esistere anche realizzazioni diverse, per questo
 motivo \macro{va\_list} è definito come \textsl{tipo opaco} e non può essere
-assegnato direttamente ad un altra variabile dello stesso tipo. Per risolvere
+assegnato direttamente ad un'altra variabile dello stesso tipo. Per risolvere
 questo problema lo standard ISO C99\footnote{alcuni sistemi che non hanno
   questa macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome
   proposto in una bozza dello standard.} ha previsto una macro ulteriore che
@@ -1378,7 +1441,7 @@ per \func{printf}).
 Una modalità diversa, che può essere applicata solo quando il tipo dei
 parametri lo rende possibile, è quella che prevede di usare un valore speciale
 come ultimo argomento (come fa ad esempio \func{execl} che usa un puntatore
-\macro{NULL} per indicare la fine della lista degli argomenti).
+\val{NULL} per indicare la fine della lista degli argomenti).
 
 
 \subsection{Potenziali problemi con le variabili automatiche}
@@ -1422,14 +1485,13 @@ ottenere le indicazioni per l'esecuzione di opportune operazioni.
 Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
 in fasi diverse, la rilevazione di un errore nell'input può accadere
 all'interno di funzioni profondamente annidate l'una nell'altra. In questo
-caso si dovrebbe per ciascuna fase dover gestire tutta la casistica del
-passaggio all'indietro di tutti gli errori rilevabili dalle funzioni usate
-nelle fasi successive, mentre sarebbe molto più comodo poter tornare
-direttamente al ciclo di lettura principale, scartando l'input come
-errato.\footnote{a meno che, come precisa \cite{glibc}, alla chiusura di
-  ciascuna fase non siano associate operazioni di pulizia specifiche (come
-  deallocazioni, chiusure di file, ecc.), che non potrebbero essere eseguite
-  con un salto non-locale.}
+caso si dovrebbe gestire, per ciascuna fase, tutta la casistica del passaggio
+all'indietro di tutti gli errori rilevabili dalle funzioni usate nelle fasi
+successive, mentre sarebbe molto più comodo poter tornare direttamente al
+ciclo di lettura principale, scartando l'input come errato.\footnote{a meno
+  che, come precisa \cite{glibc}, alla chiusura di ciascuna fase non siano
+  associate operazioni di pulizia specifiche (come deallocazioni, chiusure di
+  file, ecc.), che non potrebbero essere eseguite con un salto non-locale.}
 
 Tutto ciò può essere realizzato salvando il contesto dello stack nel punto in
 cui si vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza