Inserite nuove macro per la indicizzazione della definizione delle funzioni
[gapil.git] / process.tex
index 961a25aa8f0a918d5a0019653eba6891170be6d0..d3e98e435f9a2e6df9fbd963e085c3f9bfb4088f 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}
 
@@ -54,7 +64,7 @@ linea di comando, in sostanza un prototipo che va sempre bene 
 \end{lstlisting}
 
 In realtà nei sistemi Unix esiste un'altro modo per definire la funzione
-\func{main}, che prevede la presenza di un terzo parametro, \var{char
+\func{main}, che prevede la presenza di un terzo parametro, \code{char
   *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
 del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
 se si vogliono scrivere programmi portabili è meglio evitarla.
@@ -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.
 
@@ -115,11 +125,10 @@ valori di tipo \ctyp{int} 0 e 1.
 \label{sec:proc_exit}
 
 Come accennato le funzioni usate per effettuare un'uscita ``normale'' da un
-programma sono due, la prima è la funzione \func{exit} che è definita dallo
+programma sono due, la prima è la funzione \funcd{exit}, che è definita dallo
 standard ANSI C ed il cui prototipo è:
 \begin{prototype}{stdlib.h}{void exit(int status)}
-  Causa la conclusione ordinaria del programma restituendo il valore
-  \var{status} al processo padre.
+  Causa la conclusione ordinaria del programma.
 
   \bodydesc{La funzione non ritorna. Il processo viene terminato.}
 \end{prototype}
@@ -130,15 +139,14 @@ che sono state registrate con \func{atexit} e \func{on\_exit} (vedi
 \secref{sec:proc_atexit}), e chiude tutti gli stream effettuando il
 salvataggio dei dati sospesi (chiamando \func{fclose}, vedi
 \secref{sec:file_fopen}), infine passa il controllo al kernel chiamando
-\func{\_exit} e passando \param{status} come stato di uscita.
+\func{\_exit} e restituendo il valore di \param{status} come stato di uscita.
 
-La system call \func{\_exit} restituisce direttamente il controllo al kernel,
+La system call \funcd{\_exit} restituisce direttamente il controllo al kernel,
 concludendo immediatamente il processo; i dati sospesi nei buffer degli stream
 non vengono salvati e le eventuali funzioni registrate con \func{atexit} e
 \func{on\_exit} non vengono eseguite. Il prototipo della funzione è:
 \begin{prototype}{unistd.h}{void \_exit(int status)}
-  Causa la conclusione immediata del programma restituendo \param{status} al
-  processo padre come stato di uscita.
+  Causa la conclusione immediata del programma.
 
   \bodydesc{La funzione non ritorna. Il processo viene terminato.}
 \end{prototype}
@@ -146,7 +154,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}).
@@ -169,37 +177,37 @@ una funzione che effettui tali operazioni all'uscita dal programma. A questo
 scopo lo standard ANSI C prevede la possibilità di registrare un certo numero
 funzioni che verranno eseguite all'uscita dal programma (sia per la chiamata
 ad \func{exit} che per il ritorno di \func{main}). La prima funzione che si
-può utilizzare a tal fine è:
+può utilizzare a tal fine è \funcd{atexit} il cui prototipo è:
 \begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
-  Registra la funzione \param{function} per essere chiamata all'uscita dal
-  programma. 
+  Registra la funzione \param{function} per la chiamata all'uscita dal
+  programma.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     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
-non deve ritornare niente (deve essere essere cioè definita come \code{void
-  function(void)}).
+\noindent la funzione richiede come argomento l'indirizzo di una opportuna
+funzione di pulizia da chiamare all'uscita del programma, che non deve
+prendere argomenti e non deve ritornare niente (deve essere essere cioè
+definita come \code{void function(void)}).
 
-Un'estensione di \func{atexit} è la funzione \func{on\_exit}, che le
+Un'estensione di \func{atexit} è la funzione \funcd{on\_exit}, che le
 \acr{glibc} includono per compatibilità con SunOS, ma che non è detto sia
 definita su altri sistemi; il suo prototipo è:
 \begin{prototype}{stdlib.h}
-{void on\_exit(void (*function)(int status, void *arg), void *arg)}
-  Registra la funzione \param{function} per essere chiamata all'uscita dal
-  programma. Tutte le funzioni registrate vengono chiamate in ordine inverso
-  rispetto a quello di registrazione.
+{void on\_exit(void (*function)(int , void *), void *arg)}
+  Registra la funzione \param{function} per la chiamata all'uscita dal
+  programma. 
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
     fallimento, \var{errno} non viene modificata.}
 \end{prototype}
 
-In questo caso la funzione da chiamare prende due parametri, il primo dei
-quali sarà inizializzato allo stato di uscita con cui è stata chiamata
-\func{exit} ed il secondo al puntatore generico specificato come secondo
-argomento nella chiamata di \func{on\_exit}. Così diventa possibile passare
-dei dati alla funzione di chiusura.
+In questo caso la funzione da chiamare all'uscita prende i due parametri
+specificati nel prototipo, dovrà cioè essere definita come \code{void
+  function(int status, void *argp)}. Il primo argomento sarà inizializzato
+allo stato di uscita con cui è stata chiamata \func{exit} ed il secondo al
+puntatore \param{arg} passato come secondo argomento di \func{on\_exit}.  Così
+diventa possibile passare dei dati alla funzione di chiusura.
 
 Nella sequenza di chiusura tutte le funzioni registrate verranno chiamate in
 ordine inverso rispetto a quello di registrazione (ed una stessa funzione
@@ -258,7 +266,7 @@ la cosiddetta \textsl{memoria virtuale}\index{memoria virtuale} che consiste
 nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare,
 in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel
   caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di
-  2Gb, con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite
+  2Gb. Con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite
   è stato esteso.}
 
 Come accennato in \capref{cha:intro_unix} questo spazio di indirizzi è
@@ -308,8 +316,8 @@ a tempi molto pi
 Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed
 in genere il sistema è molto efficiente in questo lavoro; quando però ci siano
 esigenze specifiche di prestazioni è possibile usare delle funzioni che
-permettono di bloccare il meccanismo della paginazione e mantenere fisse delle
-pagine in memoria (vedi \ref{sec:proc_mem_lock}).
+permettono di bloccare il meccanismo della paginazione\index{paginazione} e
+mantenere fisse delle pagine in memoria (vedi \ref{sec:proc_mem_lock}).
 
 
 \subsection{La struttura della memoria di un processo}
@@ -322,7 +330,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
@@ -365,7 +373,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
@@ -448,31 +456,31 @@ attraverso dei puntatori.
 \label{sec:proc_mem_malloc}
 
 Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
-quattro: \func{malloc}, \func{calloc}, \func{realloc} e \func{free}, i loro
-prototipi sono i seguenti:
+quattro: \funcd{malloc}, \funcd{calloc}, \funcd{realloc} e \funcd{free}, i
+loro prototipi sono i seguenti:
 \begin{functions}
 \headdecl{stdlib.h}
 \funcdecl{void *calloc(size\_t size)}
-  Alloca \var{size} byte nello heap. La memoria viene inizializzata a 0.
+  Alloca \param{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} assumerà il valore \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.
+  Alloca \param{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} assumerà il valore \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}.
+  Cambia la dimensione del blocco allocato all'indirizzo \param{ptr}
+  portandola a \param{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} assumerà il valore \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}.
+  Disalloca lo spazio di memoria puntato da \param{ptr}.
 
   La funzione non ritorna nulla e non riporta errori.
 \end{functions}
@@ -481,11 +489,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}
@@ -498,7 +511,7 @@ 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
+\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
@@ -514,36 +527,36 @@ spazio aggiunto non viene inizializzato.
 Si deve sempre avere ben presente il fatto che il blocco di memoria restituito
 da \func{realloc} può non essere un'estensione di quello che gli si è passato
 in ingresso; per questo si dovrà \emph{sempre} eseguire la riassegnazione di
-\var{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere
+\param{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere
 ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del
 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
@@ -558,33 +571,67 @@ 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
+\funcd{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} assumerà il valore \macro{ENOMEM}.
+  Alloca \param{size} byte nello stack.
+  
+  \bodydesc{La funzione restituisce il puntatore alla zona di memoria allocata
+    in caso 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 
-automaticamente al ritorno della funzione.
+
+La funzione alloca la quantità di memoria (non inizializzata) richiesta
+dall'argomento \param{size} nel segmento di stack della funzione chiamante.
+Con questa funzione non è più necessario liberare la memoria allocata (e
+quindi non esiste un analogo della \func{free}) in quanto essa viene
+rilasciata automaticamente al ritorno della funzione.
 
 Come è evidente questa funzione ha molti vantaggi, anzitutto permette di
 evitare alla radice i problemi di memory leak, dato che non serve più la
@@ -623,33 +670,43 @@ cui torneremo in \secref{sec:proc_auto_var}.
 \subsection{Le funzioni \func{brk} e \func{sbrk}}  
 \label{sec:proc_mem_sbrk}
 
-L'uso di queste funzioni è necessario solo quando si voglia accedere alle
-analoghe system call a cui fanno da interfaccia. I loro prototipi sono:
-\begin{functions}
-  \headdecl{unistd.h}
-  \funcdecl{int brk(void *end\_data\_segment)}
-  Sposta la fine del segmento dei dati all'indirizzo specificato da
-  \var{end\_data\_segment}.
+Queste due funzioni vengono utilizzate soltanto quando è necessario effettuare
+direttamente la gestione della memoria associata allo spazio dati di un
+processo, ad esempio qualora si debba implementare la propria versione delle
+routine di allocazione della memoria viste in \secref{sec:proc_mem_malloc}. La
+prima funzione è \funcd{brk}, ed il suo prototipo è:
+\begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)}
+  Sposta la fine del segmento dei dati.
   
-  La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, nel qual caso \var{errno} assumerà il valore \macro{ENOMEM}.
+  \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+    fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.}
+\end{prototype}
 
-  \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 è un'interfaccia diretta all'ominima system call ed imposta
+l'indirizzo finale del segmento dati di un processo all'indirizzo specificato
+da \param{end\_data\_segment}. Quest'ultimo deve essere un valore ragionevole,
+ed inoltre la dimensione totale del segmento non deve comunque eccedere un
+eventuale limite (si veda \secref{sec:sys_resource_limit}) imposto sulle
+dimensioni massime dello spazio dati del processo.
+
+La seconda funzione per la manipolazione delle dimensioni del segmento
+dati\footnote{in questo caso si tratta soltanto di una funzione di libreria, e
+  non di una sistem call.} è \funcd{sbrk}, ed il suo prototipo è:
+\begin{prototype}{unistd.h}{void *sbrk(ptrdiff\_t increment)} 
+  Incrementa la dimensione dello spazio 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} assumerà il valore \macro{ENOMEM}.
-\end{functions}
-\noindent in genere si usa \func{sbrk} con un valore zero per ottenere
-l'attuale posizione della fine del segmento dati.
+  \bodydesc{La funzione restituisce il puntatore all'inizio della nuova zona
+    di memoria allocata in caso di successo e \val{NULL} in caso di
+    fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.}
+\end{prototype}
+\noindent la funzione incrementa la dimensione lo spazio dati di un programma
+di \param{increment} byte, restituendo il nuovo indirizzo finale dello stesso.
+Un valore nullo permette di ottenere 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
-implementare una sua versione delle routine di allocazione.  
+standard descritte in precedenza, che sono costruite su di esse. 
 
 
 % \subsection{La personalizzazione delle funzioni di allocazione} 
@@ -670,12 +727,13 @@ trasparente, tutte le pagine che gli occorrono; esistono per
 particolari in cui non si vuole che questo meccanismo si attivi. In generale i
 motivi per cui si possono avere di queste necessità sono due:
 \begin{itemize}
-\item \textsl{La velocità}. Il processo della paginazione è trasparente solo
-  se il programma in esecuzione non è sensibile al tempo che occorre a
-  riportare la pagina in memoria; per questo motivo processi critici che hanno
-  esigenze di tempo reale o tolleranze critiche nelle risposte (ad esempio
-  processi che trattano campionamenti sonori) possono non essere in grado di
-  sopportare le variazioni della velocità di accesso dovuta alla paginazione.
+\item \textsl{La velocità}. Il processo della paginazione\index{paginazione} è
+  trasparente solo se il programma in esecuzione non è sensibile al tempo che
+  occorre a riportare la pagina in memoria; per questo motivo processi critici
+  che hanno esigenze di tempo reale o tolleranze critiche nelle risposte (ad
+  esempio processi che trattano campionamenti sonori) possono non essere in
+  grado di sopportare le variazioni della velocità di accesso dovuta alla
+  paginazione.
   
   In certi casi poi un programmatore può conoscere meglio dell'algoritmo di
   allocazione delle pagine le esigenze specifiche del suo programma e decidere
@@ -686,77 +744,85 @@ 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 (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.
+  paginazione\index{paginazione}. Questo rende più lungo il periodo di tempo
+  in cui detti segreti 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
-un processo è chiamato \textit{memory locking} (o \textsl{blocco della
-  memoria}). Il blocco è sempre associato alle pagine della memoria virtuale
-del processo, e non al segmento reale di RAM su cui essa viene mantenuta.
+Il meccanismo che previene la paginazione\index{paginazione} di parte della
+memoria virtuale di un processo è chiamato \textit{memory locking} (o
+\textsl{blocco della memoria}). Il blocco è sempre associato alle pagine della
+memoria virtuale del processo, e non al segmento reale di RAM su cui essa
+viene mantenuta.
 
 La regola è che se un segmento di RAM fa da supporto ad almeno una pagina
-bloccata allora esso viene escluso dal meccanismo della paginazione. I blocchi
-non si accumulano, se si blocca due volte la stessa pagina non è necessario
-sbloccarla due volte, una pagina o è bloccata oppure no.
+bloccata allora esso viene escluso dal meccanismo della
+paginazione\index{paginazione}. I blocchi non si accumulano, se si blocca due
+volte la stessa pagina non è necessario sbloccarla due volte, una pagina o è
+bloccata oppure no.
 
 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
-\func{mlock} e \func{munlock}; i loro prototipi sono:
+Le funzioni per bloccare e sbloccare la paginazione\index{paginazione} di
+singole sezioni di memoria sono \funcd{mlock} e \funcd{munlock}; i loro
+prototipi sono:
 \begin{functions}
   \headdecl{sys/mman.h} 
 
   \funcdecl{int mlock(const void *addr, size\_t len)}
-  Blocca la paginazione per l'intervallo di memoria da \var{addr} per
-  \var{len} byte. Tutte le pagine che contengono una parte dell'intervallo
-  sono mantenute in RAM per tutta la durata del blocco.
+  Blocca la paginazione su un intervallo di memoria.
 
   \funcdecl{int munlock(const void *addr, size\_t len)}
-  Sblocca l'intervallo di memoria da \var{addr} per \var{len} byte.  
+  Rimuove il blocco della paginazione su un intervallo di memoria.
 
   
   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in
     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}] \param{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}
 
-Altre due funzioni, \func{mlockall} e \func{munlockall}, consentono di
-bloccare genericamente lo spazio di indirizzi di un processo.  I prototipi di
-queste funzioni sono:
+Le due funzioni permettono rispettivamente di bloccare e sbloccare la
+paginazione per l'intervallo di memoria specificato dagli argomenti, che ne
+indicano nell'ordine l'indirizzo iniziale e la lunghezza.  Tutte le pagine che
+contengono una parte dell'intervallo sono mantenute in RAM per tutta la durata
+del blocco.
 
+Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono poi di
+bloccare genericamente la paginazione\index{paginazione} per l'intero spazio
+di indirizzi di un processo.  I prototipi di queste funzioni sono:
 \begin{functions}
   \headdecl{sys/mman.h} 
 
@@ -770,13 +836,13 @@ queste funzioni sono:
     e \func{munlock}.}
 \end{functions}
 
-Il parametro \var{flags} di \func{mlockall} permette di controllarne il
+L'argomento \param{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}
 
@@ -808,7 +874,7 @@ che esse siano state effettivamente portate in memoria, ci si scrive sopra.
 
 Tutti i programmi hanno la possibilità di ricevere parametri e opzioni quando
 vengono lanciati. Il passaggio dei parametri è effettuato attraverso gli
-argomenti \var{argc} e \var{argv} della funzione \func{main}, che vengono
+argomenti \param{argc} e \param{argv} della funzione \func{main}, che vengono
 passati al programma dalla shell (o dal processo che esegue la \func{exec},
 secondo le modalità che vedremo in \secref{sec:proc_exec}) quando questo viene
 messo in esecuzione. 
@@ -834,14 +900,14 @@ di ambiente \cmd{IFS}.
 \begin{figure}[htb]
   \centering
   \includegraphics[width=11cm]{img/argv_argc}
-  \caption{Esempio dei valori di \var{argv} e \var{argc} generati nella 
+  \caption{Esempio dei valori di \param{argv} e \param{argc} generati nella 
     scansione di una riga di comando.}
   \label{fig:proc_argv_argc}
 \end{figure}
 
-Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
+Nella scansione viene costruito il vettore di puntatori \param{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
+variabile \param{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 \figref{fig:proc_argv_argc}.
 
@@ -851,8 +917,8 @@ 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 il carattere \texttt{'-'} e che
-non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato
+tali: un elemento di \param{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
@@ -861,25 +927,25 @@ e la prima vuole un parametro mentre la seconda no (\cmd{questofile.txt} 
 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}
+\param{argv} le librerie standard del C forniscono la funzione \funcd{getopt},
 che ha il seguente prototipo:
 \begin{prototype}{unistd.h}
 {int getopt(int argc, char *const argv[], const char *optstring)}
 Esegue il parsing degli argomenti passati da linea di comando
-riconoscendo le possibili opzioni segnalate con \var{optstring}.
+riconoscendo le possibili opzioni segnalate con \param{optstring}.
 
 \bodydesc{Ritorna il carattere che segue l'opzione, \cmd{':'} se manca un
   parametro all'opzione, \cmd{'?'} se l'opzione è sconosciuta, e -1 se non
   esistono altre opzioni.}
 \end{prototype}
 
-Questa funzione prende come argomenti le due variabili \var{argc} e \var{argv}
-passate a \func{main} ed una stringa che indica quali sono le opzioni valide;
-la funzione effettua la scansione della lista degli argomenti ricercando ogni
-stringa che comincia con \cmd{-} e ritorna ogni volta che trova un'opzione
-valida.
+Questa funzione prende come argomenti le due variabili \param{argc} e
+\param{argv} passate a \func{main} ed una stringa che indica quali sono le
+opzioni valide; la funzione effettua la scansione della lista degli argomenti
+ricercando ogni stringa che comincia con \cmd{-} e ritorna ogni volta che
+trova un'opzione valida.
 
-La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
+La stringa \param{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 \texttt{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
@@ -888,11 +954,11 @@ 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
 che indica che non ci sono più opzioni. Nel caso si incontri un'opzione non
-dichiarata in \var{optstring} viene ritornato il carattere \texttt{'?'}
+dichiarata in \param{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
 \texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri
-elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
+elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
 
 \begin{figure}[htb]
   \footnotesize
@@ -937,7 +1003,7 @@ carattere, in questo modo si possono eseguire azioni specifiche usando uno
 \item \var{char *optarg} contiene il puntatore alla stringa parametro
   dell'opzione.
 \item \var{int optind} alla fine della scansione restituisce l'indice del
-  primo elemento di \var{argv} che non è un'opzione.
+  primo elemento di \param{argv} che non è un'opzione.
 \item \var{int opterr} previene, se posto a zero, la stampa di un messaggio
   di errore in caso di riconoscimento di opzioni non definite.
 \item \var{int optopt} contiene il carattere dell'opzione non riconosciuta.
@@ -956,21 +1022,21 @@ opzioni che prevedono un parametro si 
 (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}
-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})
-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
-attiva quando \var{optstring} inizia con il carattere \texttt{'-'}. In questo
-caso ogni elemento che non è un'opzione viene considerato comunque un'opzione
-e associato ad un valore di ritorno pari ad 1, questo permette di identificare
-gli elementi che non sono opzioni, ma non effettua il riordinamento del
-vettore \var{argv}.
+in \code{argv[]} del primo degli argomenti rimanenti nella linea di comando.
+
+Normalmente \func{getopt} compie una permutazione degli elementi di
+\param{argv} 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 \param{argv}; se \param{optstring} inizia
+con il carattere \texttt{'+'} (o è impostata la variabile di ambiente
+\macro{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 attiva quando \param{optstring} inizia con il carattere
+\texttt{'-'}. In questo caso ogni elemento che non è un'opzione viene
+considerato comunque un'opzione e associato ad un valore di ritorno pari ad 1,
+questo permette di identificare gli elementi che non sono opzioni, ma non
+effettua il riordinamento del vettore \param{argv}.
 
 
 \subsection{Opzioni in formato esteso}
@@ -994,8 +1060,8 @@ 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
-lunghezza dell'array data da un equivalente di \var{argc}, ma la lista è
+\val{NULL}. A differenza di \code{argv[]} in questo caso non si ha una
+lunghezza dell'array data da un equivalente di \param{argc}, ma la lista è
 terminata da un puntatore nullo.
 
 L'indirizzo della lista delle variabili di ambiente è passato attraverso la
@@ -1015,16 +1081,21 @@ pi
 \end{figure}
 
 Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo
-\textsl{\texttt{nome=valore}}. Inoltre alcune variabili, come quelle elencate
+\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.
+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
@@ -1049,35 +1120,38 @@ controllare \cmd{man environ}.
     & \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
+\funcd{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}
@@ -1113,10 +1187,11 @@ in \tabref{tab:proc_env_func}.
   \label{tab:proc_env_func}
 \end{table}
 
-In Linux solo le prime quattro funzioni di \tabref{tab:proc_env_func} 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, \funcd{putenv} e \funcd{setenv},
+servono per assegnare nuove variabili di ambiente, i loro prototipi sono i
+seguenti:
 \begin{functions}
   \headdecl{stdlib.h} 
   
@@ -1127,9 +1202,9 @@ 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
+\noindent la terza, \funcd{unsetenv}, serve a cancellare una variabile di
 ambiente; il suo prototipo è:
 \begin{functions}
   \headdecl{stdlib.h}
@@ -1149,7 +1224,7 @@ variabile esista gi
 immutata se uguale a zero.
 
 La seconda funzione prende come parametro una stringa analoga quella
-restituita da \func{getenv}, e sempre nella forma \var{NOME=valore}. Se la
+restituita da \func{getenv}, e sempre nella forma \code{NOME=valore}. Se la
 variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se
 invece esiste il suo valore sarà impostato a quello specificato da
 \param{string}. Si tenga presente che, seguendo lo standard SUSv2, le
@@ -1238,7 +1313,7 @@ Come vedremo nei capitoli successivi, non sempre 
 numero fisso di parametri per una funzione.  Lo standard ISO C prevede nella
 sua sintassi la possibilità di definire delle \textit{variadic function} che
 abbiano un numero variabile di argomenti, attraverso l'uso della
-\textit{ellipsis} \var{...} nella dichiarazione della funzione; ma non
+\textit{ellipsis} \code{...} nella dichiarazione della funzione; ma non
 provvede a livello di linguaggio alcun meccanismo con cui dette funzioni
 possono accedere ai loro argomenti.
 
@@ -1264,7 +1339,7 @@ il prototipo della funzione \func{execl} che vedremo in
 \end{lstlisting}
 in questo caso la funzione prende due parametri fissi ed un numero variabile
 di altri parametri (che verranno a costituire gli elementi successivi al primo
-del vettore \var{argv} passato al nuovo processo). Lo standard ISO C richiede
+del vettore \param{argv} passato al nuovo processo). Lo standard ISO C richiede
 inoltre che l'ultimo degli argomenti fissi sia di tipo
 \textit{self-promoting}\footnote{il linguaggio C prevede che quando si
   mescolano vari tipi di dati, alcuni di essi possano essere \textsl{promossi}
@@ -1286,7 +1361,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.
@@ -1322,7 +1397,7 @@ In generale si possono avere pi
 ciascuno andrà inizializzato con \macro{va\_start} e letto con \macro{va\_arg}
 e ciascuno potrà scandire la lista degli argomenti per conto suo. 
 
-Dopo l'uso di \macro{va\_end} la variabile \var{ap} diventa indefinita e
+Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
 successive chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati
 indefiniti anche chiamando \macro{va\_arg} specificando un tipo che non
 corrisponde a quello del parametro.
@@ -1332,7 +1407,7 @@ corpo principale della funzione, il passo 2) invece pu
 in una subroutine passandole il puntatore alla lista di argomenti; in questo
 caso però si richiede che al ritorno della funzione il puntatore non venga più
 usato (lo standard richiederebbe la chiamata esplicita di \macro{va\_end}),
-dato che il valore di \var{ap} risulterebbe indefinito.
+dato che il valore di \param{ap} risulterebbe indefinito.
 
 Esistono dei casi in cui è necessario eseguire più volte la scansione dei
 parametri e poter memorizzare una posizione durante la stessa.  La cosa più
@@ -1383,7 +1458,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}
@@ -1438,7 +1513,7 @@ ciclo di lettura principale, scartando l'input come errato.\footnote{a meno
 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
 capita. La funzione che permette di salvare il contesto dello stack è
-\func{setjmp}, il cui prototipo è:
+\funcd{setjmp}, il cui prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void setjmp(jmp\_buf env)}
@@ -1464,7 +1539,7 @@ chiamato \func{setjmp} ritorna, nel qual caso l'uso di \func{longjmp} pu
 comportare conseguenze imprevedibili (e di norma fatali per il processo).
   
 Come accennato per effettuare un salto non-locale ad un punto precedentemente
-stabilito con \func{setjmp} si usa la funzione \func{longjmp}; il suo
+stabilito con \func{setjmp} si usa la funzione \funcd{longjmp}; il suo
 prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
@@ -1511,8 +1586,16 @@ Uno dei punti critici dei salti non-locali 
 variabili, ed in particolare quello delle variabili automatiche della funzione
 a cui si ritorna. In generale le variabili globali e statiche mantengono i
 valori che avevano al momento della chiamata di \func{longjmp}, ma quelli
-delle variabili automatiche (o di quelle dichiarate \code{register}) sono in
-genere indeterminati.
+delle variabili automatiche (o di quelle dichiarate
+\direct{register}\footnote{la direttiva \direct{register} del compilatore
+  chiede che la variabile dichiarata tale sia mantenuta, nei limiti del
+  possibile, all'interno di un registro del processore. Questa direttiva
+  origina dai primi compilatori, quando stava al programmatore scrivere codice
+  ottimizzato, riservando esplicitamente alle variabili più usate l'uso dei
+  registri del processore. Oggi questa direttiva oggi è in disuso dato che
+  tutti i compilatori sono normalmente in grado di valutare con maggior
+  efficacia degli stessi programmatori quando sia il caso di eseguire questa
+  ottimizzazione.}) sono in genere indeterminati.
 
 Quello che succede infatti è che i valori delle variabili che sono tenute in
 memoria manterranno il valore avuto al momento della chiamata di
@@ -1521,7 +1604,13 @@ chiamata ad un'altra funzioni vengono salvati nel contesto nello stack)
 torneranno al valore avuto al momento della chiamata di \func{setjmp}; per
 questo quando si vuole avere un comportamento coerente si può bloccare
 l'ottimizzazione che porta le variabili nei registri dichiarandole tutte come
-\code{volatile}.
+\direct{volatile}\footnote{la direttiva \ctyp{volatile} informa il compilatore
+  che la variabile che è dichiarata può essere modificata, durante
+  l'esecuzione del nostro, da altri programmi. Per questo motivo occorre dire
+  al compilatore che non deve essere mai utilizzata l'ottimizzazione per cui
+  quanto opportuno essa viene mantenuta in un registro, poiché in questo modo
+  si perderebbero le eventuali modifiche fatte dagli altri programmi (che
+  avvengono solo in una copia posta in memoria).}.