Sistemata la parte della allocazione della memoria, le variadic
[gapil.git] / process.tex
index 70ccc6113c5b5109d07d9ea8a592fd551c18ef98..8ea65d75e52f5beab2157b991aa9dc9b14f639bd 100644 (file)
@@ -167,7 +167,7 @@ librerie condivise da esso utilizzate.
 
 Vedremo nel resto della guida quali sono le risorse del sistema accessibili
 attraverso le \textit{system call} e tratteremo buona parte delle funzioni
-messe a disposizione dalla Libreria Standard del C, in questa sezione però si
+messe a disposizione dalla libreria standard del C, in questa sezione però si
 forniranno alcune indicazioni generali sul come fare perché un programma possa
 utilizzare queste funzioni.
 
@@ -193,7 +193,7 @@ volta essere definite prima delle varie inclusioni.
 
 Ogni libreria fornisce i propri file di intestazione per i quali si deve
 consultare la documentazione, ma in tab.~\ref{tab:intro_posix_header} si sono
-riportati i principali \textit{header file} definiti nella Libreria Standard
+riportati i principali \textit{header file} definiti nella libreria standard
 del C (nel caso la \acr{glibc}) che contengono le varie funzioni previste
 negli standard POSIX ed ANSI C, e che prevedono la definizione sia delle
 funzioni di utilità generica che delle interfacce alle \textit{system call}. In
@@ -356,10 +356,10 @@ direttamente valori numerici.
 \label{sec:proc_conclusion}
 
 Normalmente un programma conclude la sua esecuzione quando si fa ritornare la
-funzione \func{main}, si usa cioè l'istruzione \texttt{return} del linguaggio
-C all'interno della stessa, o se si richiede esplicitamente la chiusura
-invocando direttamente la funzione \func{exit}. Queste due modalità sono
-assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera
+funzione \func{main}, si usa cioè l'istruzione \instruction{return} del
+linguaggio C all'interno della stessa, o se si richiede esplicitamente la
+chiusura invocando direttamente la funzione \func{exit}. Queste due modalità
+sono assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera
 trasparente anche quando \func{main} ritorna, passandogli come argomento il
 valore di ritorno (che essendo .
 
@@ -376,7 +376,7 @@ standard ANSI C, è quella che deve essere invocata per una terminazione
 \end{funcproto}
 
 La funzione è pensata per eseguire una conclusione pulita di un programma che
-usi la Libreria Standard del C; essa esegue tutte le funzioni che sono state
+usi la libreria standard del C; essa esegue tutte le funzioni che sono state
 registrate con \func{atexit} e \func{on\_exit} (vedi
 sez.~\ref{sec:proc_atexit}), chiude tutti gli stream effettuando il
 salvataggio dei dati sospesi (chiamando \func{fclose}, vedi
@@ -446,7 +446,7 @@ però non comporta il salvataggio dei dati eventualmente presenti nei buffer
 degli stream, (torneremo sulle due interfacce dei file a partire da
 cap.~\ref{cha:file_intro}). Infine fa sì che ogni figlio del processo sia
 adottato da \cmd{init} (vedi cap.~\ref{cha:process_handling}), manda un
-segnale \const{SIGCHLD} al processo padre (vedi
+segnale \signal{SIGCHLD} al processo padre (vedi
 sez.~\ref{sec:sig_job_control}) e ritorna lo stato di uscita specificato
 in \param{status} che può essere raccolto usando la funzione \func{wait} (vedi
 sez.~\ref{sec:proc_wait}).
@@ -635,6 +635,7 @@ 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 è stato esteso anche per macchine a 32 bit.}
 
+
 Come accennato nel cap.~\ref{cha:intro_unix} questo spazio di indirizzi è
 virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del
 computer. In generale detto spazio non è neppure continuo, cioè non tutti gli
@@ -642,19 +643,25 @@ indirizzi possibili sono utilizzabili, e quelli usabili non sono
 necessariamente adiacenti.
 
 Per la gestione da parte del kernel la memoria viene divisa in pagine di
-dimensione fissa,\footnote{inizialmente questi erano di 4kb sulle macchine a
-  32 bit e di 8kb sulle alpha, con le versioni più recenti del kernel è
-  possibile anche utilizzare pagine di dimensioni maggiori (4Mb), per sistemi
-  con grandi quantitativi di memoria in cui l'uso di pagine troppo piccole
-  comporta una perdita di prestazioni.} e ciascuna pagina nello spazio di
-indirizzi virtuale è associata ad un supporto che può essere una pagina di
-memoria reale o ad un dispositivo di stoccaggio secondario (come lo spazio
-disco riservato alla \textit{swap}, o i file che contengono il codice). Per
-ciascun processo il kernel si cura di mantenere un mappa di queste
-corrispondenze nella cosiddetta \itindex{page~table} \textit{page
-  table}.\footnote{questa è una semplificazione brutale, il meccanismo è molto
-  più complesso; una buona trattazione di come Linux gestisce la memoria
-  virtuale si trova su \cite{LinVM}.}
+dimensione fissa. Inizialmente queste pagine erano di 4kb sulle macchine a 32
+bit e di 8kb sulle alpha. Con le versioni più recenti del kernel è possibile
+anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette \textit{huge
+  page}), per sistemi con grandi quantitativi di memoria in cui l'uso di
+pagine troppo piccole comporta una perdita di prestazioni. In alcuni sistemi
+la costante \const{PAGE\_SIZE}, definita in \file{limits.h}, indica la
+dimensione di una pagina in byte, con Linux questo non avviene e per ottenere
+questa dimensione si deve ricorrere alla funzione \func{getpagesize} (vedi
+sez.~\ref{sec:sys_memory_res}).
+
+Ciascuna pagina di memoria nello spazio di indirizzi virtuale è associata ad
+un supporto che può essere una pagina di memoria reale o ad un dispositivo di
+stoccaggio secondario (come lo spazio disco riservato alla \textit{swap}, o i
+file che contengono il codice). Per ciascun processo il kernel si cura di
+mantenere un mappa di queste corrispondenze nella cosiddetta
+\itindex{page~table} \textit{page table}.\footnote{questa è una
+  semplificazione brutale, il meccanismo è molto più complesso; una buona
+  trattazione di come Linux gestisce la memoria virtuale si trova su
+  \cite{LinVM}.}
 
 Una stessa pagina di memoria reale può fare da supporto a diverse pagine di
 memoria virtuale appartenenti a processi diversi, come accade in genere per le
@@ -707,57 +714,70 @@ commette quando si è manipolato male un puntatore e genera quella che viene
 chiamata una \itindex{segment~violation} \textit{segment violation}. Se si
 tenta cioè di leggere o scrivere con un indirizzo per il quale non esiste
 un'associazione nella memoria virtuale, il kernel risponde al relativo
-\itindex{page~fault} \textit{page fault} mandando un segnale \const{SIGSEGV}
+\itindex{page~fault} \textit{page fault} mandando un segnale \signal{SIGSEGV}
 al processo, che normalmente ne causa la terminazione immediata.
 
 È pertanto importante capire come viene strutturata \index{memoria~virtuale}
 la memoria virtuale di un processo. Essa viene divisa in \textsl{segmenti},
 cioè un insieme contiguo di indirizzi virtuali ai quali il processo può
 accedere.  Solitamente un programma C viene suddiviso nei seguenti segmenti:
-
-\begin{enumerate}
+\begin{enumerate*}
 \item Il \index{segmento!testo} segmento di testo o \textit{text segment}.
   Contiene il codice del programma, delle funzioni di librerie da esso
   utilizzate, e le costanti.  Normalmente viene condiviso fra tutti i processi
   che eseguono lo stesso programma e nel caso delle librerie anche da processi
-  che eseguono altri programmi.  Viene marcato in sola lettura per evitare
-  sovrascritture accidentali (o maliziose) che ne modifichino le istruzioni.
-  
-  Viene allocato da \func{execve} all'avvio del programma e resta invariato
-  per tutto il tempo dell'esecuzione.
-  
-\item Il \index{segmento!dati} segmento dei dati o \textit{data segment}.
-  Contiene le variabili globali, cioè quelle definite al di fuori di tutte le
-  funzioni che compongono il programma, e le variabili statiche, cioè quelle
-  dichiarate con l'attributo \ctyp{static}. Di norma è diviso in due parti.
-  
-  La prima parte è il segmento dei dati inizializzati, che contiene le
-  variabili il cui valore è stato assegnato esplicitamente. Ad esempio
-  se si definisce:
-\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.
-  
-  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:
-\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 \val{NULL}).\footnote{si ricordi che questo vale solo per le
-    variabili che vanno nel segmento dati, e non è affatto vero in generale.}
-   
-  Storicamente questa seconda parte del segmento dati viene chiamata BSS (da
-  \textit{Block Started by Symbol}). La sua dimensione è fissa.
-  
-\item Lo \itindex{heap} \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 sez.~\ref{sec:proc_mem_alloc}), ma il suo limite inferiore,
-  quello adiacente al segmento dati, ha una posizione fissa.
+  che eseguono altri programmi.  
+
+  Quando l'architettura hardware lo supporta viene marcato in sola lettura per
+  evitare sovrascritture accidentali (o maliziose) che ne modifichino le
+  istruzioni.  Viene allocato da \func{execve} all'avvio del programma e resta
+  invariato per tutto il tempo dell'esecuzione.
+
+\item Il \index{segmento!dati} segmento dei dati o \textit{data
+    segment}. Contiene tutti i dati del programma, come le
+  \index{variabili!globali} variabili globali, cioè quelle definite al di
+  fuori di tutte le funzioni che compongono il programma, e le
+  \index{variabili!statiche} variabili statiche, cioè quelle dichiarate con
+  l'attributo \direct{static},\footnote{la direttiva \direct{static} indica al
+    compilatore C che una variabile così dichiarata all'interno di una
+    funzione deve essere mantenuta staticamente in memoria (nel
+    \index{segmento!dati} segmento dati appunto); questo significa che la
+    variabile verrà inizializzata una sola volta alla prima invocazione della
+    funzione e che il suo valore sarà mantenuto fra diverse esecuzioni della
+    funzione stessa, la differenza con una \index{variabili!globali} variabile
+    globale è che essa può essere vista solo all'interno della funzione in cui
+    è dichiarata.} e la memoria allocata dinamicamente. Di norma è diviso in
+  tre parti:
   
+  \begin{itemize*}
+  \item Il segmento dei dati inizializzati, che contiene le variabili il cui
+    valore è stato assegnato esplicitamente. Ad esempio se si definisce:
+    \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.
+  \item Il segmento dei dati non inizializzati, che contiene le variabili il
+    cui valore non è stato assegnato esplicitamente. Ad esempio se si
+    definisce:
+    \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 \val{NULL}).\footnote{si ricordi che questo vale solo per le
+      variabili che vanno nel \index{segmento!dati} segmento dati, e non è
+      affatto vero in generale.}  Storicamente questa seconda parte del
+    \index{segmento!dati} segmento dati viene chiamata BSS (da \textit{Block
+      Started by Symbol}). La sua dimensione è fissa.
+  \item Lo \itindex{heap} \textit{heap}, detto anche \textit{free
+      store}. Tecnicamente lo si può considerare l'estensione del segmento dei
+    dati non inizializzati, a cui di solito è posto giusto di seguito. Questo
+    è il segmento che viene utilizzato per l'allocazione dinamica della
+    memoria.  Lo \textit{heap} può essere ridimensionato allargandolo e
+    restringendolo per allocare e disallocare la memoria dinamica con le
+    apposite funzioni (vedi sez.~\ref{sec:proc_mem_alloc}), ma il suo limite
+    inferiore, quello adiacente al segmento dei dati non inizializzati, ha una
+    posizione fissa.
+  \end{itemize*}
+
 \item Il segmento di \itindex{stack} \textit{stack}, che contiene quello che
   viene chiamato \textit{stack} del programma.  Tutte le volte che si effettua
   una chiamata ad una funzione è qui che viene salvato l'indirizzo di ritorno
@@ -782,14 +802,14 @@ accedere.  Solitamente un programma C viene suddiviso nei seguenti segmenti:
   La dimensione di questo segmento aumenta seguendo la crescita dello
   \itindex{stack} \textit{stack} del programma, ma non viene ridotta quando
   quest'ultimo si restringe.
-\end{enumerate}
+\end{enumerate*}
 
 \begin{figure}[htb]
   \centering
 %  \includegraphics[height=12cm]{img/memory_layout}
   \begin{tikzpicture}
   \draw (0,0) rectangle (4,1);
-  \draw (2,0.5) node {text};
+  \draw (2,0.5) node {\textit{text}};
   \draw (0,1) rectangle (4,2.5);
   \draw (2,1.75) node {dati inizializzati};
   \draw (0,2.5) rectangle (4,5);
@@ -797,12 +817,12 @@ accedere.  Solitamente un programma C viene suddiviso nei seguenti segmenti:
   \draw (0,5) rectangle (4,9);
   \draw[dashed] (0,6) -- (4,6);
   \draw[dashed] (0,8) -- (4,8);
-  \draw (2,5.5) node {heap};
-  \draw (2,8.5) node {stack};
+  \draw (2,5.5) node {\textit{heap}};
+  \draw (2,8.5) node {\textit{stack}};
   \draw [->] (2,6) -- (2,6.5);
   \draw [->] (2,8) -- (2,7.5);
   \draw (0,9) rectangle (4,10);
-  \draw (2,9.5) node {environment};
+  \draw (2,9.5) node {\textit{environment}};
   \draw (4,0) node [anchor=west] {\texttt{0x08000000}};
   \draw (4,5) node [anchor=west] {\texttt{0x08xxxxxx}};
   \draw (4,9) node [anchor=west] {\texttt{0xC0000000}};
@@ -811,11 +831,18 @@ accedere.  Solitamente un programma C viene suddiviso nei seguenti segmenti:
   \label{fig:proc_mem_layout}
 \end{figure}
 
-Una disposizione tipica dei vari segmenti (testo, \itindex{heap}
-\textit{heap}, \itindex{stack} \textit{stack}, ecc.) è riportata in
-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
+Una disposizione tipica dei vari segmenti (testo, dati inizializzati e non
+inizializzati, \itindex{heap} \textit{heap}, \itindex{stack} \textit{stack},
+ecc.) è riportata in fig.~\ref{fig:proc_mem_layout}. Si noti come in figura
+sia indicata una ulteriore regione, marcata \textit{environment}, che è quella
+che contiene i dati relativi alle variabili di ambiente passate al programma
+al suo avvio (torneremo su questo argomento in sez.~\ref{sec:proc_environ}).
+
+Usando il comando \cmd{size} su un programma se ne può stampare le dimensioni
+dei \index{segmento!testo} segmenti di testo e \index{segmento!dati} di dati
+(solo però per i dati inizializzati ed il BSS, dato che lo \itindex{heap}
+\textit{heap} ha una dimensione dinamica). Si tenga presente comunque che il
+BSS, contrariamente al segmento dei dati inizializzati, non è mai salvato sul
 file che contiene l'eseguibile, dato che viene sempre inizializzato a zero al
 caricamento del programma.
 
@@ -827,18 +854,21 @@ Il C supporta direttamente, come linguaggio di programmazione, soltanto due
 modalità di allocazione della memoria: l'\textsl{allocazione statica} e
 l'\textsl{allocazione automatica}.
 
-L'\textsl{allocazione statica} è quella con cui sono memorizzate le variabili
-globali e le variabili statiche, cioè le variabili il cui valore deve essere
-mantenuto per tutta la durata del programma. Come accennato queste variabili
-vengono allocate nel \index{segmento!dati} segmento dei dati all'avvio del
-programma come parte delle operazioni svolte da \func{exec}, e lo spazio da
-loro occupato non viene liberato fino alla sua conclusione.
+L'\textsl{allocazione statica} è quella con cui sono memorizzate le
+\index{variabili!globali} variabili globali e le \index{variabili!statiche}
+variabili statiche, cioè le variabili il cui valore deve essere mantenuto per
+tutta la durata del programma. Come accennato queste variabili vengono
+allocate nel \index{segmento!dati} segmento dei dati all'avvio del programma
+come parte delle operazioni svolte da \func{exec}, e lo spazio da loro
+occupato non viene liberato fino alla sua conclusione.
 
 L'\textsl{allocazione automatica} è quella che avviene per gli argomenti di
-una funzione e per le sue variabili locali (le cosiddette \textsl{variabili
-  automatiche}), che esistono solo per la durata della funzione.  Lo spazio
-per queste variabili viene allocato nello \itindex{stack} \textit{stack} quando
-viene eseguita la funzione e liberato quando si esce dalla medesima.
+una funzione e per le sue variabili locali, quelle che vengono definite
+all'interno della funzione che esistono solo per la durata della sua esecuzione
+e che per questo vengono anche dette \index{variabili!automatiche}
+\textsl{variabili automatiche}.  Lo spazio per queste variabili viene allocato
+nello \itindex{stack} \textit{stack} quando viene eseguita la funzione e
+liberato quando si esce dalla medesima.
 
 Esiste però un terzo tipo di allocazione, l'\textsl{allocazione dinamica}
 della memoria, che non è prevista direttamente all'interno del linguaggio C,
@@ -846,10 +876,10 @@ ma che è necessaria quando il quantitativo di memoria che serve è
 determinabile solo durante il corso dell'esecuzione del programma. Il C non
 consente di usare variabili allocate dinamicamente, non è possibile cioè
 definire in fase di programmazione una variabile le cui dimensioni possano
-essere modificate durante l'esecuzione del programma. Per questo la Libreria
-Standard del C fornisce una serie opportuna di funzioni per eseguire
-l'allocazione dinamica di memoria (in genere nello \itindex{heap}
-\textit{heap}).
+essere modificate durante l'esecuzione del programma. Per questo la libreria
+standard del C fornisce una opportuna serie di funzioni per eseguire
+l'allocazione dinamica di memoria, che come accennato avviene nello
+\itindex{heap} \textit{heap}.
 
 Le variabili il cui contenuto è allocato in questo modo non potranno essere
 usate direttamente come le altre (quelle nello \itindex{stack}
@@ -859,7 +889,7 @@ funzioni di allocazione.
 
 Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
 quattro: \func{malloc}, \func{calloc}, \func{realloc} e \func{free}. Le prime
-due, \funcd{malloc} e \funcd{calloc} allocano in nuovo spazio di memoria; i
+due, \funcd{malloc} e \funcd{calloc} allocano nuovo spazio di memoria; i
 rispettivi prototipi sono:
 
 \begin{funcproto}{ 
@@ -884,8 +914,8 @@ un'area di memoria.\footnote{queste funzioni presentano un comportamento
 generico non è necessario effettuare un cast per assegnarli a puntatori al
 tipo di variabile per la quale si effettua l'allocazione, inoltre le funzioni
 garantiscono che i puntatori siano allineati 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.
+dati; ad esempio sulle macchine a 32 bit in genere sono allineati a multipli
+di 4 byte e sulle macchine a 64 bit a multipli di 8 byte.
 
 Nel caso di \func{calloc} l'area di memoria viene allocata nello \textit{heap}
 come un vettore di \param{nmemb} membri di \param{size} byte di dimensione, e
@@ -916,17 +946,17 @@ dei dati di gestione dell'allocazione, che può dar luogo a problemi gravi, ad
 esempio un \textit{segmentation fault} in una successiva chiamata di una di
 queste funzioni.
 
-Dato che questo errore, chiamato in gergo \textit{double free}, è abbastanza
-frequente specie quando si manipolano vettori di puntatori, e dato che le
-conseguenze possono essere pesanti ed inaspettate, si suggerisce come
-soluzione precauzionale di assegnare sempre a \val{NULL} ogni puntatore su cui
-sia stata eseguita \func{free} immediatamente dopo l'esecuzione della
-funzione. In questo modo, dato che quando l'argomento è un puntatore nullo
+Dato che questo errore, chiamato in gergo \itindex{double~free} \textit{double
+  free}, è abbastanza frequente, specie quando si manipolano vettori di
+puntatori, e dato che le conseguenze possono essere pesanti ed inaspettate, si
+suggerisce come soluzione precauzionale di assegnare sempre a \val{NULL} ogni
+puntatore su cui sia stata eseguita \func{free} immediatamente dopo
+l'esecuzione della funzione. In questo modo, dato che con un puntatore nullo
 \func{free} non esegue nessuna operazione, si evitano i problemi del
-\textit{double free}.
+\itindex{double~free} \textit{double free}.
 
-Infine la funzione \funcd{realloc} consente di modificare (in genere
-aumentare) la dimensione di un'area di memoria precedentemente allocata, il
+Infine la funzione \funcd{realloc} consente di modificare, in genere di
+aumentare, la dimensione di un'area di memoria precedentemente allocata; il
 suo prototipo è:
 
 \begin{funcproto}{ 
@@ -969,38 +999,47 @@ sez.~\ref{sec:proc_environ}), in particolare diventa possibile tracciare
 questo tipo di errori usando la 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 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}
-
-Il problema più comune e più difficile da risolvere che si incontra con le
-funzioni di allocazione è quando non viene opportunamente liberata la memoria
-non più utilizzata, quello che in inglese viene chiamato \itindex{memory~leak}
-\textit{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 impossibilità di proseguire l'esecuzione del programma).
+come quello dei \itindex{double~free} \textit{double~free} o i
+\itindex{buffer~overrun} \textit{buffer overrun} di un byte.\footnote{uno
+  degli errori più comuni, causato ad esempio dalla scrittura di una stringa
+  di dimensione pari a quella del buffer, in cui ci si dimentica dello zero di
+  terminazione finale.}  In particolare:
+\begin{itemize*}
+\item se la variabile è posta a $0$ gli errori vengono ignorati;
+\item se la variabile è posta a $1$ viene stampato un avviso sullo
+  \textit{standard error} (vedi sez.~\ref{sec:file_std_stream});
+\item se la variabile è posta a $2$ viene chiamata la funzione \func{abort}
+  (vedi sez.~\ref{sec:sig_alarm_abort}), che in genere causa l'immediata
+  terminazione del programma;
+\item se la variabile è posta a $3$ viene stampato l'avviso e chiamata
+  \func{abort}. 
+\end{itemize*}
+
+L'errore di programmazione più comune e più difficile da risolvere che si
+incontra con le funzioni di allocazione è quando non viene opportunamente
+liberata la memoria non più utilizzata, quello che in inglese viene chiamato
+\itindex{memory~leak} \textit{memory leak}, cioè una \textsl{perdita di
+  memoria}.
+
+Un caso tipico che illustra il problema è quello in cui in una propria
+funzione 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 funzione continueranno ad effettuare altre
+allocazioni, che si accumuleranno causando a lungo andare un esaurimento della
+memoria disponibile e la 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
+essere in una sezione del codice che non ha alcuna relazione con la funzione
 che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
 \itindex{memory~leak} \textit{memory leak}.
 
 In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
 programmazione ad oggetti, il problema dei \itindex{memory~leak}
-\textit{memory leak} è notevolmente ridimensionato attraverso l'uso accurato
-di appositi oggetti come gli \textit{smartpointers}.  Questo però in genere va
-a scapito delle prestazioni dell'applicazione in esecuzione.
+\textit{memory leak} si può notevolmente ridimensionare attraverso l'uso
+accurato di appositi oggetti come gli \textit{smartpointers}.  Questo però in
+genere va a scapito delle prestazioni dell'applicazione in esecuzione.
 
 % TODO decidere cosa fare di questo che segue
 % In altri linguaggi come il java e recentemente il C\# il problema non si pone
@@ -1024,7 +1063,7 @@ a scapito delle prestazioni dell'applicazione in esecuzione.
 % allocata da un oggetto.
 
 Per limitare l'impatto di questi problemi, e semplificare la ricerca di
-eventuali errori, l'implementazione delle funzioni di allocazione delle
+eventuali errori, l'implementazione delle funzioni di allocazione nella
 \acr{glibc} mette a disposizione una serie di funzionalità che permettono di
 tracciare le allocazioni e le disallocazioni, e definisce anche una serie di
 possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
@@ -1035,20 +1074,20 @@ ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
   \href{http://dmalloc.com/}{\textsf{http://dmalloc.com/}} di Gray Watson ed
   \textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche
 molto complesse riguardo l'allocazione della memoria. Vedremo alcune delle
-funzionalità di ausilio presenti nelle \acr{glibc} in
-sez.~\ref{sec:proc_memory_adv_management}. 
+funzionalità di ausilio presenti nella \acr{glibc} in
+sez.~\ref{sec:proc_memory_adv_management}.
 
 Una possibile alternativa all'uso di \func{malloc}, per evitare di soffrire
 dei problemi di \itindex{memory~leak} \textit{memory leak} descritti in
 precedenza, è di allocare la memoria nel segmento di \itindex{stack}
 \textit{stack} della funzione corrente invece che nello \itindex{heap}
-\textit{heap}, per farlo si può usare la funzione \funcd{alloca}, la cui
+\textit{heap}. Per farlo si può usare la funzione \funcd{alloca}, la cui
 sintassi è identica a quella di \func{malloc}; il suo prototipo è:
 
 \begin{funcproto}{ 
 \fhead{stdlib.h} 
 \fdecl{void *alloca(size\_t size)}
-\fdesc{Alloca un'area di memoria nello \textit{stack}} 
+\fdesc{Alloca un'area di memoria nello \textit{stack}.
 }
 {La funzione restituisce il puntatore alla zona di memoria allocata, in caso
   di fallimento il comportamento è indefinito.}
@@ -1057,34 +1096,32 @@ sintassi è identica a quella di \func{malloc}; il suo prototipo è:
 La funzione alloca la quantità di memoria (non inizializzata) richiesta
 dall'argomento \param{size} nel segmento di \itindex{stack} \textit{stack}
 della funzione chiamante.  Con questa funzione non è più necessario liberare
-la memoria allocata (e quindi non esiste un analogo della \func{free}) in
+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 alcuni vantaggi, anzitutto permette di
-evitare alla radice i problemi di \itindex{memory~leak} \textit{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
-pool di memoria da riservare e si evitano così anche i problemi di
-frammentazione di quest'ultimo, che comportano inefficienze sia
-nell'allocazione della memoria che nell'esecuzione dell'allocazione.
+Come è evidente questa funzione ha alcuni vantaggi interessanti, anzitutto
+permette di evitare alla radice i problemi di \itindex{memory~leak}
+\textit{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 pool di memoria da riservare e si
+evitano così anche i problemi di frammentazione di quest'ultimo, che
+comportano inefficienze sia nell'allocazione della memoria che nell'esecuzione
+dell'allocazione.
 
 Gli svantaggi sono che questa funzione non è disponibile su tutti gli Unix, e
 non è inserita né nello standard POSIX né in SUSv3 (ma è presente in BSD), il
 suo utilizzo quindi limita la portabilità dei programmi. Inoltre la funzione
 non può essere usata nella lista degli argomenti di una funzione, perché lo
-spazio verrebbe allocato nel mezzo degli stessi.
-
-Inoltre non è chiaramente possibile usare \func{alloca} per allocare memoria
-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 sez.~\ref{sec:proc_auto_var}.
+spazio verrebbe allocato nel mezzo degli stessi.  Inoltre non è chiaramente
+possibile usare \func{alloca} per allocare memoria 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 \index{variabili!automatiche} variabili
+automatiche, su cui torneremo in sez.~\ref{sec:proc_var_passing}.
 
 Infine non esiste un modo di sapere se l'allocazione ha avuto successo, la
 funzione infatti viene realizzata inserendo del codice \textit{inline} nel
@@ -1101,55 +1138,68 @@ disponibile.
 Le due funzioni seguenti\footnote{le due funzioni sono state definite con BSD
   4.3, sono marcate obsolete in SUSv2 e non fanno parte delle librerie
   standard del C e mentre sono state esplicitamente rimosse dallo standard
-  POSIX/1-2001.} vengono utilizzate soltanto quando è necessario effettuare
+  POSIX.1-2001.} 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
-funzioni di allocazione della memoria. Per poterle utilizzare è necessario
-definire una della macro di funzionalità (vedi
-sez.~\ref{sec:intro_gcc_glibc_std}) fra \macro{\_BSD\_SOURCE},
-\macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un valore maggiore o
-uguale di 500). 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.
-  
-  \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}
-
-La funzione è un'interfaccia all'omonima system call ed imposta l'indirizzo
-finale del \index{segmento!dati} 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.
-
-Il valore di ritorno della funzione fa riferimento alla versione fornita dalle
+processo, per poterle utilizzare è necessario definire una della macro di
+funzionalità (vedi sez.~\ref{sec:intro_gcc_glibc_std}) fra
+\macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un
+valore maggiore o uguale di 500). La prima funzione è \funcd{brk}, ed il suo
+prototipo è:
+
+\begin{funcproto}{ 
+\fhead{unistd.h} 
+\fdecl{int brk(void *addr)}
+\fdesc{Sposta la fine del segmento dati del processo.} 
+}
+{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{funcproto}
+
+La funzione è un'interfaccia all'omonima \textit{system call} ed imposta
+l'indirizzo finale del \index{segmento!dati} segmento dati di un processo (più
+precisamente dello \itindex{heap} \textit{heap}) all'indirizzo specificato
+da \param{addr}. Quest'ultimo deve essere un valore ragionevole, e la
+dimensione totale non deve comunque eccedere un eventuale limite (vedi
+sez.~\ref{sec:sys_resource_limit}) imposto sulle dimensioni massime del
+\index{segmento!dati} segmento dati del processo.
+
+Il valore di ritorno della funzione fa riferimento alla versione fornita dalla
 \acr{glibc}, in realtà in Linux la \textit{system call} corrispondente
 restituisce come valore di ritorno il nuovo valore della fine del
 \index{segmento!dati} segmento dati in caso di successo e quello corrente in
-caso di fallimento, è la funzione di interfaccia usata dalle \acr{glibc} che
-fornisce i valori di ritorno appena descritti, questo può non accadere se si
-usano librerie diverse.
+caso di fallimento, è la funzione di interfaccia usata dalla \acr{glibc} che
+fornisce i valori di ritorno appena descritti; se si usano librerie diverse
+questo potrebbe non accadere.
 
 Una seconda funzione per la manipolazione diretta delle dimensioni
 \index{segmento!dati} 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.
-  
-  \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
-\index{segmento!dati} segmento dati.
+  soltanto di una funzione di libreria, anche se basata sulla stessa
+  \textit{system call}.} è \funcd{sbrk}, ed il suo prototipo è:
 
-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. 
+\begin{funcproto}{ 
+\fhead{unistd.h} 
+\fdecl{void *sbrk(intptr\_t increment)}
+\fdesc{Incrementa la dimensione del segmento dati del processo.} 
+}
+{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{funcproto}
+
+La funzione incrementa la dimensione dello \itindex{heap} \textit{heap} di un
+programma del valore indicato dall'argomento \param{increment}, restituendo il
+nuovo indirizzo finale dello stesso.  L'argomento è definito come di tipo
+\type{intptr\_t}, ma a seconda della versione delle librerie e del sistema può
+essere indicato con una serie di tipi equivalenti come \type{ptrdiff\_t},
+\type{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzone
+permette di ottenere l'attuale posizione della fine del \index{segmento!dati}
+segmento dati.
+
+Queste due funzioni sono state deliberatamente escluse dallo standard POSIX.1
+dato che per i normali programmi è sempre opportuno usare le funzioni di
+allocazione standard descritte in precedenza, a meno di non voler realizzare
+per proprio conto un diverso meccanismo di gestione della memoria del segmento
+dati.
 
 
 \subsection{Il controllo della memoria virtuale}  
@@ -1159,15 +1209,15 @@ standard descritte in precedenza, che sono costruite su di esse.
 
 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.
+dalla memoria per metterle nell'area di \textit{swap}, sulla base
+dell'utilizzo corrente da parte dei vari processi.
 
 Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
 meccanismo della \index{paginazione} paginazione riporta in RAM, ed in maniera
 trasparente, tutte le pagine che gli occorrono; esistono però esigenze
 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}
+\begin{itemize*}
 \item \textsl{La velocità}. Il processo della \index{paginazione} paginazione
   è trasparente solo se il programma in esecuzione non è sensibile al tempo
   che occorre a riportare la pagina in memoria; per questo motivo processi
@@ -1187,11 +1237,11 @@ motivi per cui si possono avere di queste necessità sono due:
   in memoria queste possono essere portate su disco dal meccanismo della
   \index{paginazione} 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}
+  cancellazione: un processo infatti 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*}
 
 Per ottenere informazioni sulle modalità in cui un programma sta usando la
 memoria virtuale è disponibile una apposita funzione, \funcd{mincore}, che
@@ -1207,7 +1257,7 @@ il suo prototipo è:
 %   Ritorna lo stato delle pagine di memoria occupate da un processo.
   
 %   \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
-%     errore, nel qual caso \var{errno} assumerà uno dei valori seguenti:
+%     errore, nel qual caso \var{errno} assumerà uno dei valori:
 %   \begin{errlist}
 %   \item[\errcode{ENOMEM}] o \param{addr} + \param{length} eccede la dimensione
 %     della memoria usata dal processo o l'intervallo di indirizzi specificato
@@ -1228,7 +1278,7 @@ il suo prototipo è:
 \fdesc{Ritorna lo stato delle pagine di memoria occupate da un processo.}
 }
 {La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, nel qual
-caso \var{errno} assumerà uno dei valori seguenti:
+caso \var{errno} assumerà uno dei valori:
 \begin{errlist}
    \item[\errcode{ENOMEM}] o \param{addr} + \param{length} eccede la dimensione
      della memoria usata dal processo o l'intervallo di indirizzi specificato
@@ -1243,8 +1293,8 @@ caso \var{errno} assumerà uno dei valori seguenti:
 
 La funzione permette di ottenere le informazioni sullo stato della mappatura
 della memoria per il processo chiamante, specificando l'intervallo da
-esaminare con l'indirizzo iniziale (indicato con l'argomento \param{addr}) e
-la lunghezza (indicata con l'argomento \param{length}). L'indirizzo iniziale
+esaminare con l'indirizzo iniziale, indicato con l'argomento \param{addr}, e
+la lunghezza, indicata con l'argomento \param{length}. L'indirizzo iniziale
 deve essere un multiplo delle dimensioni di una pagina, mentre la lunghezza
 può essere qualunque, fintanto che si resta nello spazio di indirizzi del
 processo,\footnote{in caso contrario si avrà un errore di \errcode{ENOMEM};
@@ -1258,15 +1308,15 @@ l'intervallo compreso fino al multiplo successivo.
 I risultati della funzione vengono forniti nel vettore puntato da \param{vec},
 che deve essere allocato preventivamente e deve essere di dimensione
 sufficiente a contenere tanti byte quante sono le pagine contenute
-nell'intervallo di indirizzi specificato.\footnote{la dimensione cioè deve
-  essere almeno pari a \code{(length+PAGE\_SIZE-1)/PAGE\_SIZE}. } Al ritorno
-della funzione il bit meno significativo di ciascun byte del vettore sarà
-acceso se la pagina di memoria corrispondente è al momento residente in
-memoria, o cancellato altrimenti. Il comportamento sugli altri bit è
-indefinito, essendo questi al momento riservati per usi futuri. Per questo
-motivo in genere è comunque opportuno inizializzare a zero il contenuto del
-vettore, così che le pagine attualmente residenti in memoria saranno indicata
-da un valore non nullo del byte corrispondente.
+nell'intervallo di indirizzi specificato, la dimensione cioè deve essere
+almeno pari a \code{(length+PAGE\_SIZE-1)/PAGE\_SIZE}.  Al ritorno della
+funzione il bit meno significativo di ciascun byte del vettore sarà acceso se
+la pagina di memoria corrispondente è al momento residente in memoria, o
+cancellato altrimenti. Il comportamento sugli altri bit è indefinito, essendo
+questi al momento riservati per usi futuri. Per questo motivo in genere è
+comunque opportuno inizializzare a zero il contenuto del vettore, così che le
+pagine attualmente residenti in memoria saranno indicata da un valore non
+nullo del byte corrispondente.
 
 Dato che lo stato della memoria di un processo può cambiare continuamente, il
 risultato di \func{mincore} è assolutamente provvisorio e lo stato delle
@@ -1289,30 +1339,28 @@ 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}.  Infine i \textit{memory lock} non sono
-ereditati dai processi figli,\footnote{ma siccome Linux usa il
-  \itindex{copy~on~write} \textit{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 \textit{memory lock} del padre.} e
-vengono automaticamente rimossi se si pone in esecuzione un altro programma
-con \func{exec} (vedi sez.~\ref{sec:proc_exec}).
-
-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 fino al kernel 2.6.9 solo un processo con i
-privilegi opportuni (la \itindex{capabilities} \textit{capability}
-\const{CAP\_IPC\_LOCK}, vedi sez.~\ref{sec:proc_capabilities}) aveva la
-capacità di bloccare una pagina.
+tutti i suoi \textit{memory lock}.  Inoltre i \textit{memory lock} non sono
+ereditati dai processi figli, ma siccome Linux usa il \itindex{copy~on~write}
+\textit{copy on write} (vedi sez.~\ref{sec:proc_fork}) gli indirizzi virtuali
+del figlio sono mantenuti sullo stesso segmento di RAM del padre, e quindi
+fintanto che un figlio non scrive su un segmento bloccato, può usufruire del
+\textit{memory lock} del padre. Infine i \textit{memory lock} vengono
+automaticamente rimossi se si pone in esecuzione un altro programma con
+\func{exec} (vedi sez.~\ref{sec:proc_exec}).
 
 Il sistema pone dei limiti all'ammontare di memoria di un processo che può
 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}. Inoltre in alcuni sistemi è definita la costante
-\const{PAGE\_SIZE} in \file{limits.h} per indicare la dimensione di una pagina
-in byte.\footnote{con Linux questo non avviene e si deve ricorrere alla
-  funzione \func{getpagesize}, vedi sez.~\ref{sec:sys_memory_res}.} 
+\textit{memory locking}.
+
+Siccome la richiesta di un \textit{memory lock} da parte di un processo riduce
+la memoria fisica disponibile nel sistema per gli altri processi, questo ha un
+evidente impatto su tutti gli altri processi, per cui fino al kernel 2.6.9
+solo un processo dotato di privilegi amministrativi (la \itindex{capabilities}
+\textit{capability} \const{CAP\_IPC\_LOCK}, vedi
+sez.~\ref{sec:proc_capabilities}) aveva la capacità di bloccare una pagina di
+memoria.
 
 A partire dal kernel 2.6.9 anche un processo normale può bloccare la propria
 memoria\footnote{la funzionalità è stata introdotta per non essere costretti a
@@ -1326,8 +1374,8 @@ però diversi processi bloccano la stessa pagina questa resterà bloccata
 fintanto che ci sarà almeno un processo che la blocca.
 
 Le funzioni per bloccare e sbloccare la \index{paginazione} paginazione di
-singole sezioni di memoria sono \funcd{mlock} e \funcd{munlock}; i loro
-prototipi sono:
+singole sezioni di memoria sono rispettivamente \funcd{mlock} e
+\funcd{munlock}; i loro prototipi sono:
 % \begin{functions}
 %   \headdecl{sys/mman.h} 
 
@@ -1339,7 +1387,7 @@ prototipi sono:
   
 %   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in
 %     caso di errore, nel qual caso \var{errno} assumerà uno dei
-%     valori seguenti:
+%     valori:
 %   \begin{errlist}
 %   \item[\errcode{ENOMEM}] alcuni indirizzi dell'intervallo specificato non
 %     corrispondono allo spazio di indirizzi del processo o si è ecceduto
@@ -1360,66 +1408,77 @@ prototipi sono:
   \fdecl{int munlock(const void *addr, size\_t len)}
   \fdesc{Rimuove il blocco della paginazione su un intervallo di memoria.}
   }
-{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ in
-    caso di errore, nel qual caso \var{errno} assumerà uno dei
-    valori seguenti:
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ in caso di
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \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[\errcode{ENOMEM}] alcuni indirizzi dell’intervallo specificato non
+    corrispondono allo spazio di indirizzi del processo o si è superato il
+    limite di \const{RLIMIT\_MEMLOCK} per un processo non privilegiato (solo
+    per kernel a partire dal 2.6.9). 
   \item[\errcode{EINVAL}] \param{len} non è un valore positivo.
-  \item[\errcode{EPERM}] con un kernel successivo al 2.6.9 il processo non è
-    privilegiato e si un limite nullo per \const{RLIMIT\_MEMLOCK}.
-  \end{errlist}
-  e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i
-  privilegi richiesti per l'operazione.}
+  \item[\errcode{EPERM}] il processo non è privilegiato (per kernel precedenti
+    il 2.6.9) o si ha un limite nullo per \const{RLIMIT\_MEMLOCK} e
+    il processo non è privilegiato (per kernel a partire dal 2.6.9).
+  \end{errlist}}
 \end{funcproto}
 
-
 Le due funzioni permettono rispettivamente di bloccare e sbloccare la
-\index{paginazione} 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.\footnote{con altri kernel si
-  può ottenere un errore di \errcode{EINVAL} se \param{addr} non è un multiplo
-  della dimensione delle pagine di memoria.}
+\index{paginazione} paginazione per l'intervallo di memoria iniziante
+all'indirizzo \param{addr} e lungo \param{len} byte.  Tutte le pagine che
+contengono una parte dell'intervallo bloccato sono mantenute in RAM per tutta
+la durata del blocco. Con kernel diversi da Linux si può ottenere un errore di
+\errcode{EINVAL} se \param{addr} non è un multiplo della dimensione delle
+pagine di memoria, pertanto se si ha a cuore la portabilità si deve avere cura
+di allinearne correttamente il valore.
 
 Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono di
 bloccare genericamente la \index{paginazione} paginazione per l'intero spazio
 di indirizzi di un processo.  I prototipi di queste funzioni sono:
-\begin{functions}
-  \headdecl{sys/mman.h} 
 
-  \funcdecl{int mlockall(int flags)}
-  Blocca la paginazione per lo spazio di indirizzi del processo corrente. 
-  
-  \funcdecl{int munlockall(void)}
-  Sblocca la paginazione per lo spazio di indirizzi del processo corrente. 
-  
-  \bodydesc{Codici di ritorno ed errori sono gli stessi di \func{mlock} e
-    \func{munlock}, con un kernel successivo al 2.6.9 l'uso di
-    \func{munlockall} senza la \itindex{capabilities} \textit{capability}
-\const{CAP\_IPC\_LOCK} genera un errore di \errcode{EPERM}.}
-\end{functions}
+\begin{funcproto}{ 
+\fhead{sys/mman.h} 
+\fdecl{int mlockall(int flags)}
+\fdesc{Blocca la paginazione per lo spazio di indirizzi del processo corrente.} 
+\fdecl{int munlockall(void)}
+\fdesc{Sblocca la paginazione per lo spazio di indirizzi del processo corrente.}
+}
+{Codici di ritorno ed errori sono gli stessi di \func{mlock} e \func{munlock},
+  tranne per \errcode{EINVAL} che viene restituito solo se si è specificato
+  con \func{mlockall} un valore sconosciuto per \param{flags}.}
+\end{funcproto}
 
 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[\const{MCL\_CURRENT}] blocca tutte le pagine correntemente mappate nello
-  spazio di indirizzi del processo.
-\item[\const{MCL\_FUTURE}] blocca tutte le pagine che verranno mappate nello
-  spazio di indirizzi del processo.
-\end{basedescript}
+comportamento; esso deve essere specificato come maschera binaria dei valori
+espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{MCL\_CURRENT}& blocca tutte le pagine correntemente mappate nello
+                          spazio di indirizzi del processo.\\
+    \const{MCL\_FUTURE} & blocca tutte le pagine che verranno mappate nello
+                          spazio di indirizzi del processo.\\
+   \hline
+  \end{tabular}
+  \caption{Valori e significato dell'argomento \param{flags} della funzione
+    \func{mlockall}.}
+  \label{tab:mlockall_flags}
+\end{table}
 
 Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
 di indirizzi del processo, sia che comprendano il \index{segmento!dati}
 \index{segmento!testo} segmento di testo, di dati, lo \itindex{stack}
 \textit{stack}, lo \itindex{heap} \textit{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.
+la memoria condivisa.  L'uso dell'argomento \param{flags} permette di
+selezionare con maggior finezza le pagine da bloccare, ad esempio usando
+\const{MCL\_FUTURE} ci si può limitare a tutte le pagine allocate a partire
+dalla chiamata della funzione.
 
 In ogni caso un processo real-time che deve entrare in una
 \index{sezione~critica} sezione critica deve provvedere a riservare memoria
@@ -1432,10 +1491,10 @@ ancora stata riportata in RAM si potrebbe avere un \itindex{page~fault}
 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
-che esse vengano mappate in RAM dallo \itindex{stack} \textit{stack}, dopo di
-che, per essere sicuri che esse siano state effettivamente portate in memoria,
-ci si scrive sopra.
+allocato una quantità sufficientemente ampia di \index{variabili!automatiche}
+variabili automatiche, in modo che esse vengano mappate in RAM dallo
+\itindex{stack} \textit{stack}, dopo di che, per essere sicuri che esse siano
+state effettivamente portate in memoria, ci si scrive sopra.
 
 \itindend{memory~locking}
 
@@ -1466,34 +1525,34 @@ funzione specifica.
 Tradizionalmente per rispondere a questa esigenza sono state create due
 funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
 rispettivi prototipi sono:
-\begin{functions}
-  \headdecl{malloc.h} 
-
-  \funcdecl{void *valloc(size\_t size)} Alloca un blocco di memoria allineato
-  alla dimensione di una pagina di memoria.
 
-  \funcdecl{void *memalign(size\_t boundary, size\_t size)}
-  Alloca un blocco di memoria allineato ad un multiplo di \param{boundary}.
-  
-  \bodydesc{Entrambe le funzioni ritornano un puntatore al blocco di memoria
-    allocato in caso di successo e \val{NULL} in caso di errore, nel qual
-    caso \var{errno} assumerà uno dei valori seguenti:
+\begin{funcproto}{ 
+\fhead{malloc.h} 
+\fdecl{void *valloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+  memoria.}  
+\fdecl{void *memalign(size\_t boundary, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+  di \param{boundary}.} 
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+  caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+  assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
-  \item[\errcode{EINVAL}] \param{boundary} non è multiplo di due.
-  \end{errlist}
-}
-\end{functions}
+  \item[\errcode{EINVAL}] \param{boundary} non è una potenza di due.
+  \end{errlist}}
+\end{funcproto}
 
-Le funzioni restituiscono il puntatore al buffer di memoria allocata, che per
-\func{memalign} sarà un multiplo di \param{boundary} mentre per \func{valloc}
-un multiplo della dimensione di una pagina di memoria. Nel caso della versione
-fornita dalle \acr{glibc} la memoria allocata con queste funzioni deve essere
-liberata con \func{free}, cosa che non è detto accada con altre
-implementazioni.
+Le funzioni restituiscono il puntatore al buffer di memoria allocata di
+dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo
+di \param{boundary} mentre per \func{valloc} un multiplo della dimensione di
+una pagina di memoria. Nel caso della versione fornita dalla \acr{glibc} la
+memoria allocata con queste funzioni deve essere liberata con \func{free},
+cosa che non è detto accada con altre implementazioni.
 
-Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due
-compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne
+Nessuna delle due funzioni ha una chiara standardizzazione nessuna delle due
+compare in POSIX.1, inoltre ci sono indicazioni discordi sui file che ne
 contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
   \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e
   \acr{libc5} la dichiarano in \texttt{malloc.h}, lo stesso vale per
@@ -1501,82 +1560,82 @@ contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
 per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
 nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
 prototipo è:
-\begin{prototype}{stdlib.h}{posix\_memalign(void **memptr, size\_t alignment,
-    size\_t size) } 
-  Alloca un buffer di memoria allineato ad un multiplo di \param{alignment}.
-  
-  \bodydesc{La funzione restituisce 0 in caso di successo e \val{NULL} in caso
-    di fallimento, o uno dei due codici di errore \errcode{ENOMEM} o
-    \errcode{EINVAL}; \var{errno} non viene impostata.}
-\end{prototype}
-
-La funzione restituisce il puntatore al buffer allocato all'indirizzo indicato
-da \param{memptr}. La funzione fallisce nelle stesse condizioni delle due
-funzioni precedenti, ma a differenza di \func{memalign} restituisce un codice
-di errore \errcode{EINVAL} anche se \param{alignment} non è un multiplo della
-la dimensione di \code{sizeof(void *)}. Come per le precedenti la memoria
-allocata con \func{posix\_memalign} può essere disallocata con
-\func{free}.\footnote{che in questo caso è quanto richiesto dallo standard.}
+
+\begin{funcproto}{ 
+\fhead{stdlib.h} 
+\fdecl{posix\_memalign(void **memptr, size\_t alignment, size\_t size)}
+\fdesc{Alloca un buffer di memoria allineato ad un multiplo
+  di \param{alignment}.}   
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+  caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+  assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+  \item[\errcode{EINVAL}] \param{alignment} non è potenza di due e multiplo
+    di \code{sizeof(void *)}.
+  \end{errlist}}
+\end{funcproto}
+
+La funzione restituisce il puntatore al buffer allocato di dimensioni pari
+a \param{size} nella variabile (di tipo \texttt{void *}) posta all'indirizzo
+indicato da \param{memptr}. La funzione fallisce nelle stesse condizioni delle
+due funzioni precedenti, ma a loro differenza restituisce direttamente come
+valore di ritorno il codice di errore.  Come per le precedenti la memoria
+allocata con \func{posix\_memalign} deve essere disallocata con \func{free},
+che in questo caso però è quanto richiesto dallo standard.  Si tenga presente
+infine che nessuna di queste funzioni inizializza il buffer di memoria
+allocato, il loro comportamento cioè è analogo, allineamento a parte, a quello
+di \func{malloc}.
 
 Un secondo caso in cui risulta estremamente utile poter avere un maggior
 controllo delle modalità di allocazione della memoria è quello in cui cercano
-errori di programmazione. Esempi di questi errori sono chiamate doppie alla
-funzione \func{free} con lo stesso puntatore, o i cosiddetti
-\itindex{buffer~overrun} \textit{buffer overrun}, cioè le scritture su un buffer
-oltre le dimensioni della sua allocazione,\footnote{entrambe queste operazioni
-  causano in genere la corruzione dei dati di controllo delle funzioni di
-  allocazione, che vengono anch'essi mantenuti nello \itindex{heap}
-  \textit{heap} per tenere traccia delle zone di memoria allocata.} o i
-classici \itindex{memory~leak} \textit{memory leak}.
-
-Una prima funzionalità di ausilio nella ricerca di questi errori viene fornita
-dalla \acr{glibc} tramite l'uso della variabile di ambiente
-\var{MALLOC\_CHECK\_}. Quando questa viene definita al posto della versione
-ordinaria delle funzioni di allocazione (\func{malloc}, \func{calloc},
-\func{realloc}, e \func{free}) viene usata una versione meno efficiente ma in
-grado di rilevare (e tollerare) alcuni degli errori più semplici, come le
-doppie chiamate a \func{free} o i \itindex{buffer~overrun} \textit{buffer
-  overrun} di un byte.\footnote{uno degli errori più comuni, causato ad
-  esempio dalla scrittura di una stringa di dimensione pari a quella del
-  buffer, in cui ci si dimentica dello zero di terminazione finale.}
-
-In questo caso a seconda del valore assegnato a \var{MALLOC\_CHECK\_} si
-avranno diversi comportamenti: con 0 l'errore sarà ignorato, con 1 verrà
-stampato un messaggio sullo \textit{standard error} (vedi
-sez.~\ref{sec:file_std_stream}), con 2 verrà invocata la funzione \func{abort}
-(vedi sez.~\ref{sec:sig_alarm_abort}) che termina il programma, con 3 viene
-sia stampato il messaggio d'errore che abortito il programma. In genere è
-opportuno definire la variabile ad un valore diverso da zero che consente di
-rilevare un errore nel momento in cui avviene.
-
-Una modalità alternativa per effettuare dei controlli di consistenza sullo
-stato delle allocazioni di memoria eseguite con \func{malloc}, anche questa
-fornita come estensione specifica (e non standard) delle \acr{glibc}, è quella
-di utilizzare la funzione \funcd{mcheck}, che deve essere chiamata prima di
-eseguire qualunque allocazione con \func{malloc}; il suo prototipo è:
-\begin{prototype}{mcheck.h}{mcheck(void (*abortfn) (enum mcheck\_status
-    status))} 
-  Attiva i controlli di consistenza delle allocazioni eseguite da \func{malloc}.
-  
-  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
-    fallimento; \var{errno} non viene impostata.}
-\end{prototype}
-
-La funzione consente di registrare una funzione di emergenza, da passare come
-argomento, che verrà eseguita tutte le volte che, in una successiva esecuzione
-di \func{malloc}, venissero trovate delle inconsistenze, come delle operazioni
-di scrittura oltre i limiti dei buffer allocati. Per questo motivo la funzione
-deve essere chiamata prima di qualunque allocazione di memoria, altrimenti
-fallirà con un valore di ritorno pari a $-1$.
-
-Se come argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata una
-funzione predefinita che stampa un messaggio di errore ed invoca la funzione
-\func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si dovrà create
-una funzione personalizzata che verrà eseguita ricevendo un unico argomento di
-tipo \type{mcheck\_status},\footnote{trattasi in sostanza di un codice di
-  errore che la funzione di emergenza potrà utilizzare per prendere le
-  opportune azioni.} un tipo enumerato che può assumere soltanto i valori di
-tab.~\ref{tab:mcheck_status_value}.
+errori di programmazione. Esempi di questi errori sono i \itindex{double~free}
+\textit{double free}, o i cosiddetti \itindex{buffer~overrun} \textit{buffer
+  overrun}, cioè le scritture su un buffer oltre le dimensioni della sua
+allocazione,\footnote{entrambe queste operazioni causano in genere la
+  corruzione dei dati di controllo delle funzioni di allocazione, che vengono
+  anch'essi mantenuti nello \itindex{heap} \textit{heap} per tenere traccia
+  delle zone di memoria allocata.} o i classici \itindex{memory~leak}
+\textit{memory leak}.
+
+Abbiamo visto in sez.~\ref{sec:proc_mem_lock} come una prima funzionalità di
+ausilio nella ricerca di questi errori sia l'uso della variabile di ambiente
+\var{MALLOC\_CHECK\_}.  Una modalità alternativa per effettuare dei controlli
+di consistenza sullo stato delle allocazioni di memoria eseguite con
+\func{malloc}, anche questa fornita come estensione specifica (e non standard)
+della \acr{glibc}, è quella di utilizzare la funzione \funcd{mcheck}, che deve
+essere chiamata prima di eseguire qualunque allocazione con \func{malloc}; il
+suo prototipo è:
+
+\begin{funcproto}{ 
+\fhead{mcheck.h} 
+\fdecl{int mcheck(void (*abortfn) (enum mcheck\_status status))}
+\fdesc{Attiva i controlli di consistenza delle allocazioni di memoria.}   
+}
+{La funzione restituisce $0$ in caso di successo e $-1$ in caso di fallimento;
+  \var{errno} non viene impostata.} 
+\end{funcproto}
+
+La funzione consente di registrare una funzione di emergenza che verrà
+eseguita tutte le volte che, in una successiva esecuzione di \func{malloc},
+venissero trovate delle inconsistenze, come delle operazioni di scrittura
+oltre i limiti dei buffer allocati. Per questo motivo la funzione deve essere
+chiamata prima di qualunque allocazione di memoria, altrimenti fallirà.
+
+Se come primo argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata
+una funzione predefinita che stampa un messaggio di errore ed invoca la
+funzione \func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si
+dovrà creare una funzione personalizzata in grado di ricevere il tipo di
+errore ed agire di conseguenza.
+
+Nonostante la scarsa leggibilità del prototipo si tratta semplicemente di
+definire una funzione di tipo \code{void abortfn(enum mcheck\_status status)},
+che non deve restituire nulla e che deve avere un unico argomento di tipo
+\type{mcheck\_status}. In caso di errore la funzione verrà eseguita ricevendo
+un opportuno valore di \param{status} che è un tipo enumerato che può assumere
+soltanto i valori di tab.~\ref{tab:mcheck_status_value} che indicano la
+tipologia di errore riscontrata.
 
 \begin{table}[htb]
   \centering
@@ -1586,9 +1645,9 @@ tab.~\ref{tab:mcheck_status_value}.
     \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \macro{MCHECK\_OK}      & riportato (a \func{mprobe}) se nessuna
+    \macro{MCHECK\_OK}      & riportato a \func{mprobe} se nessuna
                               inconsistenza è presente.\\
-    \macro{MCHECK\_DISABLED}& riportato (a \func{mprobe}) se si è chiamata
+    \macro{MCHECK\_DISABLED}& riportato a \func{mprobe} se si è chiamata
                               \func{mcheck} dopo aver già usato
                               \func{malloc}.\\
     \macro{MCHECK\_HEAD}    & i dati immediatamente precedenti il buffer sono
@@ -1608,22 +1667,25 @@ tab.~\ref{tab:mcheck_status_value}.
 \end{table}
 
 Una volta che si sia chiamata \func{mcheck} con successo si può anche
-controllare esplicitamente lo stato delle allocazioni (senza aspettare un
-errore nelle relative funzioni) utilizzando la funzione \funcd{mprobe}, il cui
+controllare esplicitamente lo stato delle allocazioni senza aspettare un
+errore nelle relative funzioni utilizzando la funzione \funcd{mprobe}, il cui
 prototipo è:
-\begin{prototype}{mcheck.h}{enum mcheck\_status mprobe(ptr)} 
-  Esegue un controllo di consistenza delle allocazioni.
-  
-  \bodydesc{La funzione restituisce un codice fra quelli riportati in
-    tab.\ref{tab:mcheck_status_value}.}
-\end{prototype}
+
+\begin{funcproto}{ 
+\fhead{mcheck.h} 
+\fdecl{enum mcheck\_status mprobe(ptr)}
+\fdesc{Esegue un controllo di consistenza delle allocazioni.}   
+}
+{La funzione restituisce un codice fra quelli riportati in
+   tab.\ref{tab:mcheck_status_value} e non ha errori.} 
+\end{funcproto}
 
 La funzione richiede che si passi come argomento un puntatore ad un blocco di
 memoria precedentemente allocato con \func{malloc} o \func{realloc}, e
 restituisce lo stesso codice di errore che si avrebbe per la funzione di
 emergenza ad una successiva chiamata di una funzione di allocazione, e poi i
 primi due codici che indicano rispettivamente quando tutto è a posto o il
-controllo non è possibile per non aver chiamato \func{mcheck} in tempo. 
+controllo non è possibile per non aver chiamato \func{mcheck} in tempo.
 
 % TODO: trattare le altre funzionalità avanzate di \func{malloc}, mallopt,
 % mtrace, muntrace, mallinfo e gli hook con le glibc 2.10 c'è pure malloc_info
@@ -1633,7 +1695,6 @@ controllo non è possibile per non aver chiamato \func{mcheck} in tempo.
 \section{Argomenti, ambiente ed altre proprietà di un processo}
 \label{sec:proc_options}
 
-
 In questa sezione esamineremo le funzioni che permettono di gestire gli
 argomenti e le opzioni, e quelle che consentono di manipolare ed utilizzare le
 variabili di ambiente. Accenneremo infine alle modalità con cui si può gestire
@@ -1645,20 +1706,25 @@ operazioni.
 \label{sec:proc_par_format}
 
 Tutti i programmi hanno la possibilità di ricevere argomenti e opzioni quando
-vengono lanciati. Il passaggio degli argomenti e delle opzioni è effettuato
-attraverso gli 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
-sez.~\ref{sec:proc_exec}) quando questo viene messo in esecuzione.
-
-In genere il passaggio di argomenti ed opzioni ad un programma viene
-effettuato dalla shell, che si incarica di leggere la linea di comando e di
-effettuarne la scansione (il cosiddetto \textit{parsing}) per individuare le
-parole che la compongono, ciascuna delle quali potrà essere considerata un
-argomento o un'opzione. Di norma per individuare le parole che andranno a
-costituire la lista degli argomenti viene usato come carattere di separazione
-lo spazio o il tabulatore, ma la cosa dipende ovviamente dalle modalità con
-cui si effettua la scansione.
+vengono lanciati e come accennato in sez.~\ref{sec:proc_main} questo viene
+effettuato attraverso gli argomenti \param{argc} e \param{argv} ricevuti nella
+funzione \func{main} all'avvio del programma. Questi argomenti vengono passati
+al programma dalla shell o dal processo che esegue la \func{exec} (secondo le
+modalità che vedremo in sez.~\ref{sec:proc_exec}) quando questo viene messo in
+esecuzione.
+
+Nel caso più comune il passaggio di argomenti ed opzioni viene effettuato
+dalla shell, che si incarica di leggere la linea di comando con cui si lancia
+il programma e di effettuarne la scansione (il cosiddetto \textit{parsing})
+per individuare le parole che la compongono, ciascuna delle quali potrà essere
+considerata un argomento o un'opzione. 
+
+Di norma per individuare le parole che andranno a costituire la lista degli
+argomenti viene usato come carattere di separazione lo spazio o il tabulatore,
+ma la cosa dipende ovviamente dalle modalità con cui si effettua la scansione
+e dalle convenzioni adottate dal programma che la esegue: ad esempio la shell
+consente di proteggere con opportuni caratteri di controllo argomenti che
+contengono degli spazi evitando di spezzarli in parole diverse.
 
 \begin{figure}[htb]
   \centering
@@ -1695,13 +1761,15 @@ cui si effettua la scansione.
   \label{fig:proc_argv_argc}
 \end{figure}
 
-Indipendentemente da come viene eseguita, il risultato della scansione deve
-essere la costruzione del vettore di puntatori \param{argv} in cui si devono
-inserire in successione i puntatori alle stringhe costituenti i vari argomenti
-ed opzioni, e della variabile \param{argc} che deve essere inizializzata al
-numero di stringhe passate. Nel caso della shell questo comporta che il primo
-argomento sia sempre il nome del programma; un esempio di questo meccanismo è
-mostrato in fig.~\ref{fig:proc_argv_argc}.
+Indipendentemente da come viene eseguita, il risultato finale della scansione
+dovrà comunque essere la costruzione del vettore di puntatori \param{argv} in
+cui si devono inserire in successione i puntatori alle stringhe costituenti i
+vari argomenti ed opzioni da passare al programma, e della
+variabile \param{argc} che deve essere inizializzata al numero di stringhe
+contenute in \param{argv}. Nel caso della shell questo comporta ad esempio che
+il primo argomento sia sempre il nome del programma. Un esempio di questo
+meccanismo è mostrato in fig.~\ref{fig:proc_argv_argc}, che illustra il
+risultato della scansione di una riga di comando.
 
 
 \subsection{La gestione delle opzioni}
@@ -1709,50 +1777,54 @@ mostrato in fig.~\ref{fig:proc_argv_argc}.
 
 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 \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
-\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 \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}
+tali: un elemento di \param{argv} successivo al primo 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 ``\texttt{-}'') e
+possono avere o no un parametro associato. Un esempio 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 degli argomenti a linea di comando passati
+in \param{argv} la libreria standard del C fornisce la funzione
+\funcd{getopt}, che ha il seguente prototipo:
+
+\begin{funcproto}{ 
+\fhead{unistd.h} 
+\fdecl{int getopt(int argc, char * const argv[], const char *optstring)}
+\fdesc{Esegue la scansione delle opzioni negli argomenti della funzione
+  \func{main}.} 
+}
+{Ritorna il carattere che segue l'opzione, ``\texttt{:}'' se manca un
+  parametro all'opzione, ``\texttt{?}'' se l'opzione è sconosciuta, e $-1$ se
+  non esistono altre opzioni.} 
+\end{funcproto}
 
 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.
+\param{argv} che devono essere quelle passate come argomenti di \func{main}
+all'esecuzione del programma, ed una stringa \param{optstring} che indica
+quali sono le opzioni valide. La funzione effettua la scansione della lista
+degli argomenti ricercando ogni stringa che comincia con il carattere
+``\texttt{-}'' e ritorna ogni volta che trova un'opzione valida.
 
 La stringa \param{optstring} indica quali sono le opzioni riconosciute ed è
 costituita da tutti i caratteri usati per identificare le singole opzioni, se
-l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
-due punti \texttt{':'}; nel caso di fig.~\ref{fig:proc_argv_argc} ad esempio la
-stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}.
+l'opzione ha un parametro al carattere deve essere fatto seguire il carattere
+di 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 \param{optstring} viene ritornato il carattere \texttt{'?'}
+dichiarata in \param{optstring} viene ritornato il carattere ``\texttt{?}''
 mentre se un'opzione che lo richiede non è seguita da un parametro viene
-ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
-\texttt{'-{}-'} la scansione viene considerata conclusa, anche se vi sono altri
-elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
+ritornato il carattere ``\texttt{:}'', infine se viene incontrato il valore
+``\texttt{-{}-}'' la scansione viene considerata conclusa, anche se vi sono
+altri elementi di \param{argv} che cominciano con il carattere ``\texttt{-}''.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
   \includecodesample{listati/option_code.c}
@@ -1762,9 +1834,10 @@ elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
   \label{fig:proc_options_code}
 \end{figure}
 
-Quando la funzione trova un'opzione essa ritorna il valore numerico del
-carattere, in questo modo si possono eseguire azioni specifiche usando uno
-\code{switch}; \func{getopt} inoltre inizializza alcune variabili globali:
+Quando \func{getopt} trova un'opzione fra quelle indicate in \param{optstring}
+essa ritorna il valore numerico del carattere, in questo modo si possono
+eseguire azioni specifiche usando uno \instruction{switch}; la funzione
+inoltre inizializza alcune \index{variabili!globali} variabili globali:
 \begin{itemize*}
 \item \var{char *optarg} contiene il puntatore alla stringa parametro
   dell'opzione.
@@ -1775,17 +1848,17 @@ carattere, in questo modo si possono eseguire azioni specifiche usando uno
 \item \var{int optopt} contiene il carattere dell'opzione non riconosciuta.
 \end{itemize*}
 
-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
+In fig.~\ref{fig:proc_options_code} si è 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 da esso supportate.
 
 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
+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.
@@ -1794,13 +1867,13 @@ 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
+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. 
+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
+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
@@ -1829,9 +1902,9 @@ 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}, che viene definita automaticamente per
-ciascun processo, e a cui si può accedere attraverso una semplice
-dichiarazione del tipo:
+\index{variabili!globali} variabile globale \var{environ}, che viene definita
+automaticamente per ciascun processo, e a cui si può accedere attraverso una
+semplice dichiarazione del tipo:
 \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
@@ -1878,7 +1951,8 @@ 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{ma si tratta solo di una
-  convenzione, niente vieta di usare caratteri minuscoli.}
+  convenzione, niente vieta di usare caratteri minuscoli, come avviene in vari
+  casi.}
 
 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
@@ -1913,7 +1987,7 @@ queste ed ulteriori variabili si può ottenere con il comando \cmd{man 7
 \begin{table}[htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|c|c|c|p{7cm}|}
+  \begin{tabular}[c]{|l|c|c|c|l|}
     \hline
     \textbf{Variabile} & \textbf{POSIX} & \textbf{XPG3} 
     & \textbf{Linux} & \textbf{Descrizione} \\
@@ -1946,20 +2020,20 @@ 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 \val{NULL} se non trova nulla, o il
-    puntatore alla stringa che corrisponde (di solito nella forma
-    \cmd{NOME=valore}).}
-\end{prototype}
 
-Oltre a questa funzione di lettura, che è l'unica definita dallo standard ANSI
-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 tab.~\ref{tab:proc_env_func}.
+\begin{funcproto}{ 
+\fhead{stdlib.h}
+\fdecl{char *getenv(const char *name)}
+\fdesc{Cerca una variabile di ambiente del processo.} 
+}
+{La funzione ritorna il puntatore alla stringa contenente il valore della
+  variabile di ambiente in caso di successo e \val{NULL} in caso di errore.} 
+\end{funcproto}
+
+La funzione effettua una ricerca nell'ambiente del processo cercando una
+variabile il cui nome corrisponda a quanto indicato con
+l'argomento \param{name}, ed in caso di successo ritorna il puntatore alla
+stringa che ne contiene il valore, nella forma ``\texttt{NOME=valore}''.
 
 \begin{table}[htb]
   \centering
@@ -1986,68 +2060,55 @@ in tab.~\ref{tab:proc_env_func}.
   \label{tab:proc_env_func}
 \end{table}
 
-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} 
-  
-  \funcdecl{int setenv(const char *name, const char *value, int overwrite)}
-  Imposta la variabile di ambiente \param{name} al valore \param{value}.
-  
-  \funcdecl{int putenv(char *string)} Aggiunge la stringa \param{string}
-  all'ambiente.
-  
-  \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e $-1$ per un
-    errore, che è sempre \errval{ENOMEM}.}
-\end{functions}
-
-La terza funzione della lista, \funcd{unsetenv}, serve a cancellare una
-variabile dall'ambiente, il suo prototipo è:
-\begin{functions}
-  \headdecl{stdlib.h}
-  
-  \funcdecl{void unsetenv(const char *name)} Rimuove la variabile di ambiente
-  \param{name}.
-\end{functions}
-
-\noindent la funzione elimina ogni occorrenza della variabile specificata; se la
-variabile non esiste non succede nulla. Non è prevista (dato che la funzione è
-\ctyp{void}) nessuna segnalazione di errore.
+Oltre a questa funzione di lettura, che è l'unica definita dallo standard ANSI
+C, nell'evoluzione dei sistemi Unix ne sono state proposte altre, da
+utilizzare per impostare, modificare e per cancellare le variabili di
+ambiente. Uno schema delle funzioni previste nei vari standard e disponibili
+in Linux è riportato in tab.~\ref{tab:proc_env_func}. Tutte le funzioni sono
+state comunque inserite nello standard POSIX.1-2001, ad eccetto di
+\func{clearenv} che è stata rigettata.
+
+In Linux sono definite tutte le funzioni elencate in
+tab.~\ref{tab:proc_env_func},\footnote{in realtà nelle libc4 e libc5 sono
+  definite solo le prime quattro, \func{clearenv} è stata introdotta con la
+  \acr{glibc} 2.0.} anche se parte delle funzionalità sono ridondanti. La
+prima funzione di manipolazione che prenderemo in considerazione è
+\funcd{putenv}, che consente di aggiungere, modificare e cancellare una
+variabile di ambiente; il suo prototipo è:
 
-Per modificare o aggiungere una variabile di ambiente si possono usare sia
-\func{setenv} che \func{putenv}. La prima permette di specificare
-separatamente nome e valore della variabile di ambiente, inoltre il valore di
-\param{overwrite} specifica il comportamento della funzione nel caso la
-variabile esista già, sovrascrivendola se diverso da zero, lasciandola
-immutata se uguale a zero.
+\begin{funcproto}{ 
+\fdecl{int putenv(char *string)}
+\fdesc{Inserisce, modifica o rimuove una variabile d'ambiente.} 
+}
+{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore, che può
+  essere solo \errval{ENOMEM}.}
+\end{funcproto}
 
-La seconda funzione prende come argomento una stringa analoga a quella
-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}. 
+La funzione prende come argomento una stringa analoga a quella restituita da
+\func{getenv} e sempre nella forma ``\texttt{NOME=valore}''. Se la variabile
+specificata (nel caso \texttt{NOME}) non esiste la stringa sarà aggiunta
+all'ambiente, se invece esiste il suo valore sarà impostato a quello
+specificato dal contenuto di \param{string} (nel caso \texttt{valore}).  Se
+invece si passa come argomento solo il nome di una variabile di ambiente
+(cioè \param{string} è nella forma ``\texttt{NAME}'' e non contiene il
+carattere ``\texttt{=}'') allora questa, se presente nell'ambiente, verrà
+cancellata.
 
 Si tenga presente che, seguendo lo standard SUSv2, le \acr{glibc} successive
-alla versione 2.1.2 aggiungono \param{string} alla lista delle variabili di
-ambiente;\footnote{il comportamento è lo stesso delle vecchie \acr{libc4} e
-  \acr{libc5}; nelle \acr{glibc}, dalla versione 2.0 alla 2.1.1, veniva invece
-  fatta una copia, 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 \direct{const} dal prototipo.} 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
-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 carattere \texttt{'='}) allora questa viene
-cancellata dall'ambiente.
-
-Infine quando chiamata a \func{putenv} comporta la necessità di creare una
+alla versione 2.1.2 aggiungono direttamente \param{string} nella lista delle
+variabili di ambiente illustrata in fig.~\ref{fig:proc_envirno_list}
+sostituendo il relativo puntatore;\footnote{il comportamento è lo stesso delle
+  vecchie \acr{libc4} e \acr{libc5}; nella \acr{glibc}, dalla versione 2.0
+  alla 2.1.1, veniva invece fatta una copia, 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 \direct{const}
+  dal prototipo.}  pertanto ogni cambiamento alla stringa in questione si
+riflette automaticamente sull'ambiente, e quindi si deve evitare di passare a
+questa funzione una \index{variabili!automatiche} variabile automatica (per
+evitare i problemi esposti in sez.~\ref{sec:proc_var_passing}).
+
+Infine quando una chiamata a \func{putenv} comporta la necessità di creare una
 nuova versione del vettore \var{environ} questo sarà allocato automaticamente,
 ma la versione corrente sarà deallocata solo se anch'essa è risultante da
 un'allocazione fatta in precedenza da un'altra \func{putenv}. Questo avviene
@@ -2058,17 +2119,59 @@ nello \itindex{heap} \textit{heap} e quindi non può essere deallocato.
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
 liberata.
 
+Come alternativa a \func{putenv} si può usare la funzione \funcd{setenv} che
+però consente solo di aggiungere o modificare una variabile di ambiente; il
+suo prototipo è:
+
+\begin{funcproto}{ 
+\fhead{stdlib.h}
+\fdecl{int setenv(const char *name, const char *value, int overwrite)}
+\fdesc{Inserisce o modifica una variabile di ambiente.} 
+}
+{La funzione ritorna 0 in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{ENOMEM}] non c'è memoria sufficiente per aggiungere una nuova
+    variabile all'ambiente.
+  \item[\errcode{EINVAL}] \param{name} è \val{NULL} o una stringa di lunghezza
+  nulla o che contiene il carattere ``\texttt{=}''.
+\end{errlist}}
+\end{funcproto}
+
+La funzione consente di specificare separatamente nome e valore della
+variabile di ambiente da aggiungere negli argomenti \param{name}
+e \param{value}. Se la variabile è già presente nell'ambiente
+l'argomento \param{overwrite} specifica il comportamento della funzione, se
+diverso da zero sarà sovrascritta, se uguale a zero sarà lasciata immutata.  A
+differenza di \func{putenv} la funzione esegue delle copie del contenuto degli
+argomenti \param{name} e \param{value} e non è necessario preoccuparsi di
+allocarli in maniera permanente.
+
+La cancellazione di una variabile di ambiente viene invece gestita
+esplicitamente con \funcd{unsetenv}, il cui prototipo è:
+
+\begin{funcproto}{ 
+\fhead{stdlib.h}
+\fdecl{int unsetenv(const char *name)}
+\fdesc{Rimuove una variabile di ambiente.} 
+}
+{La funzione ritorna 0 in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EINVAL}] \param{name} è \val{NULL} o una stringa di lunghezza
+  nulla o che contiene il carattere ``\texttt{=}''.
+  \end{errlist}}  
+\end{funcproto}
+
+La funzione richiede soltanto il nome della variabile di ambiente
+nell'argomento \param{name}, se la variabile non esiste la funzione ritorna
+comunque con un valore di successo.\footnote{questo con le versioni della
+  \acr{glibc} successive la 2.2.2, per le precedenti \func{unsetenv} era
+  definita come \texttt{void} e non restituiva nessuna informazione.}
+
 L'ultima funzione per la gestione dell'ambiente è \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
@@ -2076,23 +2179,25 @@ 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.
 
+
 \subsection{La localizzazione}
 \label{sec:proc_localization}
 
 Abbiamo accennato in sez.~\ref{sec:proc_environ} come la variabile di ambiente
 \texttt{LANG} sia usata per indicare ai processi il valore della cosiddetta
 \textsl{localizzazione}. Si tratta di una funzionalità fornita dalle librerie
-di sistema\footnote{prenderemo in esame soltanto il caso delle \acr{glibc}.}
+di sistema\footnote{prenderemo in esame soltanto il caso della \acr{glibc}.}
 che consente di gestire in maniera automatica sia la lingua in cui vengono
 stampati i vari messaggi (come i messaggi associati agli errori che vedremo in
 sez.~\ref{sec:sys_strerror}) che le convenzioni usate nei vari paesi per una
 serie di aspetti come il formato dell'ora, quello delle date, gli ordinamenti
 alfabetici, le espressioni della valute, ecc.
 
-La localizzazione di un programma si può selezionare con la 
+Da finire.
 
+% La localizzazione di un programma si può selezionare con la 
 
-In realtà perché un programma sia effettivamente localizzato non è sufficiente 
+In realtà perché un programma sia effettivamente localizzato non è sufficiente 
 
 % TODO trattare, quando ci sarà tempo, setlocale ed il resto
 
@@ -2113,53 +2218,85 @@ In realtà perché un programma sia effettivamente localizzato non è sufficient
 \section{Problematiche di programmazione generica}
 \label{sec:proc_gen_prog}
 
-Benché questo non sia un libro di C, è opportuno affrontare alcune delle
-problematiche generali che possono emergere nella programmazione e di quali
-precauzioni o accorgimenti occorre prendere per risolverle. Queste
-problematiche non sono specifiche di sistemi unix-like o multitasking, ma
-avendo trattato in questo capitolo il comportamento dei processi visti come
-entità a sé stanti, le riportiamo qui.
+Benché questo non sia un libro sul linguaggio C, è opportuno affrontare alcune
+delle problematiche generali che possono emergere nella programmazione con
+questo linguaggio e di quali precauzioni o accorgimenti occorre prendere per
+risolverle. Queste problematiche non sono specifiche di sistemi unix-like o
+multitasking, ma avendo trattato in questo capitolo il comportamento dei
+processi visti come entità a sé stanti, le riportiamo qui.
 
 
-\subsection{Il passaggio delle variabili e dei valori di ritorno}
+\subsection{Il passaggio di variabili e valori di ritorno nelle funzioni}
 \label{sec:proc_var_passing}
 
 Una delle caratteristiche standard del C è che le variabili vengono passate
-alle subroutine attraverso un meccanismo che viene chiamato \textit{by value}
-(diverso ad esempio da quanto avviene con il Fortran, dove le variabili sono
-passate, come suol dirsi, \textit{by reference}, o dal C++ dove la modalità
-del passaggio può essere controllata con l'operatore \cmd{\&}).
+alle funzioni che si invocano in un programma attraverso un meccanismo che
+viene chiamato \textit{by value}, diverso ad esempio da quanto avviene con il
+Fortran, dove le variabili sono passate, come suol dirsi, \textit{by
+  reference}, o dal C++ dove la modalità del passaggio può essere controllata
+con l'operatore \cmd{\&}.
 
 Il passaggio di una variabile \textit{by value} significa che in realtà quello
-che viene passato alla subroutine è una copia del valore attuale di quella
-variabile, copia che la subroutine potrà modificare a piacere, senza che il
+che viene passato alla funzione è una copia del valore attuale di quella
+variabile, copia che la funzione potrà modificare a piacere, senza che il
 valore originale nella funzione chiamante venga toccato. In questo modo non
-occorre preoccuparsi di eventuali effetti delle operazioni della subroutine
-sulla variabile passata come argomento.
+occorre preoccuparsi di eventuali effetti delle operazioni svolte nella
+funzione stessa sulla variabile passata come argomento.
 
 Questo però va inteso nella maniera corretta. Il passaggio \textit{by value}
-vale per qualunque variabile, puntatori compresi; quando però in una
-subroutine si usano dei puntatori (ad esempio per scrivere in un buffer) in
-realtà si va a modificare la zona di memoria a cui essi puntano, per cui anche
-se i puntatori sono copie, i dati a cui essi puntano sono sempre gli stessi, e
+vale per qualunque variabile, puntatori compresi; quando però in una funzione
+si usano dei puntatori (ad esempio per scrivere in un buffer) in realtà si va
+a modificare la zona di memoria a cui essi puntano, per cui anche se i
+puntatori sono copie, i dati a cui essi puntano saranno sempre gli stessi, e
 le eventuali modifiche avranno effetto e saranno visibili anche nella funzione
 chiamante.
 
-Nella maggior parte delle funzioni di libreria e delle system call i puntatori
-vengono usati per scambiare dati (attraverso buffer o strutture) e le
-variabili semplici vengono usate per specificare argomenti; in genere le
-informazioni a riguardo dei risultati vengono passate alla funzione chiamante
-attraverso il valore di ritorno.  È buona norma seguire questa pratica anche
-nella programmazione normale.
+Nella maggior parte delle funzioni di libreria e delle \textit{system call} i
+puntatori vengono usati per scambiare dati (attraverso i buffer o le strutture
+a cui fanno riferimento) e le variabili normali vengono usate per specificare
+argomenti; in genere le informazioni a riguardo dei risultati vengono passate
+alla funzione chiamante attraverso il valore di ritorno.  È buona norma
+seguire questa pratica anche nella programmazione normale.
 
 Talvolta però è necessario che la funzione possa restituire indietro alla
-funzione chiamante un valore relativo ad uno dei suoi argomenti.  Per far
-questo si usa il cosiddetto \itindex{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.
+funzione chiamante un valore relativo ad uno dei suoi argomenti usato anche in
+ingresso.  Per far questo si usa il cosiddetto \itindex{value~result~argument}
+\textit{value result argument}, si passa cioè, invece di una normale
+variabile, un puntatore alla stessa. Gli esempi di questa modalità di
+passaggio sono moltissimi, ad esempio essa viene usata 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 proprio questo meccanismo.
+
+Occorre tenere ben presente questa differenza, perché le variabili passate in
+maniera ordinaria, che vengono inserite nello \textit{stack}, cessano di
+esistere al ritorno di una funzione, ed ogni loro eventuale modifica
+all'interno della stessa sparisce con la conclusione della stessa, per poter
+passare delle informazioni occorre quindi usare un puntatore che faccia
+riferimento ad un indirizzo accessibile alla funzione chiamante.
+
+Questo requisito di accessibilità è fondamentale, infatti dei possibili
+problemi che si possono avere con il passaggio dei dati è quello di restituire
+alla funzione chiamante dei dati che sono contenuti in una
+\index{variabili!automatiche} variabile automatica.  Ovviamente quando la
+funzione ritorna la sezione dello \itindex{stack} \textit{stack} che conteneva
+la \index{variabili!automatiche} variabile automatica (si ricordi quanto detto
+in sez.~\ref{sec:proc_mem_alloc}) verrà liberata automaticamente e potrà
+essere riutilizzata all'invocazione di un'altra funzione, con le immaginabili
+conseguenze, quasi invariabilmente catastrofiche, di sovrapposizione e
+sovrascrittura dei dati.
+
+Per questo una delle regole fondamentali della programmazione in C è che
+all'uscita di una funzione non deve restare nessun riferimento alle sue
+\index{variabili!automatiche} variabili locali. Qualora sia necessario
+utilizzare delle variabili che devono essere viste anche dalla funzione
+chiamante queste devono essere allocate esplicitamente, o in maniera statica
+usando variabili globali o dichiarate come \direct{extern},\footnote{la
+  direttiva \direct{extern} informa il compilatore che la variabile che si è
+  dichiarata in una funzione non è da considerarsi locale, ma globale, e per
+  questo allocata staticamente e visibile da tutte le funzioni dello stesso
+  programma.} o dinamicamente con una delle funzioni della famiglia
+\func{malloc}, passando opportunamente il relativo puntatore fra le funzioni.
 
 
 \subsection{Il passaggio di un numero variabile di argomenti}
@@ -2170,33 +2307,32 @@ numero fisso di argomenti per una funzione.  Lo standard ISO C prevede nella
 sua sintassi la possibilità di definire delle \index{variadic}
 \textit{variadic function} che abbiano un numero variabile di argomenti,
 attraverso l'uso nella dichiarazione della funzione dello speciale costrutto
-``\texttt{\textellipsis}'', che viene chiamato \textit{ellipsis}.
+``\texttt{...}'', che viene chiamato \textit{ellipsis}.
 
 Lo standard però non provvede a livello di linguaggio alcun meccanismo con cui
 dette funzioni possono accedere ai loro argomenti.  L'accesso viene pertanto
-realizzato a livello delle librerie standard del C che provvedono gli
-strumenti adeguati.  L'uso di una \textit{variadic function} prevede quindi
-tre punti:
+realizzato a livello della libreria standard del C che fornisce gli strumenti
+adeguati.  L'uso di una \textit{variadic function} prevede quindi tre punti:
 \begin{itemize*}
-\item \textsl{Dichiarare} la funzione come \textit{variadic} usando un
-  prototipo che contenga una \textit{ellipsis}.
-\item \textsl{Definire} la funzione come \textit{variadic} usando la stessa
+\item \textsl{dichiarare} la funzione come \textit{variadic} usando un
+  prototipo che contenga una \textit{ellipsis};
+\item \textsl{definire} la funzione come \textit{variadic} usando la stessa
   \textit{ellipsis}, ed utilizzare le apposite macro che consentono la
-  gestione di un numero variabile di argomenti.
-\item \textsl{Invocare} la funzione specificando prima gli argomenti fissi, ed
+  gestione di un numero variabile di argomenti;
+\item \textsl{invocare} la funzione specificando prima gli argomenti fissi, ed
   a seguire quelli addizionali.
 \end{itemize*}
 
 Lo standard ISO C prevede che una \index{variadic} \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
-sez.~\ref{sec:proc_exec}:
+abbia sempre almeno un argomento fisso. Prima di effettuare la dichiarazione
+deve essere incluso l'apposito \textit{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 argomenti fissi ed un numero variabile
-di altri argomenti (che verranno a costituire gli elementi successivi al primo
-del vettore \param{argv} passato al nuovo processo). Lo standard ISO C
-richiede inoltre che l'ultimo degli argomenti fissi sia di tipo
+di altri argomenti, che andranno a costituire gli elementi successivi al primo
+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
@@ -2205,87 +2341,148 @@ richiede inoltre che l'ultimo degli argomenti fissi sia 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 argomento fisso come
-\direct{register}.
+\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.}
 
 Una volta dichiarata la funzione il secondo passo è accedere ai vari argomenti
 quando la si va a definire. Gli argomenti fissi infatti hanno un loro nome, ma
-quelli variabili vengono indicati in maniera generica dalla \textit{ellipsis}.
-
-L'unica modalità in cui essi possono essere recuperati è pertanto quella
-sequenziale; essi verranno estratti dallo \itindex{stack} \textit{stack}
-secondo l'ordine in cui sono 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
-  \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.
-\item Dichiarare la conclusione dell'estrazione degli argomenti invocando la
-  macro \macro{va\_end}.
-\end{enumerate*}
+quelli variabili vengono indicati in maniera generica dalla
+\textit{ellipsis}. L'unica modalità in cui essi possono essere recuperati è
+pertanto quella sequenziale, in cui vengono estratti dallo \itindex{stack}
+\textit{stack} secondo l'ordine in cui sono stati scritti nel prototipo della
+funzione. 
+
+Per fare questo in \file{stdarg.h} sono definite delle macro specifiche,
+previste dallo standard ISO C89, che consentono di eseguire questa operazione.
+La prima di queste macro è \macro{va\_start}, che inizializza opportunamente
+una lista degli argomenti, la sua definizione è:
+
+{\centering
+\begin{funcbox}{ 
+\fhead{stdarg.h}
+\fdecl{void va\_start(va\_list ap, last)}
+\fdesc{Inizializza una lista degli argomenti di una funzione
+  \textit{variadic}.} 
+}
+\end{funcbox}}
+
+La macro inizializza il puntatore alla lista di argomenti \param{ap} che
+deve essere una apposita variabile di tipo \type{va\_list}; il
+parametro \param{last} deve indicare il nome dell'ultimo degli argomenti fissi
+dichiarati nel prototipo della funzione \textit{variadic}. 
+
+La seconda macro di gestione delle liste di argomenti di una funzione
+\textit{variadic} è \macro{va\_arg}, che restituisce in successione un
+argomento della lista; la sua definizione è:
+
+{\centering
+\begin{funcbox}{ 
+\fhead{stdarg.h}
+\fdecl{type va\_arg(va\_list ap, type)}
+\fdesc{Restituisce il valore del successivo argomento opzionale.} 
+}
+\end{funcbox}}
+La macro restituisce il valore di un argomento, modificando opportunamente la
+lista \param{ap} perché una chiamata successiva restituisca l'argomento
+seguente. La macro richiede che si specifichi il tipo dell'argomento che si
+andrà ad estrarre attraverso il parametro \param{type} che sarà anche il tipo
+del valore da essa restituito. Si ricordi che il tipo deve essere
+\textit{self-promoting}.
 
 In generale è perfettamente legittimo richiedere meno argomenti di quelli che
 potrebbero essere stati effettivamente forniti, e nella esecuzione delle
 \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti
-saranno ignorati; se invece si richiedono più argomenti di quelli forniti si
-otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso di
-\macro{va\_end} è inutile, ma si consiglia di usarla ugualmente per
-compatibilità. Le definizioni delle macro citate sono le seguenti:
-\begin{functions}
-  \headdecl{stdarg.h}
-  
-  \funcdecl{void va\_start(va\_list ap, last)} Inizializza il puntatore alla
-  lista di argomenti \param{ap}; il parametro \param{last} \emph{deve} essere
-  l'ultimo degli argomenti fissi.
-  
-  \funcdecl{type va\_arg(va\_list ap, type)} Restituisce il valore del
-  successivo argomento opzionale, modificando opportunamente \param{ap}; la
-  macro richiede che si specifichi il tipo dell'argomento attraverso il
-  parametro \param{type} che deve essere il nome del tipo dell'argomento in
-  questione. Il tipo deve essere \textit{self-promoting}.
-
-  \funcdecl{void va\_end(va\_list ap)} Conclude l'uso di \param{ap}.
-\end{functions}
+saranno ignorati. Se invece si richiedono più argomenti di quelli forniti si
+otterranno dei valori indefiniti, si avranno risultati indefiniti anche quando
+si chiama \macro{va\_arg} specificando un tipo che non corrisponde a quello
+usato per il corrispondente argomento.
+
+Infine una volta completata l'estrazione occorre indicare che si sono concluse
+le operazioni con la macro \macro{va\_end}, la cui definizione è:
+
+{\centering
+\begin{funcbox}{ 
+\fhead{stdarg.h}
+\fdecl{void va\_end(va\_list ap)}
+\fdesc{Conclude l'estrazione degli argomenti di una funzione
+  \textit{variadic}.} 
+}
+\end{funcbox}}
+Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
+successive chiamate a \macro{va\_arg} non funzioneranno.  Nel caso del
+\cmd{gcc} l'uso di \macro{va\_end} può risultare inutile, ma è comunque
+necessario usarla per chiarezza del codice, per compatibilità con diverse
+implementazioni e per eventuali eventuali modifiche future a questo
+comportamento.
+
+Riassumendo la procedura da seguire per effettuare l'estrazione degli
+argomenti di una funzione \textit{variadic} è la seguente:
+\begin{enumerate*}
+\item inizializzare una lista degli argomenti attraverso la macro
+  \macro{va\_start};
+\item accedere agli argomenti con chiamate successive alla macro
+  \macro{va\_arg}: la prima chiamata restituirà il primo argomento, la seconda
+  il secondo e così via;
+\item dichiarare la conclusione dell'estrazione degli argomenti invocando la
+  macro \macro{va\_end}.
+\end{enumerate*}
 
-In generale si possono avere più puntatori alla lista degli argomenti,
-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 \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 dell'argomento.
+Si tenga presente che si possono usare anche più liste degli argomenti,
+ciascuna di esse andrà inizializzata con \macro{va\_start} e letta con
+\macro{va\_arg}, e ciascuna potrà essere usata per scandire la lista degli
+argomenti in modo indipendente. Infine ciascuna scansione dovrà essere
+terminata con \macro{va\_end}.
 
-Un altro limite delle macro è che i passi 1) e 3) devono essere eseguiti nel
+Un limite di queste macro è che i passi 1) e 3) devono essere eseguiti nel
 corpo principale della funzione, il passo 2) invece può essere eseguito anche
-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 \param{ap} risulterebbe indefinito.
+in un'altra funzione, passandole lista degli argomenti \param{ap}. In questo
+caso però al ritorno della funzione \macro{va\_arg} non può più essere usata
+(anche se non si era completata l'estrazione) dato che il valore di \param{ap}
+risulterebbe indefinito.
 
 Esistono dei casi in cui è necessario eseguire più volte la scansione degli
 argomenti e poter memorizzare una posizione durante la stessa. In questo caso
-sembrerebbe naturale copiarsi il puntatore alla lista degli argomenti con una
-semplice assegnazione. Dato che una delle realizzazioni più comuni di
-\macro{va\_list} è quella di un puntatore nello \itindex{stack} \textit{stack}
-all'indirizzo dove sono stati salvati gli argomenti, è assolutamente normale
-pensare di poter effettuare questa operazione.
-
-In generale però possono esistere anche realizzazioni diverse, per questo
-motivo \macro{va\_list} è definito come \index{tipo!opaco} \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
+sembrerebbe naturale copiarsi la lista degli argomenti \param{ap} con una
+semplice assegnazione ad un'altra variabile dello stesso tipo. Dato che una
+delle realizzazioni più comuni di \type{va\_list} è quella di un puntatore
+nello \itindex{stack} \textit{stack} all'indirizzo dove sono stati salvati gli
+argomenti, è assolutamente normale pensare di poter effettuare questa
+operazione.
+
+In generale però possono esistere anche realizzazioni diverse, ed è per questo
+motivo che invece che di un semplice puntatore viene \type{va\_list} è quello
+che viene chiamato un \index{tipo!opaco} \textsl{tipo opaco}. Si chiamano così
+quei tipi di dati, in genere usati da una libreria, la cui struttura interna
+non deve essere vista dal programma chiamante (da cui deriva il nome opaco)
+che li devono utilizzare solo attraverso dalle opportune funzioni di
+gestione. Per questo motivo non può essere assegnata 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}.
-\end{prototype}
-\noindent anche in questo caso è buona norma chiudere ogni esecuzione di una
-\macro{va\_copy} con una corrispondente \macro{va\_end} sul nuovo puntatore
-alla lista degli argomenti.
+ha previsto una macro ulteriore che permette di eseguire la copia di una lista
+degli argomenti:
+
+{\centering
+\begin{funcbox}{ 
+\fhead{stdarg.h}
+\fdecl{void va\_copy(va\_list dest, va\_list src)}
+\fdesc{Copia la lista degli argomenti di una funzione \textit{variadic}.} 
+}
+\end{funcbox}}
+
+La macro copia l'attuale della lista degli argomenti \param{src} su una nuova
+lista \param{dest}. Anche in questo caso è buona norma chiudere ogni
+esecuzione di una \macro{va\_copy} con una corrispondente \macro{va\_end} sul
+nuovo puntatore alla lista degli argomenti.
 
 La chiamata di una funzione con un numero variabile di argomenti, posto che la
 si sia dichiarata e definita come tale, non prevede nulla di particolare;
@@ -2316,24 +2513,6 @@ come ultimo argomento (come fa ad esempio \func{execl} che usa un puntatore
 \val{NULL} per indicare la fine della lista degli argomenti).
 
 
-\subsection{Potenziali problemi con le variabili automatiche}
-\label{sec:proc_auto_var}
-
-Uno dei possibili problemi che si possono avere con le subroutine è quello di
-restituire alla funzione chiamante dei dati che sono contenuti in una
-variabile automatica.  Ovviamente quando la subroutine ritorna la sezione
-dello \itindex{stack} \textit{stack} che conteneva la variabile automatica
-potrà essere riutilizzata da una nuova funzione, con le immaginabili
-conseguenze di sovrapposizione e sovrascrittura dei dati.
-
-Per questo una delle regole fondamentali della programmazione in C è che
-all'uscita di una funzione non deve restare nessun riferimento alle variabili
-locali; qualora sia necessario utilizzare variabili che possano essere viste
-anche dalla funzione chiamante queste devono essere allocate esplicitamente, o
-in maniera statica (usando variabili di tipo \ctyp{static} o \ctyp{extern}), o
-dinamicamente con una delle funzioni della famiglia \func{malloc}.
-
-
 \subsection{Il controllo di flusso non locale}
 \label{sec:proc_longjmp}
 
@@ -2388,14 +2567,11 @@ quando serve.  La funzione che permette di salvare il contesto dello
   
 Quando si esegue la funzione il contesto corrente dello \itindex{stack}
 \textit{stack} viene salvato nell'argomento \param{env}, una variabile di tipo
-\type{jmp\_buf}\footnote{questo è un classico esempio di variabile di
-  \index{tipo!opaco} \textsl{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.
+\type{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di
+  \index{tipo!opaco} \textsl{tipo opaco}.}  che deve essere stata definita in
+precedenza. In genere le variabili di tipo \type{jmp\_buf} vengono definite
+come \index{variabili!globali} 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
@@ -2456,19 +2632,13 @@ di \func{setjmp}, quest'ultima usualmente viene 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
-\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.
+variabili, ed in particolare quello delle \index{variabili!automatiche}
+variabili automatiche della funzione a cui si ritorna. In generale le
+\index{variabili!globali} variabili globali e \index{variabili!statiche}
+statiche mantengono i valori che avevano al momento della chiamata di
+\func{longjmp}, ma quelli delle \index{variabili!automatiche} variabili
+automatiche (o di quelle dichiarate \direct{register}) 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
@@ -2628,9 +2798,10 @@ il valore del confronto delle due variabili.
 % LocalWords:  Sun order VME  loader Windows DLL shared objects PRELOAD termios
 % LocalWords:  is to LC SIG str mem wcs assert ctype dirent fcntl signal stdio
 % LocalWords:  times library utmp syscall number Filesystem Hierarchy pathname
+% LocalWords:  context assembler sysconf fork Dinamic huge segmentation program
+% LocalWords:  break  store
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
-% LocalWords:  context assembler sysconf fork