Correzioni per le footnote e scritta altra roba sui segnali (finite kill e
[gapil.git] / process.tex
index f616206895875a0483c740447ed167e6f10f8def..554f4d6a49c4e7e6a5e23b55fa6b03d43eed38de 100644 (file)
@@ -1,37 +1,37 @@
 \chapter{L'interfaccia base con i processi}
 \label{cha:process_interface}
 
-Come accennato nell'introduzione il processo è l'unità di base con cui un
-sistema unix-like alloca ed utilizza le risorse.  Questo capitolo tratterà
-l'interfaccia base fra il sistema e i processi, come vengono passati i
-parametri, come viene gestita e allocata la memoria, come un processo può
+Come accennato nell'introduzione il \textsl{processo} è l'unità di base con
+cui un sistema unix-like alloca ed utilizza le risorse.  Questo capitolo
+tratterà l'interfaccia base fra il sistema e i processi, come vengono passati
+parametri, come viene gestita e allocata la memoria, come un processo può
 richiedere servizi al sistema e cosa deve fare quando ha finito la sua
 esecuzione. Nella sezione finale accenneremo ad alcune problematiche generiche
 di programmazione.
 
 In genere un programma viene eseguito quando un processo lo fa partire
-eseguendo una funzione della famiglia \func{exec}; torneremo su questo e
-sulla creazione e gestione dei processi nel prossimo capitolo. In questo
+eseguendo una funzione della famiglia \func{exec}; torneremo su questo e sulla
+creazione e gestione dei processi nel prossimo capitolo. In questo
 affronteremo l'avvio e il funzionamento di un singolo processo partendo dal
-punto di vista del programma  che viene messo in esecuzione.
+punto di vista del programma che viene messo in esecuzione.
 
 
 \section{Esecuzione e conclusione di un programma}
 
 Uno dei concetti base di Unix è che un processo esegue sempre uno ed un solo
 programma: si possono avere più processi che eseguono lo stesso programma ma
-ciascun processo vedrà la sua copia del codice (in realtà il kernel fa si che
+ciascun processo vedrà la sua copia del codice (in realtà il kernel fa sì che
 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
+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}.
+  torneremo più avanti.}
 
 
 \subsection{La funzione \func{main}} 
 \label{sec:proc_main}
 
-Quando un programma viene lanciato il kernel esegue unopportuna routine di
+Quando un programma viene lanciato il kernel esegue un'opportuna routine di
 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
@@ -43,7 +43,7 @@ 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 iniziale l'esecuzione; in ogni caso senza questa funzione lo stesso
+si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso
 linker darebbe luogo ad errori.
 
 Lo standard ISO C specifica che la funzione \func{main} può non avere 
@@ -64,7 +64,7 @@ se si vogliono scrivere programmi portabili 
 \label{sec:proc_conclusion}
 
 Normalmente un programma finisce è quando la funzione \func{main} ritorna, una
-modalità equivalente di concludere il programma è quella di chiamare
+modalità equivalente di chiudere il programma è quella di chiamare
 direttamente la funzione \func{exit} (che viene comunque chiamata
 automaticamente quando \func{main} ritorna).  Una forma alternativa è quella
 di chiamare direttamente la system call \func{\_exit}, che restituisce il
@@ -77,8 +77,8 @@ 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
-\textit{exit status}) e passato al processo padre che aveva lanciato il
-programma (in genere la shell). In generale si usa questo valore per fornire
+\textit{exit status}) e passato al processo che aveva lanciato il programma
+(in genere la shell). In generale si usa questo valore per fornire
 informazioni sulla riuscita o il fallimento del programma; l'informazione è
 necessariamente generica, ed il valore deve essere compreso fra 0 e 255.
 
@@ -92,7 +92,7 @@ della funzione \func{main} senza ritornare esplicitamente si ha un valore di
 uscita indefinito, è pertanto consigliabile di concludere sempre in maniera
 esplicita detta funzione.
 
-Unaltra convenzione riserva i valori da 128 a 256 per usi speciali: ad
+Un'altra convenzione riserva i valori da 128 a 256 per usi speciali: ad
 esempio 128 viene usato per indicare l'incapacità di eseguire un altro
 programma in un sottoprocesso. Benché questa convenzione non sia
 universalmente seguita è una buona idea tenerne conto.
@@ -114,9 +114,9 @@ valori di tipo \type{int} 0 e 1.
 \subsection{Le funzioni \func{exit} e \func{\_exit}}
 \label{sec:proc_exit}
 
-Come accennato le funzioni usate per effettuare unuscita ``normale'' da un
+Come accennato le funzioni usate per effettuare un'uscita ``normale'' da un
 programma sono due, la prima è la funzione \func{exit} che è definita dallo
-standard ANSI C; ed il cui prototipo è:
+standard ANSI C ed il cui prototipo è:
 \begin{prototype}{stdlib.h}{void exit(int status)}
   Causa la conclusione ordinaria del programma restituendo il valore
   \var{status} al processo padre.
@@ -145,7 +145,7 @@ non vengono salvati e le eventuali funzioni registrate con \func{atexit} e
 
 La funzione chiude tutti i file descriptor appartenenti al processo (si tenga
 presente che questo non comporta il salvataggio dei dati bufferizzati degli
-stream), fa si che ogni figlio del processo sia ereditato da \cmd{init} (vedi
+stream), fa sì che ogni figlio del processo sia ereditato da \cmd{init} (vedi
 \secref{cha:process_handling}), manda un segnale \macro{SIGCHLD} al processo
 padre (vedi \secref{sec:sig_job_control}) ed infine ritorna lo stato di uscita
 specificato in \param{status} che può essere raccolto usando la funzione
@@ -155,11 +155,11 @@ specificato in \param{status} che pu
 \subsection{Le funzioni \func{atexit} e \func{on\_exit}}
 \label{sec:proc_atexit}
 
-Unesigenza comune che si incontra nella programmazione è quella di dover
+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 una
-apposita sezione del programma, ma quando si realizza una libreria diventa
+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.
 
@@ -179,10 +179,10 @@ pu
 \end{prototype}
 \noindent la funzione richiede come argomento l'indirizzo della opportuna
 funzione di pulizia da chiamare all'uscita, che non deve prendere argomenti e
-non deve ritornare niente (deve essere essere cioè definita come \func{void
+non deve ritornare niente (deve essere essere cioè definita come \code{void
   function(void)}).
 
-Unestensione di \func{atexit} è la funzione \func{on\_exit}, che le
+Un'estensione di \func{atexit} è la funzione \func{on\_exit}, che le
 \acr{glibc} includono per compatibilità con SunOS, ma che non è detto sia
 definita su altri sistemi; il suo prototipo è:
 \begin{prototype}{stdlib.h}
@@ -253,11 +253,11 @@ 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}m che consiste nell'assegnare ad ogni
+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
+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}.
+  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
@@ -278,12 +278,12 @@ diverse pagine di memoria virtuale appartenenti a processi diversi (come
 accade in genere per le pagine che contengono il codice delle librerie
 condivise). Ad esempio il codice della funzione \func{printf} starà su una
 sola pagina di memoria reale che farà da supporto a tutte le pagine di memoria
-virtuale di tutti i processi hanno detta funzione nel loro codice. 
+virtuale di tutti i processi che hanno detta funzione nel loro codice.
 
 La corrispondenza fra le pagine della memoria virtuale e quelle della memoria
 fisica della macchina viene gestita in maniera trasparente dall'hardware di
 gestione della memoria (la \textit{Memory Management Unit} del processore).
-Poiché in genere quest'ultima è solo una piccola frazione della memoria
+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
@@ -291,7 +291,7 @@ 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 uninterruzione e passa il controllo al kernel
+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.
@@ -317,8 +317,8 @@ una parte di essi 
 tentativo di accedere ad un indirizzo non allocato è un tipico errore che si
 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 unassociazione della pagina
-virtuale il kernel risponde al relativo \textit{page fault}, mandando un
+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.
 
@@ -354,15 +354,16 @@ programma C viene suddiviso nei seguenti segmenti:
   specificati.
   
   La seconda parte è il segmento dei dati non inizializzati, che contiene le
-  variabili il cui valore è stato non è assegnato esplicitamente. Ad esempio
-  se si definisce:
+  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}
-  questo valore sarà immagazzinato in questo segmento. Anch'esso viene
-  allocato all'avvio, e tutte le variabili vengono inizializzate a
-  zero (ed i puntatori a \macro{NULL}). 
-  
+  questo vettore sarà immagazzinato in questo segmento. Anch'esso viene
+  allocato all'avvio, e tutte le variabili vengono inizializzate a zero (ed i
+  puntatori a \macro{NULL}).\footnote{si ricordi che questo vale solo per le
+    variabili che vanno nel segmento dati, e non è affatto vero in generale.}
+   
   Storicamente questo segmento viene chiamato BBS (da \textit{block started by
     symbol}). La sua dimensione è fissa.
   
@@ -379,7 +380,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.
+  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.}
   
   La dimensione di questo segmento aumenta seguendo la crescita dello stack
   del programma, ma non viene ridotta quando quest'ultimo si restringe.
@@ -476,8 +480,8 @@ multipli di 8 byte.
 In genere su usano le funzioni \func{malloc} e \func{calloc} per allocare
 dinamicamente la memoria necessaria al programma, e siccome i puntatori
 ritornati sono di tipo generico non è necessario effettuare un cast per
-assegnarli a puntatori al tipo di variabile per la quale si effettua la
-allocazione.
+assegnarli a puntatori al tipo di variabile per la quale si effettua
+l'allocazione.
 
 La memoria allocata dinamicamente deve essere esplicitamente rilasciata usando
 \func{free}\footnote{le glibc provvedono anche una funzione \func{cfree}
@@ -491,20 +495,20 @@ 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
 spazio aggiunto non viene inizializzato.
 
 Si deve sempre avere ben presente il fatto che il blocco di memoria restituito
-da \func{realloc} può non essere unestensione di quello che gli si è passato
+da \func{realloc} può non essere un'estensione di quello che gli si è passato
 in ingresso; per questo si dovrà \emph{sempre} eseguire la riassegnazione di
 \var{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere
 ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del
@@ -517,13 +521,13 @@ assegnare sempre a \macro{NULL} ogni puntatore liberato con \func{free}, dato
 che, quando il parametro è un puntatore nullo, \func{free} non esegue nessuna
 operazione.
 
-Le \acr{glibc} hanno unimplementazione delle routine di allocazione che è
+Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è
 controllabile dall'utente attraverso alcune variabili di ambiente, in
 particolare diventa possibile tracciare questo tipo di errori usando la
 variabile \macro{MALLOC\_CHECK\_} che quando viene definita mette in uso una
-versione meno efficiente delle funzioni, che però è più tollerante nei
-confronti di piccoli errori come quello di chiamate doppie a \func{free}; in
-particolare:
+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}
@@ -533,32 +537,36 @@ particolare:
 \end{itemize*}
 
 Il problema più comune e più difficile da risolvere che si incontra con le
-routines di allocazione è quando non viene opportunamente liberata la memoria
+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}).
 
-Un caso tipico che illustra il problema è quello in cui l'allocazione di una
-variabile viene fatta da una subroutine per un uso locale, ma la memoria non
-viene liberata; la funzione esce e la memoria resta allocata.  Chiamate
-ripetute alla stessa subroutine continueranno ad allocarne ancora, causando a
-lungo andare un esaurimento della memoria disponibile e l'impossibilità di
-proseguire il programma. Il problema è che l'esaurimento che può avvenire in
-qualunque momento, e senza nessuna relazione con la subroutine che contiene
-l'errore, per questo motivo è sempre complesso trovare un \textit{memory
-  leak}.
+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).
+
+Il problema è che l'esaurimento della memoria può avvenire in qualunque
+momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può
+essere in una sezione del codice che non ha alcuna relazione con la subroutine
+che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
+\textit{memory leak}.
 
 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
-\textsl{ganci} che permettono di sostituire alle funzioni di libreria una
-propria versione (che può essere più o meno specializzata per il debugging).
+\textit{hook} (\textsl{ganci}) che permettono di sostituire alle funzioni di
+libreria una propria versione (che può essere più o meno specializzata per il
+debugging).
 
 
 \subsection{La funzione \func{alloca}}  
 \label{sec:proc_mem_alloca}
 
-Una alternativa possibile all'uso di \func{malloc}, che non soffre dei di
+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
@@ -576,7 +584,7 @@ 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 readice i problemi di memory leak, dato che non serve più la
+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}).
@@ -585,7 +593,7 @@ Un altro vantaggio 
 \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
-nella allocazione della memoria che nella esecuzione della allocazione.
+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
@@ -660,17 +668,18 @@ 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 se non è sensibile al tempo che occorre a
-  riportare la pagina in memoria; per questo motivi processi critici che hanno
-  esigenze di tempo reale o tolleranze critiche nella risposte (ad esempio
+  se il programma in esecuzione non è sensibile al tempo che occorre a
+  riportare la pagina in memoria; per questo motivo processi critici che hanno
+  esigenze di tempo reale o tolleranze critiche nelle risposte (ad esempio
   processi che trattano campionamenti sonori) possono non essere in grado di
   sopportare le variazioni della velocità di accesso dovuta alla paginazione.
-
+  
   In certi casi poi un programmatore può conoscere meglio dell'algoritmo di
   allocazione delle pagine le esigenze specifiche del suo programma e decidere
   quali pagine di memoria è opportuno che restino in memoria per un aumento
   delle prestazioni. In genere queste sono esigenze particolari e richiedono
-  anche un aumento delle priorità in esecuzione (vedi \secref{sec:xxx_xxx}).
+  anche un aumento delle priorità in esecuzione del processo (vedi
+  \secref{sec:proc_real_time}).
   
 \item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro
   in memoria queste possono essere portate su disco dal meccanismo della
@@ -697,14 +706,15 @@ memoria bloccata non la sblocca. Chiaramente la terminazione del processo
 comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
 tutti i suoi \textit{memory lock}.
 
-I \textit{memory lock} non sono ereditati dai processi figli\footnote{ma
-  siccome Linux usa il copy on write 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 dei 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 sue
-pagine.
+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.
 
 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
@@ -776,10 +786,16 @@ 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 copy
-on write.  In genere questo si fa chiamando una funzione che ha allocato una
-quantità sufficiente ampia di variabili automatiche, in modo che esse vengano
-mappate in RAM dallo stack, e poi ci scrive sopra.
+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.
+
+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 stack, dopo di che, per essere sicuri
+che esse siano state effettivamente portate in memoria, ci si scrive sopra.
 
 
 
@@ -796,9 +812,9 @@ messo in esecuzione.
 Oltre al passaggio dei parametri, un'altra modalità che permette di passare
 delle informazioni che modifichino il comportamento di un programma è quello
 dell'uso del cosiddetto \textit{environment} (cioè l'uso delle
-\textsl{varibili di ambiente}). In questa sezione esamineremo le funzioni che
+\textsl{variabili di ambiente}). In questa sezione esamineremo le funzioni che
 permettono di gestire parametri e opzioni, e quelle che consentono di
-manipolare ed utilizzare le varibili di ambiente.
+manipolare ed utilizzare le variabili di ambiente.
 
 
 \subsection{Il formato dei parametri}
@@ -841,10 +857,10 @@ ed \cmd{-m} e la prima vuole un parametro mentre la seconda no
 \cmd{-m}).
 
 Per gestire le opzioni all'interno dei argomenti a linea di comando passati in
-\func{argv} le librerie standard del C forniscono la funzione \func{getopt}
+\var{argv} le librerie standard del C forniscono la funzione \func{getopt}
 che ha il seguente prototipo:
 \begin{prototype}{unistd.h}
-{int getopt(int argc, char * const argv[], const char * optstring)}
+{int getopt(int argc, char *const argv[], const char *optstring)}
 Esegue il parsing degli argomenti passati da linea di comando
 riconoscendo le possibili opzioni segnalate con \var{optstring}.
 
@@ -856,7 +872,7 @@ riconoscendo le possibili opzioni segnalate con \var{optstring}.
 Questa funzione prende come argomenti le due variabili \var{argc} e \var{argv}
 passate a \func{main} ed una stringa che indica quali sono le opzioni valide;
 la funzione effettua la scansione della lista degli argomenti ricercando ogni
-stringa che comincia con \cmd{-} e ritorna ogni volta che trova unopzione
+stringa che comincia con \cmd{-} e ritorna ogni volta che trova un'opzione
 valida.
 
 La stringa \var{optstring} indica quali sono le opzioni riconosciute ed è
@@ -912,9 +928,9 @@ elementi di \var{argv} che cominciano con il carattere \texttt{'-'}.
 
 Quando la funzione trova un'opzione essa ritorna il valore numerico del
 carattere, in questo modo si possono eseguire azioni specifiche usando uno
-\func{switch}; \func{getopt} inoltre inizializza alcune variabili globali:
+\code{switch}; \func{getopt} inoltre inizializza alcune variabili globali:
 \begin{itemize*}
-\item \var{char * optarg} contiene il puntatore alla stringa parametro
+\item \var{char *optarg} contiene il puntatore alla stringa parametro
   dell'opzione.
 \item \var{int optind} alla fine della scansione restituisce l'indice del
   primo elemento di \var{argv} che non è un'opzione.
@@ -931,13 +947,13 @@ 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 una opportuna azione, ad esempio per
+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 a linea di
-comando restanti.
+\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
@@ -1042,7 +1058,7 @@ anche altre: per una lista pi
     \macro{BROWSER} & $\bullet$ & $\bullet$ & $\bullet$ & Browser di default\\
     \hline
   \end{tabular}
-  \caption{Variabile di ambiente più comuni definite da vari standard}
+  \caption{Variabili di ambiente più comuni definite da vari standard.}
   \label{tab:proc_env_var}
 \end{table}
 
@@ -1128,14 +1144,14 @@ 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
-\func{string}. Si tenga presente che, seguendo lo standard SUSv2, le
+\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
   \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 \type{const} dal prototipo.} \func{string} alla lista delle
+  l'attributo \type{const} dal prototipo.} \param{string} alla lista delle
 variabili di ambiente; pertanto ogni cambiamento alla stringa in questione si
 riflette automaticamente sull'ambiente, e quindi si deve evitare di passare a
 questa funzione una variabile automatica (per evitare i problemi esposti in
@@ -1143,13 +1159,16 @@ 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
-\var{=}) 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 una allocazione fatta in
-precedenza da un'altra \func{putenv}, il vettore originale (in genere piazzato
-al di sopra dello stack, vedi \figref{fig:proc_mem_layout}), o la memoria
-associata alle variabili di ambiente eliminate non viene comunque liberata.
+\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
+liberata.
 
 
 \section{Problematiche di programmazione generica}
@@ -1160,7 +1179,7 @@ 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 se stanti, le riportiamo qui.
+entità a sé stanti, le riportiamo qui.
 
 
 \subsection{Il passaggio delle variabili e dei valori di ritorno}
@@ -1245,8 +1264,8 @@ inoltre che l'ultimo degli argomenti fissi sia di tipo
   per compatibilità; ad esempio i tipi \type{float} vengono convertiti
   automaticamente a \type{double} ed i \type{char} e gli \type{short} ad
   \type{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
-  a se stesso.} il che esclude array, puntatori a funzioni e interi di tipo
-\type{char} o \type{short} (con segno o meno). Una ulteriore restrizione di
+  a sé stesso.} il che esclude array, puntatori a funzioni e interi di tipo
+\type{char} o \type{short} (con segno o meno). Una restrizione ulteriore di
 alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
 \type{register}.
 
@@ -1271,7 +1290,7 @@ in generale 
 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} poi l'uso della macro
+otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro
 \macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per
 compatibilità.
 
@@ -1321,11 +1340,11 @@ motivo \macro{va\_list} 
 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 ulteriore macro che permette di
-eseguire la copia di un puntatore alla lista degli argomenti:
+  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{desc}.
+  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
@@ -1341,7 +1360,7 @@ In Linux gli argomenti dello stesso tipo sono passati allo stesso modo, sia
 che siano fissi sia che siano opzionali (alcuni sistemi trattano diversamente
 gli opzionali), ma dato che il prototipo non può specificare il tipo degli
 argomenti opzionali, questi verranno sempre promossi, pertanto nella ricezione
-dei medesimi ocoorrerà tenerne conto (ad esempio un \type{char} verrà visto da
+dei medesimi occorrerà tenerne conto (ad esempio un \type{char} verrà visto da
 \macro{va\_arg} come \type{int}).
 
 
@@ -1373,7 +1392,7 @@ 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 necessirio utilizzare variabili che possano essere viste
+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 \type{static} o \type{extern}), o
 dinamicamente con una delle funzioni della famiglia \func{malloc}.
@@ -1382,10 +1401,12 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}.
 \label{sec:proc_longjmp}
 
 Il controllo del flusso di un programma in genere viene effettuato con le
-varie istruzioni del linguaggio C, la più bistrattata delle quali è il
-\func{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste
-però un caso in l'uso di questa istruzione porta all'implementazione più
-efficiente, quello dell'uscita in caso di errore.
+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 funzioni profondamente
@@ -1393,7 +1414,6 @@ 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 è:
 
@@ -1425,3 +1445,8 @@ suo prototipo 
   \bodydesc{La funzione non ritorna.}
 \end{functions}
 
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: