Completata la descrizione dell'esempio dei mutex realizzati con i semafori.
[gapil.git] / process.tex
index d23e54f..67cb4f5 100644 (file)
@@ -24,8 +24,8 @@ ciascun processo vedr
 tutte le parti uguali siano condivise), avrà un suo spazio di indirizzi,
 variabili proprie e sarà eseguito in maniera completamente indipendente da
 tutti gli altri.\footnote{questo non è del tutto vero nel caso di un programma
-  \textit{multi-thread}, ma sulla gestione dei \textit{thread} in Linux
-  torneremo più avanti.}
+  \textit{multi-thread}, ma la gestione dei \textit{thread} in Linux sarà
+  trattata a parte.}
 
 
 \subsection{La funzione \func{main}} 
@@ -50,10 +50,10 @@ Lo standard ISO C specifica che la funzione \func{main} pu
 argomenti o prendere due argomenti che rappresentano gli argomenti passati da
 linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-     int main (int argc, char *argv[])
+    int main (int argc, char *argv[])
 \end{lstlisting}
 
-In realtà nei sistemi unix esiste un'altro modo per definire la funzione
+In realtà nei sistemi Unix esiste un'altro modo per definire la funzione
 \func{main}, che prevede la presenza di un terzo parametro, \var{char
   *envp[]}, che fornisce l'\textsl{ambiente} (vedi \secref{sec:proc_environ})
 del programma; questa forma però non è prevista dallo standard POSIX.1 per cui
@@ -63,7 +63,7 @@ se si vogliono scrivere programmi portabili 
 \subsection{Come chiudere un programma}
 \label{sec:proc_conclusion}
 
-Normalmente un programma finisce è quando la funzione \func{main} ritorna, una
+Normalmente un programma finisce quando la funzione \func{main} ritorna, una
 modalità equivalente di chiudere il programma è quella di chiamare
 direttamente la funzione \func{exit} (che viene comunque chiamata
 automaticamente quando \func{main} ritorna).  Una forma alternativa è quella
@@ -157,11 +157,11 @@ specificato in \param{status} che pu
 
 Un'esigenza comune che si incontra nella programmazione è quella di dover
 effettuare una serie di operazioni di pulizia (ad esempio salvare dei dati,
-ripristinare dei settaggi, eliminare dei file temporanei, ecc.) prima della
-conclusione di un programma. In genere queste operazioni vengono fatte in
-un'apposita sezione del programma, ma quando si realizza una libreria diventa
-antipatico dover richiedere una chiamata esplicita ad una funzione di pulizia
-al programmatore che la utilizza.
+ripristinare delle impostazioni, eliminare dei file temporanei, ecc.) prima
+della conclusione di un programma. In genere queste operazioni vengono fatte
+in un'apposita sezione del programma, ma quando si realizza una libreria
+diventa antipatico dover richiedere una chiamata esplicita ad una funzione di
+pulizia al programmatore che la utilizza.
 
 È invece molto meno soggetto ad errori, e completamente trasparente
 all'utente, avere la possibilità di effettuare automaticamente la chiamata ad
@@ -175,7 +175,7 @@ pu
   programma. 
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, \var{errno} non viene settata.}
+    fallimento, \var{errno} non viene modificata.}
 \end{prototype}
 \noindent la funzione richiede come argomento l'indirizzo della opportuna
 funzione di pulizia da chiamare all'uscita, che non deve prendere argomenti e
@@ -192,7 +192,7 @@ definita su altri sistemi; il suo prototipo 
   rispetto a quello di registrazione.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, \var{errno} non viene settata.}
+    fallimento, \var{errno} non viene modificata.}
 \end{prototype}
 
 In questo caso la funzione da chiamare prende due parametri, il primo dei
@@ -211,7 +211,7 @@ stream aperti, infine verr
 \label{sec:proc_term_conclusion}
 
 Data l'importanza dell'argomento è opportuno sottolineare ancora una volta che
-in un sistema unix l'unico modo in cui un programma può essere eseguito dal
+in un sistema Unix l'unico modo in cui un programma può essere eseguito dal
 kernel è attraverso la chiamata alla system call \func{execve} (o attraverso
 una delle funzioni della famiglia \func{exec} che vedremo in
 \secref{sec:proc_exec}).
@@ -222,7 +222,7 @@ volontariamente la sua esecuzione 
 \func{exit} o il ritorno di \func{main}.
 
 Uno schema riassuntivo che illustra le modalità con cui si avvia e conclude
-normalmente un programma è riportato in \nfig.
+normalmente un programma è riportato in \figref{fig:proc_prog_start_stop}.
 
 \begin{figure}[htb]
   \centering
@@ -233,7 +233,8 @@ normalmente un programma 
 
 Si ricordi infine che un programma può anche essere interrotto dall'esterno
 attraverso l'uso di un segnale (modalità di conclusione non mostrata in
-\curfig); torneremo su questo aspetto in \capref{cha:signals}.
+\figref{fig:proc_prog_start_stop}); torneremo su questo aspetto in
+\capref{cha:signals}.
 
 
 
@@ -253,11 +254,12 @@ esecuzione, e le varie funzioni utilizzabili per la sua gestione.
 Ci sono vari modi in cui i vari sistemi organizzano la memoria (ed i dettagli
 di basso livello dipendono spesso in maniera diretta dall'architettura
 dell'hardware), ma quello più tipico, usato dai sistemi unix-like come Linux è
-la cosiddetta \textsl{memoria virtuale} che consiste nell'assegnare ad ogni
-processo uno spazio virtuale di indirizzamento lineare, in cui gli indirizzi
-vanno da zero ad un qualche valore massimo.\footnote{nel caso di Linux fino al
-  kernel 2.2 detto massimo era, per macchine a 32bit, di 2Gb, con il kernel
-  2.4 ed il supporto per la \textit{high-memory} il limite è stato esteso.}
+la cosiddetta \textsl{memoria virtuale}\index{memoria virtuale} che consiste
+nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare,
+in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel
+  caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di
+  2Gb, con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite
+  è stato esteso.}
 
 Come accennato in \capref{cha:intro_unix} questo spazio di indirizzi è
 virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del
@@ -286,15 +288,16 @@ gestione della memoria (la \textit{Memory Management Unit} del processore).
 Poiché in genere la memoria fisica è solo una piccola frazione della memoria
 virtuale, è necessario un meccanismo che permetta di trasferire le pagine che
 servono dal supporto su cui si trovano in memoria, eliminando quelle che non
-servono. Questo meccanismo è detto \textit{paging}, ed è uno dei compiti
-principali del kernel.
+servono. Questo meccanismo è detto \textsl{paginazione}\index{paginazione} (o
+\textit{paging}), ed è uno dei compiti principali del kernel.
 
 Quando un processo cerca di accedere ad una pagina che non è nella memoria
-reale, avviene quello che viene chiamato un \textit{page fault}; l'hardware di
-gestione della memoria genera un'interruzione e passa il controllo al kernel
-il quale sospende il processo e si incarica di mettere in RAM la pagina
-richiesta (effettuando tutte le operazioni necessarie per reperire lo spazio
-necessario), per poi restituire il controllo al processo.
+reale, avviene quello che viene chiamato un 
+\textit{page fault}\index{page fault}; 
+l'hardware di gestione della memoria genera un'interruzione e passa
+il controllo al kernel il quale sospende il processo e si incarica di mettere
+in RAM la pagina richiesta (effettuando tutte le operazioni necessarie per
+reperire lo spazio necessario), per poi restituire il controllo al processo.
 
 Dal punto di vista di un processo questo meccanismo è completamente
 trasparente, e tutto avviene come se tutte le pagine fossero sempre
@@ -305,8 +308,8 @@ a tempi molto pi
 Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed
 in genere il sistema è molto efficiente in questo lavoro; quando però ci siano
 esigenze specifiche di prestazioni è possibile usare delle funzioni che
-permettono di bloccare il meccanismo del paging e mantenere fisse delle pagine
-in memoria (vedi \ref{sec:proc_mem_lock}).
+permettono di bloccare il meccanismo della paginazione e mantenere fisse delle
+pagine in memoria (vedi \ref{sec:proc_mem_lock}).
 
 
 \subsection{La struttura della memoria di un processo}
@@ -318,14 +321,15 @@ tentativo di accedere ad un indirizzo non allocato 
 commette quando si è manipolato male un puntatore e genera quello che viene
 chiamato un \textit{segmentation fault}. Se si tenta cioè di leggere o
 scrivere da un indirizzo per il quale non esiste un'associazione della pagina
-virtuale, il kernel risponde al relativo \textit{page fault} mandando un
-segnale \macro{SIGSEGV} al processo, che normalmente ne causa la terminazione
-immediata.
+virtuale, il kernel risponde al relativo \textit{page fault}\index{page fault}
+mandando un segnale \macro{SIGSEGV} al processo, che normalmente ne causa la
+terminazione immediata.
 
-È pertanto importante capire come viene strutturata 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:
+È pertanto importante capire come viene strutturata \textsl{la memoria
+  virtuale}\index{page fault} 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}
 \item Il segmento di testo o \textit{text segment}. Contiene il codice del
@@ -380,10 +384,10 @@ programma C viene suddiviso nei seguenti segmenti:
   del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la
   funzione chiamata alloca qui lo spazio per le sue variabili locali: in
   questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
-  della funzione lo spazio è automaticamente rilasciato. Al ritorno della
-  funzione lo spazio è automaticamente ripulito. La pulizia in C e C++ viene
-  fatta dal chiamante.\footnote{a meno che non sia stato specificato
-    l'utilizzo di una calling convention diversa da quella standard.}
+  della funzione lo spazio è automaticamente rilasciato e ``ripulito''. La
+  pulizia in C e C++ viene fatta dal chiamante.\footnote{a meno che non sia
+    stato specificato l'utilizzo di una calling convention diversa da quella
+    standard.}
   
   La dimensione di questo segmento aumenta seguendo la crescita dello stack
   del programma, ma non viene ridotta quando quest'ultimo si restringe.
@@ -392,7 +396,7 @@ programma C viene suddiviso nei seguenti segmenti:
 \begin{figure}[htb]
   \centering
   \includegraphics[width=5cm]{img/memory_layout}
-  \caption{Disposizione tipica dei segmenti di memoria di un processo}
+  \caption{Disposizione tipica dei segmenti di memoria di un processo.}
   \label{fig:proc_mem_layout}
 \end{figure}
 
@@ -453,20 +457,20 @@ prototipi sono i seguenti:
   
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
   di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
+  \var{errno} assumerà il valore \macro{ENOMEM}.
 \funcdecl{void *malloc(size\_t size)}
   Alloca \var{size} byte nello heap. La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
   di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
+  \var{errno} assumerà il valore \macro{ENOMEM}.
 \funcdecl{void *realloc(void *ptr, size\_t size)}
   Cambia la dimensione del blocco allocato all'indirizzo \var{ptr}
   portandola a \var{size}.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
   di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
+  \var{errno} assumerà il valore \macro{ENOMEM}.
 \funcdecl{void free(void *ptr)}
   Disalloca lo spazio di memoria puntato da \var{ptr}.
 
@@ -477,7 +481,7 @@ allineato correttamente per tutti i tipi di dati; ad esempio sulle macchine a
 32 bit in genere è allineato a multipli di 4 byte e sulle macchine a 64 bit a
 multipli di 8 byte.
 
-In genere su usano le funzioni \func{malloc} e \func{calloc} per allocare
+In genere si usano le funzioni \func{malloc} e \func{calloc} per allocare
 dinamicamente la memoria necessaria al programma, e siccome i puntatori
 ritornati sono di tipo generico non è necessario effettuare un cast per
 assegnarli a puntatori al tipo di variabile per la quale si effettua
@@ -495,13 +499,13 @@ La funzione \func{realloc} si usa invece per cambiare (in genere aumentare) la
 dimensione di un'area di memoria precedentemente allocata, la funzione vuole
 in ingresso il puntatore restituito dalla precedente chiamata ad una
 \func{malloc} (se è passato un valore \macro{NULL} allora la funzione si
-comporta come \func{malloc},\footnote{questo è vero per Linux e
+comporta come \func{malloc})\footnote{questo è vero per Linux e
   l'implementazione secondo lo standard ANSI C, ma non è vero per alcune
   vecchie implementazioni, inoltre alcune versioni delle librerie del C
   consentivano di usare \func{realloc} anche per un puntatore liberato con
   \func{free} purché non ci fossero state nel frattempo altre chiamate a
   funzioni di allocazione, questa funzionalità è totalmente deprecata e non è
-  consentita sotto Linux.}) ad esempio quando si deve far crescere la
+  consentita sotto Linux.} ad esempio quando si deve far crescere la
 dimensione di un vettore. In questo caso se è disponibile dello spazio
 adiacente al precedente la funzione lo utilizza, altrimenti rialloca altrove
 un blocco della dimensione voluta, copiandoci automaticamente il contenuto; lo
@@ -528,25 +532,25 @@ variabile \macro{MALLOC\_CHECK\_} che quando viene definita mette in uso una
 versione meno efficiente delle funzioni suddette, che però è più tollerante
 nei confronti di piccoli errori come quello di chiamate doppie a \func{free}.
 In particolare:
-\begin{itemize*}
+\begin{itemize}
 \item se la variabile è posta a zero gli errori vengono ignorati.
 \item se è posta ad 1 viene stampato un avviso sullo \textit{standard error}
   (vedi \secref{sec:file_std_stream}).
 \item se è posta a 2 viene chiamata \func{abort}, che in genere causa
   l'immediata conclusione del programma.
-\end{itemize*}
+\end{itemize}
 
 Il problema più comune e più difficile da risolvere che si incontra con le
 routine di allocazione è quando non viene opportunamente liberata la memoria
 non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak},
-(cioè \textsl{perdita di memoria}).
+cioè una \textsl{perdita di memoria}.
 
 Un caso tipico che illustra il problema è quello in cui in una subroutine si
 alloca della memoria per uso locale senza liberarla prima di uscire. La
 memoria resta così allocata fino alla terminazione del processo.  Chiamate
 ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni,
 causando a lungo andare un esaurimento della memoria disponibile (e la
-probabile l'impossibilità di proseguire l'esecuzione programma).
+probabile impossibilità di proseguire l'esecuzione del programma).
 
 Il problema è che l'esaurimento della memoria può avvenire in qualunque
 momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
@@ -554,30 +558,61 @@ essere in una sezione del codice che non ha alcuna relazione con la subroutine
 che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
 \textit{memory leak}.
 
-Per ovviare a questi problemi l'implementazione delle routine di allocazione
-delle \acr{glibc} mette a disposizione una serie di funzionalità (su cui
-torneremo in \secref{sec:xxx_advanced}) che permettono di tracciare le
-allocazioni e le disallocazione, e definisce anche una serie di possibili
-\textit{hook} (\textsl{ganci}) che permettono di sostituire alle funzioni di
-libreria una propria versione (che può essere più o meno specializzata per il
-debugging).
+In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
+programmazione ad oggetti, il problema dei \textit{memory leak} è notevolmente
+ridimensionato attraverso l'uso accurato di appositi oggetti come gli
+\textit{smartpointers}.  Questo però va a scapito delle performance
+dell'applicazione in esecuzione.
+
+In altri linguaggi come il java e recentemente il C\# il problema non si pone
+nemmeno perché la gestione della memoria viene fatta totalmente in maniera
+automatica, ovvero il programmatore non deve minimamente preoccuparsi di
+liberare la memoria allocata precedentemente quando non serve più, poiché il
+framework gestisce automaticamente la cosiddetta \textit{garbage collection}.
+In tal caso, attraverso meccanismi simili a quelli del \textit{reference
+  counting}, quando una zona di memoria precedentemente allocata non è più
+riferita da nessuna parte del codice in esecuzione, può essere deallocata
+automaticamente in qualunque momento dall'infrastruttura.
+
+Anche questo va a scapito delle performance dell'applicazione in esecuzione
+(inoltre le applicazioni sviluppate con tali linguaggi di solito non sono
+eseguibili compilati, come avviene invece per il C ed il C++, ed è necessaria
+la presenza di una infrastruttura per la loro interpretazione e pertanto hanno
+di per sé delle performance più scadenti rispetto alle stesse applicazioni
+compilate direttamente).  Questo comporta però il problema della non
+predicibilità del momento in cui viene deallocata la memoria precedentemente
+allocata da un oggetto.
+
+Per limitare l'impatto di questi problemi, e semplificare la ricerca di
+eventuali errori, l'implementazione delle routine di allocazione delle
+\acr{glibc} mette a disposizione una serie di funzionalità che permettono di
+tracciare le allocazioni e le disallocazione, e definisce anche una serie di
+possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
+funzioni di libreria una propria versione (che può essere più o meno
+specializzata per il debugging). Esistono varie librerie che forniscono dei
+sostituti opportuni delle routine di allocazione in grado, senza neanche
+ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
+  \href{http://dmalloc.com/}{http://dmalloc.com/} di Gray Watson ed
+  \textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche
+molto complesse riguardo l'allocazione della memoria.
+
 
 
 \subsection{La funzione \func{alloca}}  
 \label{sec:proc_mem_alloca}
 
 Una possibile alternativa all'uso di \func{malloc}, che non soffre dei
-problemi di memory leak descritti in precedenza, è la funzione \func{alloca},
-che invece di allocare la memoria nello heap usa il segmento di stack della
-funzione corrente. La sintassi è identica a quella di \func{malloc}, il suo
-prototipo è:
+problemi di \textit{memory leak} descritti in precedenza, è la funzione
+\func{alloca}, che invece di allocare la memoria nello heap usa il segmento di
+stack della funzione corrente. La sintassi è identica a quella di
+\func{malloc}, il suo prototipo è:
 \begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
   Alloca \var{size} byte nel segmento di stack della funzione chiamante.
   La memoria non viene inizializzata.
 
   La funzione restituisce il puntatore alla zona di memoria allocata in caso
   di successo e \macro{NULL} in caso di fallimento, nel qual caso
-  \var{errno} viene settata a \macro{ENOMEM}.
+  \var{errno} assumerà il valore \macro{ENOMEM}.
 \end{prototype}
 \noindent ma in questo caso non è più necessario liberare la memoria (e quindi
 non esiste un analogo della \func{free}) in quanto essa viene rilasciata 
@@ -601,7 +636,7 @@ suo utilizzo quindi limita la portabilit
 non può essere usata nella lista degli argomenti di una funzione, perché lo
 spazio verrebbe allocato nel mezzo degli stessi.
 
-% Questo è riportato solo dal manuale delle glibc, nelle man page non c'è 
+% Questo è riportato solo dal manuale delle glibc, nelle pagine di manuale non c'è 
 % traccia di tutto ciò
 %
 %Inoltre se si
@@ -629,7 +664,7 @@ analoghe system call a cui fanno da interfaccia. I loro prototipi sono:
   \var{end\_data\_segment}.
   
   La funzione restituisce 0 in caso di successo e -1 in caso di
-    fallimento, nel qual caso \var{errno} viene settata a \macro{ENOMEM}.
+    fallimento, nel qual caso \var{errno} assumerà il valore \macro{ENOMEM}.
 
   \funcdecl{void *sbrk(ptrdiff\_t increment)} Incrementa lo spazio dati di un
   programma di \var{increment}. Un valore zero restituisce l'attuale posizione
@@ -637,7 +672,7 @@ analoghe system call a cui fanno da interfaccia. I loro prototipi sono:
   
   La funzione restituisce il puntatore all'inizio della nuova zona di memoria
   allocata in caso di successo e \macro{NULL} in caso di fallimento, nel qual
-  caso \macro{errno} viene settata a \macro{ENOMEM}.
+  caso \macro{errno} assumerà il valore \macro{ENOMEM}.
 \end{functions}
 \noindent in genere si usa \func{sbrk} con un valore zero per ottenere
 l'attuale posizione della fine del segmento dati.
@@ -653,19 +688,19 @@ implementare una sua versione delle routine di allocazione.
 % \label{sec:proc_mem_malloc_custom}
 
 
-\subsection{Il controllo della memoria virtuale}  
+\subsection{Il controllo della memoria virtuale\index{memoria virtuale}}  
 \label{sec:proc_mem_lock}
 
-Come spiegato in \secref{sec:proc_mem_gen} il kernel gestisce la memoria 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.
+Come spiegato in \secref{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.
 
 Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
-meccanismo della 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:
+meccanismo della paginazione\index{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}
 \item \textsl{La velocità}. Il processo della paginazione è trasparente solo
   se il programma in esecuzione non è sensibile al tempo che occorre a
@@ -684,11 +719,11 @@ avere di queste necessit
 \item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro
   in memoria queste possono essere portate su disco dal meccanismo della
   paginazione. Questo rende più lungo il periodo di tempo in cui detti segreti
-  sono presenti in chiaro e più complessa la loro cancellazione (ad un
-  processo è possibile cancellare la memoria su cui scrive le sue variabili,
-  ma non può toccare lo spazio disco su cui una pagina di memoria può essere
-  stata salvata). Per questo motivo di solito i programmi di crittografia
-  richiedono il blocco di alcune pagine di memoria.
+  sono presenti in chiaro e più complessa la loro cancellazione (un processo
+  può cancellare la memoria su cui scrive le sue variabili, ma non può toccare
+  lo spazio disco su cui una pagina di memoria può essere stata salvata). Per
+  questo motivo di solito i programmi di crittografia richiedono il blocco di
+  alcune pagine di memoria.
 \end{itemize}
 
 Il meccanismo che previene la paginazione di parte della memoria virtuale di
@@ -707,14 +742,14 @@ comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
 tutti i suoi \textit{memory lock}.
 
 I \textit{memory lock} non sono ereditati dai processi figli.\footnote{ma
-  siccome Linux usa il \textit{copy on write} (vedi \secref{sec:proc_fork})
-  gli indirizzi virtuali del figlio sono mantenuti sullo stesso segmento di
-  RAM del padre, quindi fintanto che un figlio non scrive su un segmento, può
-  usufruire del memory lock del padre.}  Siccome la presenza di un
-\textit{memory lock} riduce la memoria disponibile al sistema, con un impatto
-su tutti gli altri processi, solo l'amministratore ha la capacità di bloccare
-una pagina. Ogni processo può però sbloccare le pagine relative alla propria
-memoria.
+  siccome Linux usa il \textit{copy on write}\index{copy on write} (vedi
+  \secref{sec:proc_fork}) gli indirizzi virtuali del figlio sono mantenuti
+  sullo stesso segmento di RAM del padre, quindi fintanto che un figlio non
+  scrive su un segmento, può usufruire del memory lock del padre.}  Siccome la
+presenza di un \textit{memory lock} riduce la memoria disponibile al sistema,
+con un impatto su tutti gli altri processi, solo l'amministratore ha la
+capacità di bloccare una pagina. Ogni processo può però sbloccare le pagine
+relative alla propria memoria.
 
 Il sistema pone dei limiti all'ammontare di memoria di un processo che può
 essere bloccata e al totale di memoria fisica che può dedicare a questo, lo
@@ -738,7 +773,7 @@ Le funzioni per bloccare e sbloccare singole sezioni di memoria sono
 
   
   \bodydesc{Entrambe le funzioni ritornano 0 in caso di successo e -1 in
-    caso di errore, nel qual caso \var{errno} è settata ad uno dei
+    caso di errore, nel qual caso \var{errno} assumerà uno dei
     valori seguenti:
   \begin{errlist}
   \item[\macro{ENOMEM}] alcuni indirizzi dell'intervallo specificato non
@@ -786,11 +821,12 @@ esempio limitandosi a tutte le pagine allocate a partire da un certo momento.
 
 In ogni caso un processo real-time che deve entrare in una sezione critica
 deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
-scongiurare in partenza un eventuale page fault causato dal meccanismo di
-\textit{copy on write}.  Infatti se nella sezione critica si va ad utilizzare
-memoria che non è ancora stata riportata in RAM si potrebbe avere un page
-fault durante l'esecuzione della stessa, con conseguente rallentamento
-(probabilmente inaccettabile) dei tempi di esecuzione.
+scongiurare in partenza un eventuale page fault\index{page fault} causato dal
+meccanismo di \textit{copy on write}\index{copy on write}.  Infatti se nella
+sezione critica si va ad utilizzare memoria che non è ancora stata riportata
+in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
+conseguente rallentamento (probabilmente inaccettabile) dei tempi di
+esecuzione.
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
@@ -813,7 +849,7 @@ Oltre al passaggio dei parametri, un'altra modalit
 delle informazioni che modifichino il comportamento di un programma è quello
 dell'uso del cosiddetto \textit{environment} (cioè l'uso delle
 \textsl{variabili di ambiente}). In questa sezione esamineremo le funzioni che
-permettono di gestire parametri e opzioni, e quelle che consentono di
+permettono di gestire parametri ed opzioni, e quelle che consentono di
 manipolare ed utilizzare le variabili di ambiente.
 
 
@@ -824,8 +860,8 @@ 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 viene considerata un parametro. Di norma per individuare
 le parole viene usato come carattere di separazione lo spazio o il tabulatore,
-ma il comportamento è modificabile attraverso il settaggio della variabile di
-ambiente \cmd{IFS}.
+ma il comportamento è modificabile attraverso l'impostazione della variabile
+di ambiente \cmd{IFS}.
 
 \begin{figure}[htb]
   \centering
@@ -839,22 +875,22 @@ Nella scansione viene costruito il vettore di puntatori \var{argv} inserendo
 in successione il puntatore alla stringa costituente l'$n$-simo parametro; la
 variabile \var{argc} viene inizializzata al numero di parametri trovati, in
 questo modo il primo parametro è sempre il nome del programma; un esempio di
-questo meccanismo è mostrato in \curfig.
+questo meccanismo è mostrato in \figref{fig:proc_argv_argc}.
 
 
 \subsection{La gestione delle opzioni}
 \label{sec:proc_opt_handling}
 
-In generale un programma unix riceve da linea di comando sia gli argomenti che
+In generale un programma Unix riceve da linea di comando sia gli argomenti che
 le opzioni, queste ultime sono standardizzate per essere riconosciute come
-tali: un elemento di \var{argv} che inizia con \texttt{-} e che non sia un
-singolo \texttt{-} o un \texttt{--} viene considerato un'opzione.  In genere
-le opzioni sono costituite da una lettera singola (preceduta dal \cmd{-}) e
-possono avere o no un parametro associato; un comando tipico può essere quello
-mostrato in \figref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r}
-ed \cmd{-m} e la prima vuole un parametro mentre la seconda no
-(\cmd{questofile.txt} è un argomento del programma, non un parametro di
-\cmd{-m}).
+tali: un elemento di \var{argv} che inizia con il carattere \texttt{'-'} e che
+non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato
+un'opzione.  In genere le opzioni sono costituite da una lettera singola
+(preceduta dal carattere \cmd{'-'}) e possono avere o no un parametro
+associato; un comando tipico può essere quello mostrato in
+\figref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r} e \cmd{-m}
+e la prima vuole un parametro mentre la seconda no (\cmd{questofile.txt} è un
+argomento del programma, non un parametro di \cmd{-m}).
 
 Per gestire le opzioni all'interno dei argomenti a linea di comando passati in
 \var{argv} le librerie standard del C forniscono la funzione \func{getopt}
@@ -878,8 +914,8 @@ valida.
 La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
 costituita da tutti i caratteri usati per identificare le singole opzioni, se
 l'opzione ha un parametro al carattere deve essere fatto seguire un segno di
-due punti \var{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
-stringa di opzioni avrebbe dovuto contenere \var{"r:m"}.
+due punti \texttt{':'}; nel caso di \figref{fig:proc_argv_argc} ad esempio la
+stringa di opzioni avrebbe dovuto contenere \texttt{"r:m"}.
 
 La modalità di uso di \func{getopt} è pertanto quella di chiamare più volte la
 funzione all'interno di un ciclo, fintanto che essa non ritorna il valore -1
@@ -887,7 +923,7 @@ che indica che non ci sono pi
 dichiarata in \var{optstring} viene ritornato il carattere \texttt{'?'}
 mentre se un opzione che lo richiede non è seguita da un parametro viene
 ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
-\cmd{--} la scansione viene considerata conclusa, anche se vi sono altri
+\texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri
 elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
 
 \begin{figure}[htb]
@@ -944,22 +980,21 @@ In \figref{fig:proc_options_code} 
 sulla creazione dei processi) deputata alla decodifica delle opzioni a riga di
 comando. 
 
-Anzitutto si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la
-stampa di messaggi di errore per opzioni non riconosciute, per poi passare al
-ciclo per la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle
-opzioni possibili si è poi provveduto ad un'azione opportuna, ad esempio per
-le tre opzioni che prevedono un parametro si è effettuata la decodifica del
-medesimo (il cui indirizzo è contenuto nella variabile \var{optarg})
-avvalorando la relativa variabile (\texttt{\small 12-14}, \texttt{\small
-  15-17} e \texttt{\small 18-20}). Completato il ciclo troveremo in
-\var{optind} l'indice in \var{argv[]} del primo degli argomenti rimanenti
-nella linea di comando.
+Si può notare che si è anzitutto (\texttt{\small 1}) disabilitata la stampa di
+messaggi di errore per opzioni non riconosciute, per poi passare al ciclo per
+la verifica delle opzioni (\texttt{\small 2-27}); per ciascuna delle opzioni
+possibili si è poi provveduto ad un'azione opportuna, ad esempio per le tre
+opzioni che prevedono un parametro si è effettuata la decodifica del medesimo
+(il cui indirizzo è contenuto nella variabile \var{optarg}) avvalorando la
+relativa variabile (\texttt{\small 12-14}, \texttt{\small 15-17} e
+\texttt{\small 18-20}). Completato il ciclo troveremo in \var{optind} l'indice
+in \var{argv[]} del primo degli argomenti rimanenti nella linea di comando.
 
 Normalmente \func{getopt} compie una permutazione degli elementi di \var{argv}
-così che alla fine della scansione gli elementi che non sono opzioni sono
+cosicché alla fine della scansione gli elementi che non sono opzioni sono
 spostati in coda al vettore. Oltre a questa esistono altre due modalità di
 gestire gli elementi di \var{argv}; se \var{optstring} inizia con il carattere
-\texttt{'+'} (o è settata la variabile di ambiente \macro{POSIXLY\_CORRECT})
+\texttt{'+'} (o è impostata la variabile di ambiente \macro{POSIXLY\_CORRECT})
 la scansione viene fermata non appena si incontra un elemento che non è
 un'opzione. L'ultima modalità, usata quando un programma può gestire la
 mescolanza fra opzioni e argomenti, ma se li aspetta in un ordine definito, si
@@ -1001,8 +1036,9 @@ dichiarazione del tipo:
 \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 extern char ** environ;
 \end{lstlisting}
-un esempio del contenuto dell'ambiente, in si è riportato un estratto delle
-variabili che normalmente sono definite dal sistema, è riportato in \nfig.
+un esempio della struttura di questa lista, contenente alcune delle variabili
+più comuni che normalmente sono definite dal sistema, è riportato in
+\figref{fig:proc_envirno_list}.
 \begin{figure}[htb]
   \centering
   \includegraphics[width=11cm]{img/environ_var}
@@ -1012,9 +1048,9 @@ variabili che normalmente sono definite dal sistema, 
 
 Per convenzione le stringhe che definiscono l'ambiente sono tutte del tipo
 \textsl{\texttt{nome=valore}}. Inoltre alcune variabili, come quelle elencate
-in \curfig, sono definite dal sistema per essere usate da diversi programmi e
-funzioni: per queste c'è l'ulteriore convenzione di usare nomi espressi in
-caratteri maiuscoli.
+in \figref{fig:proc_envirno_list}, sono definite dal sistema per essere usate
+da diversi programmi e funzioni: per queste c'è l'ulteriore convenzione di
+usare nomi espressi in caratteri maiuscoli.
 
 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
@@ -1024,18 +1060,21 @@ configurazione.
 
 La shell ad esempio ne usa molte per il suo funzionamento (come \var{PATH} per
 la ricerca dei comandi, o \cmd{IFS} per la scansione degli argomenti), e
-alcune di esse (come \var{HOME}, \var{USER}, etc.)  sono definite al login. In
-genere è cura dell'amministratore definire le opportune variabili di ambiente
-in uno script di avvio. Alcune servono poi come riferimento generico per molti
-programmi (come \var{EDITOR} che indica l'editor preferito da invocare in caso
-di necessità).
+alcune di esse (come \var{HOME}, \var{USER}, etc.) sono definite al login (per
+i dettagli si veda \secref{sec:sess_login}). In genere è cura
+dell'amministratore definire le opportune variabili di ambiente in uno script
+di avvio. Alcune servono poi come riferimento generico per molti programmi
+(come \var{EDITOR} che indica l'editor preferito da invocare in caso di
+necessità).
 
 Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più
-comuni), come riportato in \ntab. GNU/Linux le supporta tutte e ne definisce
-anche altre: per una lista più completa si può controllare \cmd{man environ}.
+comuni), come riportato in \tabref{tab:proc_env_var}. GNU/Linux le supporta
+tutte e ne definisce anche altre: per una lista più completa si può
+controllare \cmd{man environ}.
 
 \begin{table}[htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|l|c|c|c|p{7cm}|}
     \hline
     \textbf{Variabile} & \textbf{POSIX} & \textbf{XPG3} 
@@ -1043,7 +1082,7 @@ anche altre: per una lista pi
     \hline
     \hline
     \macro{USER} & $\bullet$ & $\bullet$ & $\bullet$ & Nome utente\\
-    \macro{LOGNAME} & $\bullet$ & $\bullet$ & $\bullet$ & Nome utente\\
+    \macro{LOGNAME} & $\bullet$ & $\bullet$ & $\bullet$ & Nome di login\\
     \macro{HOME} & $\bullet$ & $\bullet$ & $\bullet$ & 
     Directory base dell'utente\\
     \macro{LANG} & $\bullet$ & $\bullet$ & $\bullet$ & Localizzazione\\
@@ -1054,8 +1093,8 @@ anche altre: per una lista pi
     \macro{TERM} & $\bullet$ & $\bullet$ & $\bullet$ & Tipo di terminale\\
     \macro{PAGER} & $\bullet$ & $\bullet$ & $\bullet$ & Programma per vedere i
     testi\\
-    \macro{EDITOR} & $\bullet$ & $\bullet$ & $\bullet$ & Editor di default\\
-    \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser di default\\
+    \macro{EDITOR} & $\bullet$ & $\bullet$ & $\bullet$ & Editor preferito\\
+    \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser preferito\\
     \hline
   \end{tabular}
   \caption{Variabili di ambiente più comuni definite da vari standard.}
@@ -1077,12 +1116,13 @@ il cui prototipo 
 
 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 settare e per cancellare le variabili di ambiente. Uno schema
+utilizzare per impostare e per cancellare le variabili di ambiente. Uno schema
 delle funzioni previste nei vari standard e disponibili in Linux è riportato
-in \ntab.
+in \tabref{tab:proc_env_func}.
 
 \begin{table}[htb]
   \centering
+  \footnotesize
   \begin{tabular}[c]{|l|c|c|c|c|c|c|}
     \hline
     \textbf{Funzione} & \textbf{ANSI C} & \textbf{POSIX.1} & \textbf{XPG3} & 
@@ -1105,15 +1145,15 @@ in \ntab.
   \label{tab:proc_env_func}
 \end{table}
 
-In Linux solo le prime quattro funzioni di \curtab\ sono definite,
-\func{getenv} l'abbiamo già esaminata; delle tre restanti le prime due,
-\func{putenv} e \func{setenv}, servono per assegnare nuove variabili di
+In Linux solo le prime quattro funzioni di \tabref{tab:proc_env_func} sono
+definite, \func{getenv} l'abbiamo già esaminata; delle tre restanti le prime
+due, \func{putenv} e \func{setenv}, servono per assegnare nuove variabili di
 ambiente, i loro prototipi sono i seguenti:
 \begin{functions}
   \headdecl{stdlib.h} 
   
   \funcdecl{int setenv(const char *name, const char *value, int overwrite)}
-  Setta la variabile di ambiente \param{name} al valore \param{value}.
+  Imposta la variabile di ambiente \param{name} al valore \param{value}.
   
   \funcdecl{int putenv(char *string)} Aggiunge la stringa \param{string}
   all'ambiente.
@@ -1143,7 +1183,7 @@ immutata se uguale a zero.
 La seconda funzione prende come parametro una stringa analoga quella
 restituita da \func{getenv}, e sempre nella forma \var{NOME=valore}. Se la
 variabile specificata non esiste la stringa sarà aggiunta all'ambiente, se
-invece esiste il suo valore sarà settato a quello specificato da
+invece esiste il suo valore sarà impostato a quello specificato da
 \param{string}. Si tenga presente che, seguendo lo standard SUSv2, le
 \acr{glibc} successive alla versione 2.1.2 aggiungono\footnote{il
   comportamento è lo stesso delle vecchie \acr{libc4} e \acr{libc5}; nelle
@@ -1159,12 +1199,12 @@ questa funzione una variabile automatica (per evitare i problemi esposti in
 
 Si tenga infine presente che se si passa a \func{putenv} solo il nome di una
 variabile (cioè \param{string} è nella forma \texttt{NAME} e non contiene un
-\texttt{=}) allora questa viene cancellata dall'ambiente. Infine se la
-chiamata di \func{putenv} comporta la necessità di allocare una nuova versione
-del vettore \var{environ} questo sarà allocato, ma la versione corrente sarà
-deallocata solo se anch'essa è risultante da un'allocazione fatta in
-precedenza da un'altra \func{putenv}. Questo perché il vettore delle variabili
-di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
+carattere \texttt{'='}) allora questa viene cancellata dall'ambiente. Infine
+se la chiamata di \func{putenv} comporta la necessità di allocare una nuova
+versione del vettore \var{environ} questo sarà allocato, ma la versione
+corrente sarà deallocata solo se anch'essa è risultante da un'allocazione
+fatta in precedenza da un'altra \func{putenv}. Questo perché il vettore delle
+variabili di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
 \secref{sec:proc_exec}) è piazzato al di sopra dello stack, (vedi
 \figref{fig:proc_mem_layout}) e non nello heap e non può essere deallocato.
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
@@ -1213,7 +1253,6 @@ informazioni a riguardo dei risultati vengono passate alla routine 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 parametri.  Per far
 questo si usa il cosiddetto \textit{value result argument}, si passa cioè,
@@ -1336,12 +1375,12 @@ stack all'indirizzo dove sono stati salvati i parametri, 
 normale pensare di poter effettuare questa operazione.
 
 In generale però possono esistere anche realizzazioni diverse, per questo
-motivo \macro{va\_list} è definito come tipo opaco e non può essere assegnato
-direttamente ad un altra variabile dello stesso tipo. Per risolvere questo
-problema lo standard ISO C99\footnote{alcuni sistemi che non hanno questa
-  macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome proposto
-  in una bozza dello standard.} ha previsto una macro ulteriore che permette
-di eseguire la copia di un puntatore alla lista degli argomenti:
+motivo \macro{va\_list} è definito come \textsl{tipo opaco} e non può essere
+assegnato direttamente ad un'altra variabile dello stesso tipo. Per risolvere
+questo problema lo standard ISO C99\footnote{alcuni sistemi che non hanno
+  questa macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome
+  proposto in una bozza dello standard.} ha previsto una macro ulteriore che
+permette di eseguire la copia di un puntatore alla lista degli argomenti:
 \begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
   Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
   su \param{dest}.
@@ -1363,7 +1402,6 @@ argomenti opzionali, questi verranno sempre promossi, pertanto nella ricezione
 dei medesimi occorrerà tenerne conto (ad esempio un \ctyp{char} verrà visto da
 \macro{va\_arg} come \ctyp{int}).
 
-
 Uno dei problemi che si devono affrontare con le funzioni con un numero
 variabile di argomenti è che non esiste un modo generico che permetta di
 stabilire quanti sono i parametri passati effettivamente in una chiamata.
@@ -1397,6 +1435,7 @@ 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}
 
@@ -1405,46 +1444,118 @@ varie istruzioni del linguaggio C; fra queste la pi
 \code{goto}, che viene deprecato in favore dei costrutti della programmazione
 strutturata, che rendono il codice più leggibile e mantenibile . Esiste però
 un caso in cui l'uso di questa istruzione porta all'implementazione più
-efficiente e chiara anche dal punto di vista della struttura del programma,
+efficiente e chiara anche dal punto di vista della struttura del programma:
 quello dell'uscita in caso di errore.
 
 Il C però non consente di effettuare un salto ad una label definita in
-un'altra funzione, per cui se l'errore avviene in funzioni profondamente
-annidate occorre usare quello che viene chiamato un salto \textsl{non-locale};
-questo viene fatto usando salvando il contesto dello stack nel punto in cui si
-vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza capita.
-
-La funzione che permette di salvare il contesto dello stack è \func{setjmp},
-il cui prototipo è:
-
+un'altra funzione, per cui se l'errore avviene in una funzione e la sua
+gestione ordinaria è in un'altra occorre usare quello che viene chiamato un
+\textsl{salto non-locale}.  Il caso classico in cui si ha questa necessità,
+citato sia da \cite{APUE} che da da \cite{glibc}, è quello di un programma nel
+cui corpo principale in cui viene letto un input del quale viene eseguita,
+attraverso una serie di funzioni di analisi, una scansione dei contenuti da cui
+ottenere le indicazioni per l'esecuzione di opportune operazioni.
+
+Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
+in fasi diverse, la rilevazione di un errore nell'input può accadere
+all'interno di funzioni profondamente annidate l'una nell'altra. In questo
+caso si dovrebbe gestire, per ciascuna fase, tutta la casistica del passaggio
+all'indietro di tutti gli errori rilevabili dalle funzioni usate nelle fasi
+successive, mentre sarebbe molto più comodo poter tornare direttamente al
+ciclo di lettura principale, scartando l'input come errato.\footnote{a meno
+  che, come precisa \cite{glibc}, alla chiusura di ciascuna fase non siano
+  associate operazioni di pulizia specifiche (come deallocazioni, chiusure di
+  file, ecc.), che non potrebbero essere eseguite con un salto non-locale.}
+
+Tutto ciò può essere realizzato salvando il contesto dello stack nel punto in
+cui si vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza
+capita. La funzione che permette di salvare il contesto dello stack è
+\func{setjmp}, il cui prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void setjmp(jmp\_buf env)}
   
   Salva il contesto dello stack in \param{env} per un successivo uso da parte
-  di \func{longjmp}. Il contesto viene invalidato se la routine che ha
-  chiamato \func{setjmp} ritorna.
-  
+  di \func{longjmp}. 
+
   \bodydesc{La funzione ritorna zero quando è chiamata direttamente e un
     valore diverso da zero quando ritorna da una chiamata di \func{longjmp}
     che usa il contesto salvato in precedenza.}
 \end{functions}
 
-
-Per poter effettuare un salto non locale si usa la funzione \func{longjmp}; il
-suo prototipo è:
+Quando si esegue la funzione il contesto viene salvato in appositi oggetti (di
+tipo \type{jmp\_buf}), passati come primo argomento alla funzione, in genere
+questi vengono definiti come variabili globali in modo da poter essere visti
+in tutte le funzioni del programma.
+
+Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
+diverso da zero viene restituito solo quando il ritorno è dovuto ad una
+chiamata di \func{longjmp} in un'altra parte del programma. Si tenga conto che
+il contesto salvato in \param{env} viene invalidato se la routine che ha
+chiamato \func{setjmp} ritorna, nel qual caso l'uso di \func{longjmp} può
+comportare conseguenze imprevedibili (e di norma fatali per il processo).
+  
+Come accennato per effettuare un salto non-locale ad un punto precedentemente
+stabilito con \func{setjmp} si usa la funzione \func{longjmp}; il suo
+prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void longjmp(jmp\_buf env, int val)}
   
-  Ripristina il contesto dello stack salvato dall'ultima chiamata di
-  \func{setjmp} con l'argomento \param{env}. Il programma prosegue dal ritorno
-  di \func{setjmp} con un valore \param{val}. Il valore di \param{val} deve
-  essere diverso da zero, se viene specificato 0 sarà usato 1 al suo posto.
-
+  Ripristina il contesto dello stack salvato nell'ultima chiamata di
+  \func{setjmp} con l'argomento \param{env}.
+  
   \bodydesc{La funzione non ritorna.}
 \end{functions}
 
+Dopo l'esecuzione della funzione programma prosegue dal codice successivo al
+ritorno della \func{setjmp} con cui si era salvato \param{env}, che restituirà
+il valore \param{val} invece di zero.  Il valore di \param{val} specificato
+nella chiamata deve essere diverso da zero, se si è specificato 0 sarà
+comunque restituito 1 al suo posto.
+
+In sostanza un \func{longjmp} è analogo ad un \code{return}, solo che invece
+di ritornare alla riga successiva della funzione chiamante, il programma
+ritorna alla posizione della relativa \func{setjmp}, ed il ritorno può essere
+effettuato anche attraverso diversi livelli di funzioni annidate.
+
+L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
+interagiscono direttamente con la gestione dello stack ed il funzionamento del
+compilatore stesso. In particolare \func{setjmp} è implementata con una macro,
+pertanto non si può cercare di ottenerne l'indirizzo, ed inoltre delle
+chiamate a questa funzione sono sicure solo in uno dei seguenti casi:
+\begin{itemize}
+\item come espressione di controllo in un comando condizionale, di selezione
+  o di iterazione (come \code{if}, \code{switch} o \code{while}).
+\item come operando per un operatore di uguaglianza o confronto in una
+  espressione di controllo di un comando condizionale, di selezione o di
+  iterazione.
+\item come operando per l'operatore di negazione (\code{!}) in una espressione
+  di controllo di un comando condizionale, di selezione o di iterazione.
+\item come espressione a sé stante.
+\end{itemize}
+
+In generale, dato che l'unica differenza fra la chiamata diretta e quella
+ottenuta da un \func{longjmp}, è il valore di ritorno di \func{setjmp}, essa è
+usualmente chiamata all'interno di un comando \code{if}. 
+
+Uno dei punti critici dei salti non-locali è quello del valore delle
+variabili, ed in particolare quello delle variabili automatiche della funzione
+a cui si ritorna. In generale le variabili globali e statiche mantengono i
+valori che avevano al momento della chiamata di \func{longjmp}, ma quelli
+delle variabili automatiche (o di quelle dichiarate \code{register}) sono in
+genere indeterminati.
+
+Quello che succede infatti è che i valori delle variabili che sono tenute in
+memoria manterranno il valore avuto al momento della chiamata di
+\func{longjmp}, mentre quelli tenuti nei registri del processore (che nella
+chiamata ad un'altra funzioni vengono salvati nel contesto nello stack)
+torneranno al valore avuto al momento della chiamata di \func{setjmp}; per
+questo quando si vuole avere un comportamento coerente si può bloccare
+l'ottimizzazione che porta le variabili nei registri dichiarandole tutte come
+\code{volatile}.
+
+
 
 %%% Local Variables: 
 %%% mode: latex