Correzioni multiple da Daniele Masini
[gapil.git] / process.tex
index a574eb3bca402bdd43b1c709a53a5b1f1cad6d73..935f34e5f6c67f14f4b7d3dc87781408e0e4345d 100644 (file)
@@ -1,26 +1,26 @@
 \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
@@ -31,7 +31,7 @@ tutti gli altri\footnote{questo non 
 \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 
@@ -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.
 
@@ -182,7 +182,7 @@ funzione di pulizia da chiamare all'uscita, che non deve prendere argomenti e
 non deve ritornare niente (deve essere essere cioè definita come \code{void
   function(void)}).
 
-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,7 +253,7 @@ 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
   kernel 2.2 detto massimo era, per macchine a 32bit, di 2Gb, con il kernel
@@ -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.
   
@@ -476,8 +477,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}
@@ -504,7 +505,7 @@ 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 +518,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}
@@ -539,26 +540,27 @@ non pi
 
 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}.
+viene liberata; la funzione esce e la memoria resta allocata (fino alla
+terminazione del processo).  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}.
 
 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
@@ -585,7 +587,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 +662,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 +700,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 +780,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.
 
 
 
@@ -856,7 +866,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 è
@@ -931,13 +941,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 +1052,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}
 
@@ -1135,7 +1145,7 @@ invece esiste il suo valore sar
   seguendo il comportamento di BSD4.4; dato che questo può dar luogo a perdite
   di memoria e non rispetta lo standard. Il comportamento è stato modificato a
   partire dalle 2.1.2, eliminando anche, sempre in conformità a SUSv2,
-  l'attributo \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 +1153,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
-\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 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}
@@ -1246,7 +1259,7 @@ inoltre che l'ultimo degli argomenti fissi sia di tipo
   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). Unulteriore restrizione di
+\type{char} o \type{short} (con segno o meno). Un'ulteriore restrizione di
 alcuni compilatori è di non dichiarare l'ultimo parametro fisso come
 \type{register}.
 
@@ -1321,7 +1334,7 @@ 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 unulteriore macro che permette di
+  in una bozza dello standard} ha previsto un'ulteriore macro 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