Cambiato il riferimento nelle note di copyright alla nuova sezione invariante
[gapil.git] / process.tex
index 9f61d88cc9262ae9705916a33256f9895d839219..006947bc34838132a54e1fce083a7b3069fef5a8 100644 (file)
@@ -1,3 +1,13 @@
+%% process.tex
+%%
+%% Copyright (C) 2000-2004 Simone Piccardi.  Permission is granted to
+%% copy, distribute and/or modify this document under the terms of the GNU Free
+%% Documentation License, Version 1.1 or any later version published by the
+%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
+%% 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}
 
@@ -36,26 +46,24 @@ avvio, usando il programma \cmd{ld-linux.so}.  Questo programma prima carica
 le librerie condivise che servono al programma, poi effettua il link dinamico
 del codice e alla fine lo esegue. Infatti, a meno di non aver specificato il
 flag \texttt{-static} durante la compilazione, tutti i programmi in Linux sono
-incompleti e necessitano di essere linkati alle librerie condivise quando
-vengono avviati.  La procedura è controllata da alcune variabili di ambiente e
-dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati nella man
-page di \cmd{ld.so}.
+incompleti e necessitano di essere \textit{linkati} alle librerie condivise
+quando vengono avviati.  La procedura è controllata da alcune variabili di
+ambiente e dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati
+nella man page di \cmd{ld.so}.
 
 Il sistema fa partire qualunque programma chiamando la funzione \func{main};
 sta al programmatore chiamare così la funzione principale del programma da cui
 si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso
-linker darebbe luogo ad errori.
+\textit{linker} darebbe luogo ad errori.
 
 Lo standard ISO C specifica che la funzione \func{main} può non avere 
 argomenti o prendere due argomenti che rappresentano gli argomenti passati da
 linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    int main (int argc, char *argv[])
-\end{lstlisting}
+\includecodesnip{listati/main_def.c}
 
 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
-  *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
+\func{main}, che prevede la presenza di un terzo parametro, \code{char
+  *envp[]}, che fornisce l'\textsl{ambiente} (vedi sez.~\ref{sec:proc_environ})
 del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
 se si vogliono scrivere programmi portabili è meglio evitarla.
 
@@ -63,17 +71,17 @@ 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
 di chiamare direttamente la system call \func{\_exit}, che restituisce il
 controllo direttamente alla routine di conclusione dei processi del kernel.
 
-Oltre alla conclusione ``normale'' esiste anche la possibilità di una
-conclusione ``anomala'' del programma a causa della ricezione di un segnale
-(si veda \capref{cha:signals}) o della chiamata alla funzione \func{abort};
-torneremo su questo in \secref{sec:proc_termination}.
+Oltre alla conclusione ``\textsl{normale}'' esiste anche la possibilità di una
+conclusione ``\textsl{anomala}'' del programma a causa della ricezione di un
+segnale (si veda cap.~\ref{cha:signals}) o della chiamata alla funzione
+\func{abort}; torneremo su questo in sez.~\ref{sec:proc_termination}.
 
 Il valore di ritorno della funzione \func{main}, o quello usato nelle chiamate
 ad \func{exit} e \func{\_exit}, viene chiamato \textsl{stato di uscita} (o
@@ -99,14 +107,14 @@ universalmente seguita 
 
 Si tenga presente inoltre che non è una buona idea usare il codice di errore
 restituito dalla variabile \var{errno} (per i dettagli si veda
-\secref{sec:sys_errors}) come stato di uscita. In generale infatti una shell
+sez.~\ref{sec:sys_errors}) come stato di uscita. In generale infatti una shell
 non si cura del valore se non per vedere se è diverso da zero; inoltre il
 valore dello stato di uscita è sempre troncato ad 8 bit, per cui si potrebbe
 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.
 
@@ -114,12 +122,11 @@ valori di tipo \ctyp{int} 0 e 1.
 \subsection{Le funzioni \func{exit} e \func{\_exit}}
 \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
-standard ANSI C ed il cui prototipo è:
+Come accennato le funzioni usate per effettuare un'uscita ``\textit{normale}''
+da un 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}
@@ -127,18 +134,17 @@ standard ANSI C ed il cui prototipo 
 La funzione \func{exit} è pensata per eseguire una conclusione pulita di un
 programma che usi le librerie standard del C; essa esegue tutte le funzioni
 che sono state registrate con \func{atexit} e \func{on\_exit} (vedi
-\secref{sec:proc_atexit}), e chiude tutti gli stream effettuando il
+sez.~\ref{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.
+sez.~\ref{sec:file_fopen}), infine passa il controllo al kernel chiamando
+\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,10 +152,10 @@ 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
-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}).
+cap.~\ref{cha:process_handling}), manda un segnale \const{SIGCHLD} al processo
+padre (vedi sez.~\ref{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 sez.~\ref{sec:proc_wait}).
 
 
 \subsection{Le funzioni \func{atexit} e \func{on\_exit}}
@@ -167,39 +173,39 @@ pulizia al programmatore che la utilizza.
 all'utente, avere la possibilità di effettuare automaticamente la chiamata ad
 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 è:
+di 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 è \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 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
-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 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 impostata.}
+    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
@@ -214,7 +220,7 @@ Data l'importanza dell'argomento 
 in un sistema Unix l'unico modo in cui un programma può essere eseguito dal
 kernel è attraverso la chiamata alla system call \func{execve} (o attraverso
 una delle funzioni della famiglia \func{exec} che vedremo in
-\secref{sec:proc_exec}).
+sez.~\ref{sec:proc_exec}).
 
 Allo stesso modo l'unico modo in cui un programma può concludere
 volontariamente la sua esecuzione è attraverso una chiamata alla system call
@@ -222,18 +228,19 @@ 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 fig.~\ref{fig:proc_prog_start_stop}.
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=12cm]{img/proc_beginend}
+  \includegraphics[width=14cm]{img/proc_beginend}
   \caption{Schema dell'avvio e della conclusione di un programma.}
   \label{fig:proc_prog_start_stop}
 \end{figure}
 
 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}.
+fig.~\ref{fig:proc_prog_start_stop}); torneremo su questo aspetto in
+cap.~\ref{cha:signals}.
 
 
 
@@ -257,10 +264,10 @@ 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 è
+Come accennato in cap.~\ref{cha:intro_unix} questo spazio di indirizzi è
 virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del
 computer; in genere detto spazio non è neppure continuo (cioè non tutti gli
 indirizzi possibili sono utilizzabili, e quelli usabili non sono
@@ -269,10 +276,13 @@ necessariamente adiacenti).
 Per la gestione da parte del kernel la memoria virtuale viene divisa in pagine
 di dimensione fissa (che ad esempio sono di 4kb su macchine a 32 bit e 8kb
 sulle alpha, valori strettamente connessi all'hardware di gestione della
-memoria), e ciascuna pagina della memoria virtuale è associata ad un supporto
-che può essere una pagina di memoria reale o ad un dispositivo di stoccaggio
-secondario (in genere lo spazio disco riservato alla swap, o i file che
-contengono il codice).
+memoria),\footnote{con le versioni più recenti del kernel è possibile anche
+  utilizzare pagine di dimensioni maggiori, per sistemi con grandi
+  quantitativi di memoria in cui l'uso di pagine troppo piccole comporta una
+  perdita di prestazioni.} e ciascuna pagina della memoria virtuale è
+associata ad un supporto che può essere una pagina di memoria reale o ad un
+dispositivo di stoccaggio secondario (in genere lo spazio disco riservato alla
+swap, o i file che contengono il codice).
 
 Lo stesso pezzo di memoria reale (o di spazio disco) può fare da supporto a
 diverse pagine di memoria virtuale appartenenti a processi diversi (come
@@ -307,8 +317,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 sez.~\ref{sec:proc_mem_lock}).
 
 
 \subsection{La struttura della memoria di un processo}
@@ -321,7 +331,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
@@ -349,9 +359,7 @@ seguenti segmenti:
   La prima parte è il segmento dei dati inizializzati, che contiene le
   variabili il cui valore è stato assegnato esplicitamente. Ad esempio
   se si definisce:
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    double pi = 3.14;
-  \end{lstlisting}
+\includecodesnip{listati/pi.c}
   questo valore sarà immagazzinato in questo segmento. La memoria di questo
   segmento viene preallocata all'avvio del programma e inizializzata ai valori
   specificati.
@@ -359,22 +367,20 @@ seguenti segmenti:
   La seconda parte è il segmento dei dati non inizializzati, che contiene le
   variabili il cui valore non è stato assegnato esplicitamente. Ad esempio se
   si definisce:
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    int vect[100];
-  \end{lstlisting}
+\includecodesnip{listati/vect.c}
   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
+  Storicamente questo segmento viene chiamato BSS (da \textit{block started by
     symbol}). La sua dimensione è fissa.
   
 \item Lo \textit{heap}. Tecnicamente lo si può considerare l'estensione del
   segmento dati, a cui di solito è posto giusto di seguito. È qui che avviene
   l'allocazione dinamica della memoria; può essere ridimensionato allocando e
   disallocando la memoria dinamica con le apposite funzioni (vedi
-  \secref{sec:proc_mem_alloc}), ma il suo limite inferiore (quello adiacente
+  sez.~\ref{sec:proc_mem_alloc}), ma il suo limite inferiore (quello adiacente
   al segmento dati) ha una posizione fissa.
   
 \item Il segmento di \textit{stack}, che contiene lo \textit{stack} del
@@ -383,10 +389,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
+  ``\textsl{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.
@@ -394,13 +400,13 @@ seguenti segmenti:
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=5cm]{img/memory_layout}
-  \caption{Disposizione tipica dei segmenti di memoria di un processo}
+  \includegraphics[height=12cm]{img/memory_layout}
+  \caption{Disposizione tipica dei segmenti di memoria di un processo.}
   \label{fig:proc_mem_layout}
 \end{figure}
 
 Una disposizione tipica di questi segmenti è riportata in
-\figref{fig:proc_mem_layout}. Usando il comando \cmd{size} su un programma se
+fig.~\ref{fig:proc_mem_layout}. Usando il comando \cmd{size} su un programma se
 ne può stampare le dimensioni dei segmenti di testo e di dati (inizializzati e
 BSS); si tenga presente però che il BSS non è mai salvato sul file che
 contiene l'eseguibile, dato che viene sempre inizializzato a zero al
@@ -447,31 +453,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} 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.
+  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} 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}.
+  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} 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}.
+  Disalloca lo spazio di memoria puntato da \param{ptr}.
 
   La funzione non ritorna nulla e non riporta errori.
 \end{functions}
@@ -480,11 +486,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 +508,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
@@ -513,83 +524,117 @@ 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
+Un errore abbastanza frequente (specie se si ha a che fare con vettori 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 di 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}).
+  (vedi sez.~\ref{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}).
+non più utilizzata, quello che in inglese viene chiamato \textit{memory
+  leak}\index{memory leak}, 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ò
 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}.
+\textit{memory leak}\index{memory leak}.
+
+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 prestazioni
+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 prestazioni 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 prestazioni 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.
 
-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).
 
 
 \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}\index{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} viene impostata a \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
-deallocazione esplicita; inoltre la deallocazione automatica funziona anche
-quando si usa \func{longjmp} per uscire da una subroutine con un salto non
-locale da una funzione (vedi \secref{sec:proc_longjmp}).
+evitare alla radice i problemi di memory leak\index{memory leak}, dato che non
+serve più la deallocazione esplicita; inoltre la deallocazione automatica
+funziona anche quando si usa \func{longjmp} per uscire da una subroutine con
+un salto non locale da una funzione (vedi sez.~\ref{sec:proc_longjmp}).
 
 Un altro vantaggio è che in Linux la funzione è molto più veloce di
 \func{malloc} e non viene sprecato spazio, infatti non è necessario gestire un
@@ -616,39 +661,49 @@ che deve poi essere usata anche al di fuori della funzione in cui essa viene
 chiamata, dato che all'uscita dalla funzione lo spazio allocato diventerebbe
 libero, e potrebbe essere sovrascritto all'invocazione di nuove funzioni.
 Questo è lo stesso problema che si può avere con le variabili automatiche, su
-cui torneremo in \secref{sec:proc_auto_var}.
+cui torneremo in sez.~\ref{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 sez.~\ref{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} viene impostata a \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'omonima 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 sez.~\ref{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 system 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} viene impostata a \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} 
@@ -658,7 +713,7 @@ implementare una sua versione delle routine di allocazione.
 \subsection{Il controllo della memoria virtuale\index{memoria virtuale}}  
 \label{sec:proc_mem_lock}
 
-Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria
+Come spiegato in sez.~\ref{sec:proc_mem_gen} il kernel gestisce la memoria
 virtuale in maniera trasparente ai processi, decidendo quando rimuovere pagine
 dalla memoria per metterle nello swap, sulla base dell'utilizzo corrente da
 parte dei vari processi.
@@ -669,93 +724,102 @@ 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
   quali pagine di memoria è opportuno che restino in memoria per un aumento
   delle prestazioni. In genere queste sono esigenze particolari e richiedono
   anche un aumento delle priorità in esecuzione del processo (vedi
-  \secref{sec:proc_real_time}).
+  sez.~\ref{sec:proc_real_time}).
   
 \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.
+  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 sez.~\ref{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 sez.~\ref{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} è 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}] \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\index{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 bloccato sono
+mantenute in RAM per tutta la durata del blocco.
 
+Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono 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} 
 
@@ -769,31 +833,31 @@ 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 verranno mappate nello
   spazio di indirizzi del processo.
 \end{basedescript}
 
-Con \func{mlockall} si può bloccare tutte le pagine mappate nello spazio di
-indirizzi del processo, sia che comprendano il segmento di testo, di dati, lo
-stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
+Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
+di indirizzi del processo, sia che comprendano il segmento di testo, di dati,
+lo stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
 memoria, i dati del kernel mappati in user space, la memoria condivisa.  L'uso
 dei flag permette di selezionare con maggior finezza le pagine da bloccare, ad
 esempio limitandosi a tutte le pagine allocate a partire da un certo momento.
 
 In ogni caso un processo real-time che deve entrare in una sezione critica
 deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
-scongiurare in partenza un eventuale page fault\index{page fault} causato dal
-meccanismo di \textit{copy on write}\index{copy on write}.  Infatti se nella
-sezione critica si va ad utilizzare memoria che non è ancora stata riportata
-in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
-conseguente rallentamento (probabilmente inaccettabile) dei tempi di
-esecuzione.
+scongiurare l'occorrenza di un eventuale \textit{page fault}\index{page fault}
+causato dal meccanismo di \textit{copy on write}\index{copy on write}.
+Infatti se nella sezione critica si va ad utilizzare memoria che non è ancora
+stata riportata in RAM si potrebbe avere un page fault durante l'esecuzione
+della stessa, con conseguente rallentamento (probabilmente inaccettabile) dei
+tempi di esecuzione.
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
@@ -807,16 +871,16 @@ 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. 
+secondo le modalità che vedremo in sez.~\ref{sec:proc_exec}) quando questo
+viene messo in esecuzione.
 
 Oltre al passaggio dei parametri, un'altra modalità che permette di passare
 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.
 
 
@@ -833,16 +897,16 @@ 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 \curfig.
+questo meccanismo è mostrato in fig.~\ref{fig:proc_argv_argc}.
 
 
 \subsection{La gestione delle opzioni}
@@ -850,81 +914,55 @@ 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 \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
+fig.~\ref{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}
+\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 \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 fig.~\ref{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
 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
-\cmd{--} la scansione viene considerata conclusa, anche se vi sono altri
-elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
+\texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri
+elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
 
 \begin{figure}[htb]
-  \footnotesize
-    \begin{lstlisting}{}
-    opterr = 0;  /* don't want writing to stderr */
-    while ( (i = getopt(argc, argv, "hp:c:e:")) != -1) {
-        switch (i) {
-        /* 
-         * Handling options 
-         */ 
-        case 'h':   /* help option */
-            printf("Wrong -h option use\n");
-            usage();
-            return -1;
-            break;
-        case 'c':   /* take wait time for childen */
-            wait_child = strtol(optarg, NULL, 10);    /* convert input */
-            break;
-        case 'p':   /* take wait time for childen */
-            wait_parent = strtol(optarg, NULL, 10);   /* convert input */
-            break;
-        case 'e':   /* take wait before parent exit */
-            wait_end = strtol(optarg, NULL, 10);      /* convert input */
-            break;
-        case '?':   /* unrecognized options */
-            printf("Unrecognized options -%c\n",optopt);
-            usage();
-        default:    /* should not reached */
-            usage();
-        }
-    }
-    debug("Optind %d, argc %d\n",optind,argc);
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+  \includecodesample{listati/option_code.c}
+  \end{minipage}
+  \normalsize
   \caption{Esempio di codice per la gestione delle opzioni.}
   \label{fig:proc_options_code}
 \end{figure}
@@ -936,41 +974,40 @@ 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.
 \end{itemize*}
 
-In \figref{fig:proc_options_code} è mostrata la sezione del programma
+In fig.~\ref{fig:proc_options_code} è mostrata la sezione del programma
 \file{ForkTest.c} (che useremo nel prossimo capitolo per effettuare dei test
 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.
-
-Normalmente \func{getopt} compie una permutazione degli elementi di \var{argv}
-così che 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}.
+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 \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}
@@ -992,20 +1029,19 @@ sistema un \textsl{ambiente}, nella forma di una lista di variabili (detta
 \textit{environment list}) messa a disposizione dal processo, e costruita
 nella chiamata alla funzione \func{exec} quando questo viene lanciato.
 
-Come per la lista dei parametri anche questa lista è un array di puntatori a
+Come per la lista dei parametri anche questa lista è un vettore 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 del vettore 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
 variabile globale \var{environ}, a cui si può accedere attraverso una semplice
 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.
+\includecodesnip{listati/env_ptr.c}
+un esempio della struttura di questa lista, contenente alcune delle variabili
+più comuni che normalmente sono definite dal sistema, è riportato in
+fig.~\ref{fig:proc_envirno_list}.
 \begin{figure}[htb]
   \centering
   \includegraphics[width=11cm]{img/environ_var}
@@ -1014,66 +1050,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 fig.~\ref{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. 
-
-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à).
+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 sez.~\ref{sec:proc_exec}).
+
+La shell ad esempio ne usa molte per il suo funzionamento (come \texttt{PATH}
+per la ricerca dei comandi, o \texttt{IFS} per la scansione degli argomenti),
+e alcune di esse (come \texttt{HOME}, \texttt{USER}, etc.) sono definite al
+login (per i dettagli si veda sez.~\ref{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 \texttt{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 tab.~\ref{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$ & 
-    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\\
+    \texttt{USER}   &$\bullet$&$\bullet$&$\bullet$& Nome utente\\
+    \texttt{LOGNAME}&$\bullet$&$\bullet$&$\bullet$& Nome di login\\
+    \texttt{HOME}   &$\bullet$&$\bullet$&$\bullet$& Directory base
+                                                    dell'utente\\
+    \texttt{LANG}   &$\bullet$&$\bullet$&$\bullet$& Localizzazione\\
+    \texttt{PATH}   &$\bullet$&$\bullet$&$\bullet$& Elenco delle directory
+                                                    dei programmi\\
+    \texttt{PWD}    &$\bullet$&$\bullet$&$\bullet$& Directory corrente\\
+    \texttt{SHELL}  &$\bullet$&$\bullet$&$\bullet$& Shell in uso\\
+    \texttt{TERM}   &$\bullet$&$\bullet$&$\bullet$& Tipo di terminale\\
+    \texttt{PAGER}  &$\bullet$&$\bullet$&$\bullet$& Programma per vedere i
+                                                    testi\\
+    \texttt{EDITOR} &$\bullet$&$\bullet$&$\bullet$& Editor preferito\\
+    \texttt{BROWSER}&$\bullet$&$\bullet$&$\bullet$& Browser preferito\\
+    \texttt{TMPDIR} &$\bullet$&$\bullet$&$\bullet$& Directory dei file
+                                                    temporanei\\
     \hline
   \end{tabular}
-  \caption{Variabili di ambiente più comuni definite da vari standard.}
+  \caption{Esempi delle 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}
@@ -1082,35 +1129,38 @@ 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 tab.~\ref{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} & 
     \textbf{SVr4} & \textbf{BSD} & \textbf{Linux} \\
     \hline
     \hline
-    \func{getenv} & $\bullet$ &  $\bullet$ & $\bullet$ & 
-      $\bullet$ & $\bullet$ & $\bullet$ \\
-    \func{setenv} &   &   &    & 
-        & $\bullet$ & $\bullet$ \\
-    \func{unsetenv} &  &   &    & 
-        & $\bullet$ & $\bullet$ \\
-    \func{putenv} &  & opz.  & $\bullet$ & 
-        & $\bullet$ & $\bullet$ \\
-    \func{clearenv} &  & opz.  &    & 
-        &  &  \\
+    \func{getenv}  & $\bullet$ & $\bullet$ & $\bullet$ 
+                   & $\bullet$ & $\bullet$ & $\bullet$ \\
+    \func{setenv}  &    --     &    --     &   --      
+                   &    --     & $\bullet$ & $\bullet$ \\
+    \func{unsetenv}&    --     &    --     &   --       
+                   &    --     & $\bullet$ & $\bullet$ \\
+    \func{putenv}  &    --     & opz.      & $\bullet$ 
+                   &    --     & $\bullet$ & $\bullet$ \\
+    \func{clearenv}&    --     & opz.      &   --
+                   &    --     &    --     & $\bullet$ \\
     \hline
   \end{tabular}
   \caption{Funzioni per la gestione delle variabili di ambiente.}
   \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
+In Linux\footnote{in realtà nelle libc4 e libc5 sono definite solo le prime
+  quattro, \func{clearenv} è stata introdotta con le \acr{glibc} 2.0.} sono
+definite tutte le funzioni elencate in tab.~\ref{tab:proc_env_func}. La prima,
+\func{getenv}, l'abbiamo appena esaminata; delle 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} 
@@ -1122,9 +1172,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}
@@ -1144,7 +1194,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
@@ -1154,25 +1204,43 @@ invece esiste il suo valore sar
   seguendo il comportamento di BSD4.4; dato che questo può dar luogo a perdite
   di memoria e non rispetta lo standard. Il comportamento è stato modificato a
   partire dalle 2.1.2, eliminando anche, sempre in conformità a SUSv2,
-  l'attributo \ctyp{const} dal prototipo.} \param{string} alla lista delle
+  l'attributo \direct{const} dal prototipo.} \param{string} alla lista delle
 variabili di ambiente; pertanto ogni cambiamento alla stringa in questione si
 riflette automaticamente sull'ambiente, e quindi si deve evitare di passare a
 questa funzione una variabile automatica (per evitare i problemi esposti in
-\secref{sec:proc_auto_var}).
+sez.~\ref{sec:proc_auto_var}).
 
 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
-\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.
+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
+sez.~\ref{sec:proc_exec}) è piazzato al di sopra dello stack, (vedi
+fig.~\ref{fig:proc_mem_layout}) e non nello heap e non può essere deallocato.
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
 liberata.
 
+L'ultima funzione è \funcd{clearenv}, che viene usata per cancellare
+completamente tutto l'ambiente; il suo prototipo è:
+\begin{functions}
+  \headdecl{stdlib.h}
+  
+  \funcdecl{int clearenv(void)} 
+  Cancella tutto l'ambiente.
+  
+  \bodydesc{la funzione restituisce 0 in caso di successo e un valore diverso
+    da zero per un errore.}
+\end{functions}
+
+In genere si usa questa funzione in maniera precauzionale per evitare i
+problemi di sicurezza connessi nel trasmettere ai programmi che si invocano un
+ambiente che può contenere dei dati non controllati. In tal caso si provvede
+alla cancellazione di tutto l'ambiente per costruirne una versione
+``\textsl{sicura}'' da zero.
+
 
 \section{Problematiche di programmazione generica}
 \label{sec:proc_gen_prog}
@@ -1218,10 +1286,11 @@ nella programmazione normale.
 
 Talvolta però è necessario che la funzione possa restituire indietro alla
 funzione chiamante un valore relativo ad uno dei suoi parametri.  Per far
-questo si usa il cosiddetto \textit{value result argument}, si passa cioè,
-invece di una normale variabile, un puntatore alla stessa; vedremo alcuni
-esempi di questa modalità nelle funzioni che gestiscono i socket (in
-\secref{sec:TCPel_functions}), in cui, per permettere al kernel di restituire
+questo si usa il cosiddetto
+\index{\textit{value~result~argument}}\textit{value result argument}, si passa
+cioè, invece di una normale variabile, un puntatore alla stessa; vedremo
+alcuni esempi di questa modalità nelle funzioni che gestiscono i socket (in
+sez.~\ref{sec:TCP_functions}), in cui, per permettere al kernel di restituire
 informazioni sulle dimensioni delle strutture degli indirizzi utilizzate,
 viene usato questo meccanismo.
 
@@ -1231,11 +1300,11 @@ viene usato questo meccanismo.
 
 Come vedremo nei capitoli successivi, non sempre è possibile specificare un
 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
-provvede a livello di linguaggio alcun meccanismo con cui dette funzioni
-possono accedere ai loro argomenti.
+sua sintassi la possibilità di definire delle \textit{variadic
+  function}\index{variadic} che abbiano un numero variabile di argomenti,
+attraverso l'uso della \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.
 
 L'accesso viene invece realizzato dalle librerie standard che provvedono gli
 strumenti adeguati.  L'uso delle \textit{variadic function} prevede tre punti:
@@ -1249,27 +1318,25 @@ strumenti adeguati.  L'uso delle \textit{variadic function} prevede tre punti:
   a seguire gli addizionali.
 \end{itemize*}
 
-Lo standard ISO C prevede che una \textit{variadic function} abbia sempre
-almeno un argomento fisso; prima di effettuare la dichiarazione deve essere
-incluso l'apposito header file \file{stdarg.h}; un esempio di dichiarazione è
-il prototipo della funzione \func{execl} che vedremo in
-\secref{sec:proc_exec}:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-  int execl(const char *path, const char *arg, ...);
-\end{lstlisting}
+Lo standard ISO C prevede che una \textit{variadic function}\index{variadic}
+abbia sempre almeno un argomento fisso; prima di effettuare la dichiarazione
+deve essere incluso l'apposito header file \file{stdarg.h}; un esempio di
+dichiarazione è il prototipo della funzione \func{execl} che vedremo in
+sez.~\ref{sec:proc_exec}:
+\includecodesnip{listati/exec_sample.c}
 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}
   per compatibilità; ad esempio i tipi \ctyp{float} vengono convertiti
   automaticamente a \ctyp{double} ed i \ctyp{char} e gli \ctyp{short} ad
   \ctyp{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
-  a sé stesso.} il che esclude array, puntatori a funzioni e interi di tipo
+  a sé stesso.} il che esclude vettori, puntatori a funzioni e interi di tipo
 \ctyp{char} o \ctyp{short} (con segno o meno). Una restrizione ulteriore di
 alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
-\ctyp{register}.
+\direct{register}.
 
 Una volta dichiarata la funzione il secondo passo è accedere ai vari parametri
 quando la si va a definire. I parametri fissi infatti hanno un loro nome, ma
@@ -1281,7 +1348,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.
@@ -1317,7 +1384,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.
@@ -1327,7 +1394,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ù
@@ -1338,12 +1405,13 @@ stack all'indirizzo dove sono stati salvati i parametri, 
 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
-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
-permette di eseguire la copia di un puntatore alla lista degli argomenti:
+motivo \macro{va\_list} è definito come \textsl{tipo opaco}\index{tipo!opaco}
+e non può essere 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 permette di eseguire la copia di un
+puntatore alla lista degli argomenti:
 \begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
   Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
   su \param{dest}.
@@ -1378,7 +1446,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}
@@ -1405,83 +1473,93 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}.
 Il controllo del flusso di un programma in genere viene effettuato con le
 varie istruzioni del linguaggio C; fra queste la più bistrattata è il
 \code{goto}, che viene deprecato in favore dei costrutti della programmazione
-strutturata, che rendono il codice più leggibile e mantenibile . Esiste però
-un caso in cui l'uso di questa istruzione porta all'implementazione più
-efficiente e chiara anche dal punto di vista della struttura del programma:
-quello dell'uscita in caso di errore.
-
-Il C però non consente di effettuare un salto ad una label definita in
-un'altra funzione, per cui se l'errore avviene in una funzione e la sua
-gestione ordinaria è in un'altra occorre usare quello che viene chiamato un
-\textsl{salto non-locale}.  Il caso classico in cui si ha questa necessità,
-citato sia da \cite{APUE} che da da \cite{glibc}, è quello di un programma nel
-cui corpo principale in cui viene letto un input del quale viene eseguita,
-attraverso una serie di funzioni di analisi, una scansione dei contenuti da cui
-ottenere le indicazioni per l'esecuzione di opportune operazioni.
+strutturata, che rendono il codice più leggibile e mantenibile. Esiste però un
+caso in cui l'uso di questa istruzione porta all'implementazione più
+efficiente e più chiara anche dal punto di vista della struttura del
+programma: quello dell'uscita in caso di errore.
+
+Il C però non consente di effettuare un salto ad una etichetta definita in
+un'altra funzione, per cui se l'errore avviene in una funzione, e la sua
+gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un
+\textsl{salto non-locale}\index{salto non-locale}.  Il caso classico in cui si
+ha questa necessità, citato sia da \cite{APUE} che da \cite{glibc}, è quello
+di un programma nel cui corpo principale vengono letti dei dati in ingresso
+sui quali viene eseguita, tramite una serie di funzioni di analisi, una
+scansione dei contenuti da si ottengono le indicazioni per l'esecuzione delle
+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
+in fasi diverse, la rilevazione di un errore nei dati in ingresso 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.}
-
-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 è:
+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.  Questo comporterebbe una notevole complessità, 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\index{salto non-locale}.}
+
+Tutto ciò può essere realizzato proprio con un salto non-locale; questo di
+norma viene realizzato salvando il contesto dello stack nel punto in cui si
+vuole tornare in caso di errore, e ripristinandolo, in modo da tornare nella
+funzione da cui si era partiti, quando serve.  La funzione che permette di
+salvare il contesto dello stack è \funcd{setjmp}, il cui prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
-  \funcdecl{void setjmp(jmp\_buf env)}
+  \funcdecl{int setjmp(jmp\_buf env)}
   
-  Salva il contesto dello stack in \param{env} per un successivo uso da parte
-  di \func{longjmp}. 
+  Salva il contesto dello stack. 
 
   \bodydesc{La funzione ritorna zero quando è chiamata direttamente e un
     valore diverso da zero quando ritorna da una chiamata di \func{longjmp}
     che usa il contesto salvato in precedenza.}
 \end{functions}
-
-Quando si esegue la funzione il contesto viene salvato in appositi oggetti (di
-tipo \type{jmp\_buf}), passati come primo argomento alla funzione, in genere
-questi vengono definiti come variabili globali in modo da poter essere visti
-in tutte le funzioni del programma.
+  
+Quando si esegue la funzione il contesto corrente dello stack viene salvato
+nell'argomento \param{env}, una variabile di tipo
+\type{jmp\_buf}\footnote{questo è un classico esempio di variabile di
+  \textsl{tipo opaco}\index{tipo!opaco}. Si definiscono così strutture ed
+  altri oggetti usati da una libreria, la cui struttura interna non deve
+  essere vista dal programma chiamante (da cui il nome) che li devono
+  utilizzare solo attraverso dalle opportune funzioni di gestione.}  che deve
+essere stata definita in precedenza. In genere le variabili di tipo
+\type{jmp\_buf} vengono definite come variabili globali in modo da poter
+essere viste in tutte le funzioni del programma.
 
 Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
 diverso da zero viene restituito solo quando il ritorno è dovuto ad una
-chiamata di \func{longjmp} in un'altra parte del programma. Si tenga conto che
-il contesto salvato in \param{env} viene invalidato se la routine che ha
-chiamato \func{setjmp} ritorna, nel qual caso l'uso di \func{longjmp} può
-comportare conseguenze imprevedibili (e di norma fatali per il processo).
+chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
+stack effettuando il salto non-locale\index{salto non-locale}. Si tenga conto
+che il contesto salvato in \param{env} viene invalidato se la routine che ha
+chiamato \func{setjmp} ritorna, nel qual caso un successivo 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
-prototipo è:
+Come accennato per effettuare un salto non-locale\index{salto non-locale} ad
+un punto precedentemente stabilito con \func{setjmp} si usa la funzione
+\funcd{longjmp}; il suo prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void longjmp(jmp\_buf env, int val)}
   
-  Ripristina il contesto dello stack salvato nell'ultima chiamata di
-  \func{setjmp} con l'argomento \param{env}.
+  Ripristina il contesto dello stack.
   
   \bodydesc{La funzione non ritorna.}
 \end{functions}
 
-Dopo l'esecuzione della funzione programma prosegue dal codice successivo al
-ritorno della \func{setjmp} con cui si era salvato \param{env}, che restituirà
-il valore \param{val} invece di zero.  Il valore di \param{val} specificato
-nella chiamata deve essere diverso da zero, se si è specificato 0 sarà
-comunque restituito 1 al suo posto.
+La funzione ripristina il contesto dello stack salvato da una chiamata a
+\func{setjmp} nell'argomento \param{env}. Dopo l'esecuzione della funzione il
+programma prosegue nel codice successivo al ritorno della \func{setjmp} con
+cui si era salvato \param{env}, che restituirà il valore \param{val} invece di
+zero.  Il valore di \param{val} specificato nella chiamata deve essere diverso
+da zero, se si è specificato 0 sarà comunque restituito 1 al suo posto.
 
 In sostanza un \func{longjmp} è analogo ad un \code{return}, solo che invece
 di ritornare alla riga successiva della funzione chiamante, il programma
-ritorna alla posizione della relativa \func{setjmp}, ed il ritorno può essere
-effettuato anche attraverso diversi livelli di funzioni annidate.
+ritorna alla posizione della relativa \func{setjmp}, l'altra differenza è che
+il ritorno può essere effettuato anche attraverso diversi livelli di funzioni
+annidate.
 
 L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
 interagiscono direttamente con la gestione dello stack ed il funzionamento del
@@ -1503,21 +1581,35 @@ In generale, dato che l'unica differenza fra la chiamata diretta e quella
 ottenuta da un \func{longjmp}, è il valore di ritorno di \func{setjmp}, essa è
 usualmente chiamata all'interno di un comando \code{if}. 
 
-Uno dei punti critici dei salti non-locali è quello del valore delle
-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.
+Uno dei punti critici dei salti non-locali\index{salto non-locale} è quello
+del valore delle 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
+\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 è
+  originaria dell'epoca 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 è 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
 \func{longjmp}, mentre quelli tenuti nei registri del processore (che nella
-chiamata ad un'altra funzioni vengono salvati nel contesto nello stack)
+chiamata ad un'altra funzione 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 \direct{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).}.