Una lunga serie di modifiche per tenere conto della riorganizzazione della
[gapil.git] / process.tex
index d3e98e435f9a2e6df9fbd963e085c3f9bfb4088f..831c6482e8e4b096847d7bf8a392d1b9225cba85 100644 (file)
@@ -1,6 +1,6 @@
 %% process.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2003 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -46,22 +46,20 @@ avvio, usando il programma \cmd{ld-linux.so}.  Questo programma prima carica
 le librerie condivise che servono al programma, poi effettua il link dinamico
 del codice e alla fine lo esegue. Infatti, a meno di non aver specificato il
 flag \texttt{-static} durante la compilazione, tutti i programmi in Linux sono
-incompleti e necessitano di essere linkati alle librerie condivise quando
-vengono avviati.  La procedura è controllata da alcune variabili di ambiente e
-dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati nella man
-page di \cmd{ld.so}.
+incompleti e necessitano di essere \textit{linkati} alle librerie condivise
+quando vengono avviati.  La procedura è controllata da alcune variabili di
+ambiente e dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati
+nella man page di \cmd{ld.so}.
 
 Il sistema fa partire qualunque programma chiamando la funzione \func{main};
 sta al programmatore chiamare così la funzione principale del programma da cui
 si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso
-linker darebbe luogo ad errori.
+\textit{linker} darebbe luogo ad errori.
 
 Lo standard ISO C specifica che la funzione \func{main} può non avere 
 argomenti o prendere due argomenti che rappresentano gli argomenti passati da
 linea di comando, in sostanza un prototipo che va sempre bene è il seguente:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    int main (int argc, char *argv[])
-\end{lstlisting}
+\includecodesnip{listati/main_def.c}
 
 In realtà nei sistemi Unix esiste un'altro modo per definire la funzione
 \func{main}, che prevede la presenza di un terzo parametro, \code{char
@@ -80,10 +78,10 @@ automaticamente quando \func{main} ritorna).  Una forma alternativa 
 di chiamare direttamente la system call \func{\_exit}, che restituisce il
 controllo direttamente alla routine di conclusione dei processi del kernel.
 
-Oltre alla conclusione ``normale'' esiste anche la possibilità di una
-conclusione ``anomala'' del programma a causa della ricezione di un segnale
-(si veda \capref{cha:signals}) o della chiamata alla funzione \func{abort};
-torneremo su questo in \secref{sec:proc_termination}.
+Oltre alla conclusione ``\textsl{normale}'' esiste anche la possibilità di una
+conclusione ``\textsl{anomala}'' del programma a causa della ricezione di un
+segnale (si veda \capref{cha:signals}) o della chiamata alla funzione
+\func{abort}; torneremo su questo in \secref{sec:proc_termination}.
 
 Il valore di ritorno della funzione \func{main}, o quello usato nelle chiamate
 ad \func{exit} e \func{\_exit}, viene chiamato \textsl{stato di uscita} (o
@@ -124,9 +122,9 @@ valori di tipo \ctyp{int} 0 e 1.
 \subsection{Le funzioni \func{exit} e \func{\_exit}}
 \label{sec:proc_exit}
 
-Come accennato le funzioni usate per effettuare un'uscita ``normale'' da un
-programma sono due, la prima è la funzione \funcd{exit}, che è definita dallo
-standard ANSI C ed il cui prototipo è:
+Come accennato le funzioni usate per effettuare un'uscita ``\textit{normale}''
+da un programma sono due, la prima è la funzione \funcd{exit}, che è definita
+dallo standard ANSI C ed il cui prototipo è:
 \begin{prototype}{stdlib.h}{void exit(int status)}
   Causa la conclusione ordinaria del programma.
 
@@ -175,9 +173,9 @@ pulizia al programmatore che la utilizza.
 all'utente, avere la possibilità di effettuare automaticamente la chiamata ad
 una funzione che effettui tali operazioni all'uscita dal programma. A questo
 scopo lo standard ANSI C prevede la possibilità di registrare un certo numero
-funzioni che verranno eseguite all'uscita dal programma (sia per la chiamata
-ad \func{exit} che per il ritorno di \func{main}). La prima funzione che si
-può utilizzare a tal fine è \funcd{atexit} il cui prototipo è:
+di funzioni che verranno eseguite all'uscita dal programma (sia per la
+chiamata ad \func{exit} che per il ritorno di \func{main}). La prima funzione
+che si può utilizzare a tal fine è \funcd{atexit} il cui prototipo è:
 \begin{prototype}{stdlib.h}{void atexit(void (*function)(void))}
   Registra la funzione \param{function} per la chiamata all'uscita dal
   programma.
@@ -187,8 +185,8 @@ pu
 \end{prototype}
 \noindent la funzione richiede come argomento l'indirizzo di una opportuna
 funzione di pulizia da chiamare all'uscita del programma, che non deve
-prendere argomenti e non deve ritornare niente (deve essere essere cioè
-definita come \code{void function(void)}).
+prendere argomenti e non deve ritornare niente (deve essere cioè definita come
+\code{void function(void)}).
 
 Un'estensione di \func{atexit} è la funzione \funcd{on\_exit}, che le
 \acr{glibc} includono per compatibilità con SunOS, ma che non è detto sia
@@ -358,9 +356,7 @@ seguenti segmenti:
   La prima parte è il segmento dei dati inizializzati, che contiene le
   variabili il cui valore è stato assegnato esplicitamente. Ad esempio
   se si definisce:
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    double pi = 3.14;
-  \end{lstlisting}
+\includecodesnip{listati/pi.c}
   questo valore sarà immagazzinato in questo segmento. La memoria di questo
   segmento viene preallocata all'avvio del programma e inizializzata ai valori
   specificati.
@@ -368,9 +364,7 @@ seguenti segmenti:
   La seconda parte è il segmento dei dati non inizializzati, che contiene le
   variabili il cui valore non è stato assegnato esplicitamente. Ad esempio se
   si definisce:
-  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-    int vect[100];
-  \end{lstlisting}
+\includecodesnip{listati/vect.c}
   questo vettore sarà immagazzinato in questo segmento. Anch'esso viene
   allocato all'avvio, e tutte le variabili vengono inizializzate a zero (ed i
   puntatori a \val{NULL}).\footnote{si ricordi che questo vale solo per le
@@ -392,10 +386,10 @@ seguenti segmenti:
   del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la
   funzione chiamata alloca qui lo spazio per le sue variabili locali: in
   questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
-  della funzione lo spazio è automaticamente rilasciato 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.}
+  della funzione lo spazio è automaticamente rilasciato e
+  ``\textsl{ripulito}''. La pulizia in C e C++ viene fatta dal
+  chiamante.\footnote{a meno che non sia stato specificato l'utilizzo di una
+    calling convention diversa da quella standard.}
   
   La dimensione di questo segmento aumenta seguendo la crescita dello stack
   del programma, ma non viene ridotta quando quest'ultimo si restringe.
@@ -531,7 +525,7 @@ in ingresso; per questo si dovr
 ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del
 blocco di dati ridimensionato.
 
-Un errore abbastanza frequente (specie se si ha a che fare con array di
+Un errore abbastanza frequente (specie se si ha a che fare con vettori di
 puntatori) è quello di chiamare \func{free} più di una volta sullo stesso
 puntatore; per evitare questo problema una soluzione di ripiego è quella di
 assegnare sempre a \val{NULL} ogni puntatore liberato con \func{free}, dato
@@ -541,7 +535,7 @@ operazione.
 Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è
 controllabile dall'utente attraverso alcune variabili di ambiente, in
 particolare diventa possibile tracciare questo tipo di errori usando la
-variabile d'ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in
+variabile dambiente \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:
@@ -555,8 +549,8 @@ tollerante nei confronti di piccoli errori come quello di chiamate doppie a
 
 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è una \textsl{perdita di memoria}.
+non più utilizzata, quello che in inglese viene chiamato \textit{memory
+  leak}\index{memory leak}, cioè una \textsl{perdita di memoria}.
 
 Un caso tipico che illustra il problema è quello in cui in una subroutine si
 alloca della memoria per uso locale senza liberarla prima di uscire. La
@@ -569,7 +563,7 @@ Il problema 
 momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
 essere in una sezione del codice che non ha alcuna relazione con la subroutine
 che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
-\textit{memory leak}.
+\textit{memory leak}\index{memory leak}.
 
 In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
 programmazione ad oggetti, il problema dei \textit{memory leak} è notevolmente
@@ -615,10 +609,10 @@ molto complesse riguardo l'allocazione della memoria.
 \label{sec:proc_mem_alloca}
 
 Una possibile alternativa all'uso di \func{malloc}, che non soffre dei
-problemi di \textit{memory leak} descritti in precedenza, è la funzione
-\funcd{alloca}, che invece di allocare la memoria nello heap usa il segmento
-di stack della funzione corrente. La sintassi è identica a quella di
-\func{malloc}, il suo prototipo è:
+problemi di \textit{memory leak}\index{memory leak} descritti in precedenza, è
+la funzione \funcd{alloca}, che invece di allocare la memoria nello heap usa
+il segmento di stack della funzione corrente. La sintassi è identica a quella
+di \func{malloc}, il suo prototipo è:
 \begin{prototype}{stdlib.h}{void *alloca(size\_t size)}
   Alloca \param{size} byte nello stack.
   
@@ -634,10 +628,10 @@ quindi non esiste un analogo della \func{free}) in quanto essa viene
 rilasciata automaticamente al ritorno della funzione.
 
 Come è evidente questa funzione ha molti vantaggi, anzitutto permette di
-evitare alla radice i problemi di memory leak, dato che non serve più la
-deallocazione esplicita; inoltre la deallocazione automatica funziona anche
-quando si usa \func{longjmp} per uscire da una subroutine con un salto non
-locale da una funzione (vedi \secref{sec:proc_longjmp}).
+evitare alla radice i problemi di memory leak\index{memory leak}, dato che non
+serve più la deallocazione esplicita; inoltre la deallocazione automatica
+funziona anche quando si usa \func{longjmp} per uscire da una subroutine con
+un salto non locale da una funzione (vedi \secref{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
@@ -682,7 +676,7 @@ prima funzione 
     fallimento, nel qual caso \var{errno} assumerà il valore \errval{ENOMEM}.}
 \end{prototype}
 
-La funzione è un'interfaccia diretta all'ominima system call ed imposta
+La funzione è un'interfaccia diretta all'omonima system call ed imposta
 l'indirizzo finale del segmento dati di un processo all'indirizzo specificato
 da \param{end\_data\_segment}. Quest'ultimo deve essere un valore ragionevole,
 ed inoltre la dimensione totale del segmento non deve comunque eccedere un
@@ -691,7 +685,7 @@ dimensioni massime dello spazio dati del processo.
 
 La seconda funzione per la manipolazione delle dimensioni del segmento
 dati\footnote{in questo caso si tratta soltanto di una funzione di libreria, e
-  non di una sistem call.} è \funcd{sbrk}, ed il suo prototipo è:
+  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.
   
@@ -815,12 +809,12 @@ prototipi sono:
 \end{functions}
 
 Le due funzioni permettono rispettivamente di bloccare e sbloccare la
-paginazione per l'intervallo di memoria specificato dagli argomenti, che ne
-indicano nell'ordine l'indirizzo iniziale e la lunghezza.  Tutte le pagine che
-contengono una parte dell'intervallo sono mantenute in RAM per tutta la durata
-del blocco.
+paginazione\index{paginazione} per l'intervallo di memoria specificato dagli
+argomenti, che ne indicano nell'ordine l'indirizzo iniziale e la lunghezza.
+Tutte le pagine che contengono una parte dell'intervallo bloccato sono
+mantenute in RAM per tutta la durata del blocco.
 
-Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono poi di
+Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono di
 bloccare genericamente la paginazione\index{paginazione} per l'intero spazio
 di indirizzi di un processo.  I prototipi di queste funzioni sono:
 \begin{functions}
@@ -842,25 +836,25 @@ 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 saranno mappate nello
+\item[\const{MCL\_FUTURE}] blocca tutte le pagine che verranno mappate nello
   spazio di indirizzi del processo.
 \end{basedescript}
 
-Con \func{mlockall} si può bloccare tutte le pagine mappate nello spazio di
-indirizzi del processo, sia che comprendano il segmento di testo, di dati, lo
-stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
+Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
+di indirizzi del processo, sia che comprendano il segmento di testo, di dati,
+lo stack, lo heap e pure le funzioni di libreria chiamate, i file mappati in
 memoria, i dati del kernel mappati in user space, la memoria condivisa.  L'uso
 dei flag permette di selezionare con maggior finezza le pagine da bloccare, ad
 esempio limitandosi a tutte le pagine allocate a partire da un certo momento.
 
 In ogni caso un processo real-time che deve entrare in una sezione critica
 deve provvedere a riservare memoria sufficiente prima dell'ingresso, per
-scongiurare in partenza un eventuale page fault\index{page fault} causato dal
-meccanismo di \textit{copy on write}\index{copy on write}.  Infatti se nella
-sezione critica si va ad utilizzare memoria che non è ancora stata riportata
-in RAM si potrebbe avere un page fault durante l'esecuzione della stessa, con
-conseguente rallentamento (probabilmente inaccettabile) dei tempi di
-esecuzione.
+scongiurare l'occorrenza di un eventuale \textit{page fault}\index{page fault}
+causato dal meccanismo di \textit{copy on write}\index{copy on write}.
+Infatti se nella sezione critica si va ad utilizzare memoria che non è ancora
+stata riportata in RAM si potrebbe avere un page fault durante l'esecuzione
+della stessa, con conseguente rallentamento (probabilmente inaccettabile) dei
+tempi di esecuzione.
 
 In genere si ovvia a questa problematica chiamando una funzione che ha
 allocato una quantità sufficientemente ampia di variabili automatiche, in modo
@@ -961,37 +955,11 @@ ritornato il carattere \texttt{':'}, infine se viene incontrato il valore
 elementi di \param{argv} che cominciano con il carattere \texttt{'-'}.
 
 \begin{figure}[htb]
-  \footnotesize
-    \begin{lstlisting}{}
-    opterr = 0;  /* don't want writing to stderr */
-    while ( (i = getopt(argc, argv, "hp:c:e:")) != -1) {
-        switch (i) {
-        /* 
-         * Handling options 
-         */ 
-        case 'h':   /* help option */
-            printf("Wrong -h option use\n");
-            usage();
-            return -1;
-            break;
-        case 'c':   /* take wait time for childen */
-            wait_child = strtol(optarg, NULL, 10);    /* convert input */
-            break;
-        case 'p':   /* take wait time for childen */
-            wait_parent = strtol(optarg, NULL, 10);   /* convert input */
-            break;
-        case 'e':   /* take wait before parent exit */
-            wait_end = strtol(optarg, NULL, 10);      /* convert input */
-            break;
-        case '?':   /* unrecognized options */
-            printf("Unrecognized options -%c\n",optopt);
-            usage();
-        default:    /* should not reached */
-            usage();
-        }
-    }
-    debug("Optind %d, argc %d\n",optind,argc);
-  \end{lstlisting}
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+  \includecodesample{listati/option_code.c}
+  \end{minipage}
+  \normalsize
   \caption{Esempio di codice per la gestione delle opzioni.}
   \label{fig:proc_options_code}
 \end{figure}
@@ -1058,18 +1026,16 @@ sistema un \textsl{ambiente}, nella forma di una lista di variabili (detta
 \textit{environment list}) messa a disposizione dal processo, e costruita
 nella chiamata alla funzione \func{exec} quando questo viene lanciato.
 
-Come per la lista dei parametri anche questa lista è un array di puntatori a
+Come per la lista dei parametri anche questa lista è un vettore di puntatori a
 caratteri, ciascuno dei quali punta ad una stringa, terminata da un
 \val{NULL}. A differenza di \code{argv[]} in questo caso non si ha una
-lunghezza dell'array data da un equivalente di \param{argc}, ma la lista è
+lunghezza del vettore data da un equivalente di \param{argc}, ma la lista è
 terminata da un puntatore nullo.
 
 L'indirizzo della lista delle variabili di ambiente è passato attraverso la
 variabile globale \var{environ}, a cui si può accedere attraverso una semplice
 dichiarazione del tipo:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-extern char ** environ;
-\end{lstlisting}
+\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
 \figref{fig:proc_envirno_list}.
@@ -1138,7 +1104,7 @@ controllare \cmd{man environ}.
                                                        temporanei\\
     \hline
   \end{tabular}
-  \caption{Esempi di variabili di ambiente più comuni definite da vari
+  \caption{Esempi delle variabili di ambiente più comuni definite da vari
     standard.} 
   \label{tab:proc_env_var}
 \end{table}
@@ -1180,18 +1146,19 @@ in \tabref{tab:proc_env_func}.
     \func{putenv} &  & opz.  & $\bullet$ & 
         & $\bullet$ & $\bullet$ \\
     \func{clearenv} &  & opz.  &    & 
-        &  &  \\
+        &  &  $\bullet$ \\
     \hline
   \end{tabular}
   \caption{Funzioni per la gestione delle variabili di ambiente.}
   \label{tab:proc_env_func}
 \end{table}
 
-In Linux sono definite solo le prime quattro delle funzioni elencate in
-\tabref{tab:proc_env_func}. La prima, \func{getenv}, l'abbiamo appena
-esaminata; delle tre restanti le prime due, \funcd{putenv} e \funcd{setenv},
-servono per assegnare nuove variabili di ambiente, i loro prototipi sono i
-seguenti:
+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 \tabref{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} 
   
@@ -1253,6 +1220,24 @@ variabili di ambiente iniziale, creato dalla chiamata ad \func{exec} (vedi
 Inoltre la memoria associata alle variabili di ambiente eliminate non viene
 liberata.
 
+L'ultima funzione è \funcd{clearenv}, che viene usata per cancellare
+completamente tutto l'ambiente; il suo prototipo è:
+\begin{functions}
+  \headdecl{stdlib.h}
+  
+  \funcdecl{int clearenv(void)} 
+  Cancella tutto l'ambiente.
+  
+  \bodydesc{la funzione restituisce 0 in caso di successo e un valore diverso
+    da zero per un errore.}
+\end{functions}
+
+In genere si usa questa funzione in maniera precauzionale per evitare i
+problemi di sicurezza connessi nel trasmettere ai programmi che si invocano un
+ambiente che può contenere dei dati non controllati. In tal caso si provvede
+alla cancellazione di tutto l'ambiente per costruirne una versione
+``\textsl{sicura}'' da zero.
+
 
 \section{Problematiche di programmazione generica}
 \label{sec:proc_gen_prog}
@@ -1301,7 +1286,7 @@ funzione chiamante un valore relativo ad uno dei suoi parametri.  Per far
 questo si usa il cosiddetto \textit{value result argument}, si passa cioè,
 invece di una normale variabile, un puntatore alla stessa; vedremo alcuni
 esempi di questa modalità nelle funzioni che gestiscono i socket (in
-\secref{sec:TCPel_functions}), in cui, per permettere al kernel di restituire
+\secref{sec:TCP_functions}), in cui, per permettere al kernel di restituire
 informazioni sulle dimensioni delle strutture degli indirizzi utilizzate,
 viene usato questo meccanismo.
 
@@ -1311,11 +1296,11 @@ viene usato questo meccanismo.
 
 Come vedremo nei capitoli successivi, non sempre è possibile specificare un
 numero fisso di parametri per una funzione.  Lo standard ISO C prevede nella
-sua sintassi la possibilità di definire delle \textit{variadic function} che
-abbiano un numero variabile di argomenti, attraverso l'uso della
-\textit{ellipsis} \code{...} nella dichiarazione della funzione; ma non
-provvede a livello di linguaggio alcun meccanismo con cui dette funzioni
-possono accedere ai loro argomenti.
+sua sintassi la possibilità di definire delle \textit{variadic
+  function}\index{variadic} che abbiano un numero variabile di argomenti,
+attraverso l'uso della \textit{ellipsis} \code{...} nella dichiarazione della
+funzione; ma non provvede a livello di linguaggio alcun meccanismo con cui
+dette funzioni possono accedere ai loro argomenti.
 
 L'accesso viene invece realizzato dalle librerie standard che provvedono gli
 strumenti adeguati.  L'uso delle \textit{variadic function} prevede tre punti:
@@ -1329,14 +1314,12 @@ strumenti adeguati.  L'uso delle \textit{variadic function} prevede tre punti:
   a seguire gli addizionali.
 \end{itemize*}
 
-Lo standard ISO C prevede che una \textit{variadic function} abbia sempre
-almeno un argomento fisso; prima di effettuare la dichiarazione deve essere
-incluso l'apposito header file \file{stdarg.h}; un esempio di dichiarazione è
-il prototipo della funzione \func{execl} che vedremo in
+Lo standard ISO C prevede che una \textit{variadic function}\index{variadic}
+abbia sempre almeno un argomento fisso; prima di effettuare la dichiarazione
+deve essere incluso l'apposito header file \file{stdarg.h}; un esempio di
+dichiarazione è il prototipo della funzione \func{execl} che vedremo in
 \secref{sec:proc_exec}:
-\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
-  int execl(const char *path, const char *arg, ...);
-\end{lstlisting}
+\includecodesnip{listati/exec_sample.c}
 in questo caso la funzione prende due parametri fissi ed un numero variabile
 di altri parametri (che verranno a costituire gli elementi successivi al primo
 del vettore \param{argv} passato al nuovo processo). Lo standard ISO C richiede
@@ -1346,7 +1329,7 @@ inoltre che l'ultimo degli argomenti fissi sia di tipo
   per compatibilità; ad esempio i tipi \ctyp{float} vengono convertiti
   automaticamente a \ctyp{double} ed i \ctyp{char} e gli \ctyp{short} ad
   \ctyp{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
-  a sé stesso.} il che esclude array, puntatori a funzioni e interi di tipo
+  a sé stesso.} il che esclude vettori, puntatori a funzioni e interi di tipo
 \ctyp{char} o \ctyp{short} (con segno o meno). Una restrizione ulteriore di
 alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
 \ctyp{register}.
@@ -1418,12 +1401,13 @@ stack all'indirizzo dove sono stati salvati i parametri, 
 normale pensare di poter effettuare questa operazione.
 
 In generale però possono esistere anche realizzazioni diverse, per questo
-motivo \macro{va\_list} è definito come \textsl{tipo opaco} e non può essere
-assegnato direttamente ad un'altra variabile dello stesso tipo. Per risolvere
-questo problema lo standard ISO C99\footnote{alcuni sistemi che non hanno
-  questa macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome
-  proposto in una bozza dello standard.} ha previsto una macro ulteriore che
-permette di eseguire la copia di un puntatore alla lista degli argomenti:
+motivo \macro{va\_list} è definito come \textsl{tipo opaco}\index{tipo!opaco}
+e non può essere assegnato direttamente ad un'altra variabile dello stesso
+tipo. Per risolvere questo problema lo standard ISO C99\footnote{alcuni
+  sistemi che non hanno questa macro provvedono al suo posto
+  \macro{\_\_va\_copy} che era il nome proposto in una bozza dello standard.}
+ha previsto una macro ulteriore che permette di eseguire la copia di un
+puntatore alla lista degli argomenti:
 \begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
   Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
   su \param{dest}.
@@ -1485,82 +1469,93 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}.
 Il controllo del flusso di un programma in genere viene effettuato con le
 varie istruzioni del linguaggio C; fra queste la più bistrattata è il
 \code{goto}, che viene deprecato in favore dei costrutti della programmazione
-strutturata, che rendono il codice più leggibile e mantenibile . Esiste però
-un caso in cui l'uso di questa istruzione porta all'implementazione più
-efficiente e chiara anche dal punto di vista della struttura del programma:
-quello dell'uscita in caso di errore.
-
-Il C però non consente di effettuare un salto ad una label definita in
-un'altra funzione, per cui se l'errore avviene in una funzione e la sua
-gestione ordinaria è in un'altra occorre usare quello che viene chiamato un
-\textsl{salto non-locale}.  Il caso classico in cui si ha questa necessità,
-citato sia da \cite{APUE} che da da \cite{glibc}, è quello di un programma nel
-cui corpo principale in cui viene letto un input del quale viene eseguita,
-attraverso una serie di funzioni di analisi, una scansione dei contenuti da cui
-ottenere le indicazioni per l'esecuzione di opportune operazioni.
+strutturata, che rendono il codice più leggibile e mantenibile. Esiste però un
+caso in cui l'uso di questa istruzione porta all'implementazione più
+efficiente e più chiara anche dal punto di vista della struttura del
+programma: quello dell'uscita in caso di errore.
+
+Il C però non consente di effettuare un salto ad una etichetta definita in
+un'altra funzione, per cui se l'errore avviene in una funzione, e la sua
+gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un
+\textsl{salto non-locale}\index{salto non-locale}.  Il caso classico in cui si
+ha questa necessità, citato sia da \cite{APUE} che da \cite{glibc}, è quello
+di un programma nel cui corpo principale vengono letti dei dati in ingresso
+sui quali viene eseguita, tramite una serie di funzioni di analisi, una
+scansione dei contenuti da si ottengono le indicazioni per l'esecuzione delle
+opportune operazioni.
 
 Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
-in fasi diverse, la rilevazione di un errore nell'input può accadere
+in fasi diverse, la rilevazione di un errore nei dati in ingresso può accadere
 all'interno di funzioni profondamente annidate l'una nell'altra. In questo
 caso si dovrebbe 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 è
-\funcd{setjmp}, il cui prototipo è:
+successive.  Questo comporterebbe una notevole complessità, mentre sarebbe
+molto più comodo poter tornare direttamente al ciclo di lettura principale,
+scartando l'input come errato.\footnote{a meno che, come precisa \cite{glibc},
+  alla chiusura di ciascuna fase non siano associate operazioni di pulizia
+  specifiche (come deallocazioni, chiusure di file, ecc.), che non potrebbero
+  essere eseguite con un salto non-locale\index{salto non-locale}.}
+
+Tutto ciò può essere realizzato proprio con un salto non-locale; questo di
+norma viene realizzato salvando il contesto dello stack nel punto in cui si
+vuole tornare in caso di errore, e ripristinandolo, in modo da tornare nella
+funzione da cui si era partiti, quando serve.  La funzione che permette di
+salvare il contesto dello stack è \funcd{setjmp}, il cui prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void setjmp(jmp\_buf env)}
   
-  Salva il contesto dello stack in \param{env} per un successivo uso da parte
-  di \func{longjmp}. 
+  Salva il contesto dello stack. 
 
   \bodydesc{La funzione ritorna zero quando è chiamata direttamente e un
     valore diverso da zero quando ritorna da una chiamata di \func{longjmp}
     che usa il contesto salvato in precedenza.}
 \end{functions}
-
-Quando si esegue la funzione il contesto viene salvato in appositi oggetti (di
-tipo \type{jmp\_buf}), passati come primo argomento alla funzione, in genere
-questi vengono definiti come variabili globali in modo da poter essere visti
-in tutte le funzioni del programma.
+  
+Quando si esegue la funzione il contesto corrente dello stack viene salvato
+nell'argomento \param{env}, una variabile di tipo
+\type{jmp\_buf}\footnote{questo è un classico esempio di variabile di
+  \textsl{tipo opaco}\index{tipo!opaco}. Si definiscono così strutture ed
+  altri oggetti usati da una libreria, la cui struttura interna non deve
+  essere vista dal programma chiamante (da cui il nome) che li devono
+  utilizzare solo attraverso dalle opportune funzioni di gestione.}  che deve
+essere stata definita in precedenza. In genere le variabili di tipo
+\type{jmp\_buf} vengono definite come variabili globali in modo da poter
+essere viste in tutte le funzioni del programma.
 
 Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
 diverso da zero viene restituito solo quando il ritorno è dovuto ad una
-chiamata di \func{longjmp} in un'altra parte del programma. Si tenga conto che
-il contesto salvato in \param{env} viene invalidato se la routine che ha
-chiamato \func{setjmp} ritorna, nel qual caso l'uso di \func{longjmp} può
-comportare conseguenze imprevedibili (e di norma fatali per il processo).
+chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
+stack effettuando il salto non-locale\index{salto non-locale}. Si tenga conto
+che il contesto salvato in \param{env} viene invalidato se la routine che ha
+chiamato \func{setjmp} ritorna, nel qual caso un successivo uso di
+\func{longjmp} può comportare conseguenze imprevedibili (e di norma fatali)
+per il processo.
   
-Come accennato per effettuare un salto non-locale ad un punto precedentemente
-stabilito con \func{setjmp} si usa la funzione \funcd{longjmp}; il suo
-prototipo è:
+Come accennato per effettuare un salto non-locale\index{salto non-locale} ad
+un punto precedentemente stabilito con \func{setjmp} si usa la funzione
+\funcd{longjmp}; il suo prototipo è:
 \begin{functions}
   \headdecl{setjmp.h}
   \funcdecl{void longjmp(jmp\_buf env, int val)}
   
-  Ripristina il contesto dello stack salvato nell'ultima chiamata di
-  \func{setjmp} con l'argomento \param{env}.
+  Ripristina il contesto dello stack.
   
   \bodydesc{La funzione non ritorna.}
 \end{functions}
 
-Dopo l'esecuzione della funzione programma prosegue dal codice successivo al
-ritorno della \func{setjmp} con cui si era salvato \param{env}, che restituirà
-il valore \param{val} invece di zero.  Il valore di \param{val} specificato
-nella chiamata deve essere diverso da zero, se si è specificato 0 sarà
-comunque restituito 1 al suo posto.
+La funzione ripristina il contesto dello stack salvato da una chiamata a
+\func{setjmp} nell'argomento \param{env}. Dopo l'esecuzione della funzione il
+programma prosegue nel codice successivo al ritorno della \func{setjmp} con
+cui si era salvato \param{env}, che restituirà il valore \param{val} invece di
+zero.  Il valore di \param{val} specificato nella chiamata deve essere diverso
+da zero, se si è specificato 0 sarà comunque restituito 1 al suo posto.
 
 In sostanza un \func{longjmp} è analogo ad un \code{return}, solo che invece
 di ritornare alla riga successiva della funzione chiamante, il programma
-ritorna alla posizione della relativa \func{setjmp}, ed il ritorno può essere
-effettuato anche attraverso diversi livelli di funzioni annidate.
+ritorna alla posizione della relativa \func{setjmp}, l'altra differenza è che
+il ritorno può essere effettuato anche attraverso diversi livelli di funzioni
+annidate.
 
 L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
 interagiscono direttamente con la gestione dello stack ed il funzionamento del
@@ -1582,25 +1577,25 @@ 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
+Uno dei punti critici dei salti non-locali\index{salto non-locale} è quello
+del valore delle variabili, ed in particolare quello delle variabili
+automatiche della funzione a cui si ritorna. In generale le variabili globali
+e statiche mantengono i valori che avevano al momento della chiamata di
+\func{longjmp}, ma quelli delle variabili automatiche (o di quelle dichiarate
 \direct{register}\footnote{la direttiva \direct{register} del compilatore
   chiede che la variabile dichiarata tale sia mantenuta, nei limiti del
-  possibile, all'interno di un registro del processore. Questa direttiva
-  origina dai primi compilatori, quando stava al programmatore scrivere codice
-  ottimizzato, riservando esplicitamente alle variabili più usate l'uso dei
-  registri del processore. Oggi questa direttiva oggi è in disuso dato che
-  tutti i compilatori sono normalmente in grado di valutare con maggior
-  efficacia degli stessi programmatori quando sia il caso di eseguire questa
-  ottimizzazione.}) sono in genere indeterminati.
+  possibile, all'interno di un registro del processore. Questa direttiva è
+  originaria dell'epoca dai primi compilatori, quando stava al programmatore
+  scrivere codice ottimizzato, riservando esplicitamente alle variabili più
+  usate l'uso dei registri del processore. Oggi questa direttiva è in disuso
+  dato che tutti i compilatori sono normalmente in grado di valutare con
+  maggior efficacia degli stessi programmatori quando sia il caso di eseguire
+  questa ottimizzazione.}) sono in genere indeterminati.
 
 Quello che succede infatti è che i valori delle variabili che sono tenute in
 memoria manterranno il valore avuto al momento della chiamata di
 \func{longjmp}, mentre quelli tenuti nei registri del processore (che nella
-chiamata ad un'altra funzioni vengono salvati nel contesto nello stack)
+chiamata ad un'altra funzione vengono salvati nel contesto nello stack)
 torneranno al valore avuto al momento della chiamata di \func{setjmp}; per
 questo quando si vuole avere un comportamento coerente si può bloccare
 l'ottimizzazione che porta le variabili nei registri dichiarandole tutte come