Varie correzioni, completata revisione capitolo sull'I/O su file
[gapil.git] / process.tex
index b25c6582a1db27571ba476e832190f6f73807e1c..cb1fa55c6d08085c353b156bc01fab9ba1de09c9 100644 (file)
@@ -1,6 +1,6 @@
 %% process.tex
 %%
-%% Copyright (C) 2000-2015 by Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2019 by 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 "Un preambolo",
@@ -36,7 +36,7 @@ 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. Questo non è del tutto vero nel caso di un programma
 \textit{multi-thread}, ma la gestione dei \textit{thread} in Linux sarà
-trattata a parte in cap.~\ref{cha:threads}.
+trattata a parte\unavref{in cap.~\ref{cha:threads}}.
 
 
 \subsection{L'avvio e l'esecuzione di un programma}
@@ -44,9 +44,9 @@ trattata a parte in cap.~\ref{cha:threads}.
 
 \itindbeg{link-loader}
 \itindbeg{shared~objects}
-Quando un programma viene messo in esecuzione cosa che può essere fatta solo
-con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}) il
-kernel esegue un opportuno codice di avvio, il cosiddetto
+Quando un programma viene messo in esecuzione, cosa che può essere fatta solo
+con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}),
+il kernel esegue un opportuno codice di avvio, il cosiddetto
 \textit{link-loader}, costituito dal programma \cmd{ld-linux.so}. Questo
 programma è una parte fondamentale del sistema il cui compito è quello della
 gestione delle cosiddette \textsl{librerie condivise}, quelle che nel mondo
@@ -64,15 +64,15 @@ una sola volta per tutti i programmi che lo usano.
 Questo significa però che normalmente il codice di un programma è incompleto,
 contenendo solo i riferimenti alle funzioni di libreria che vuole utilizzare e
 non il relativo codice. Per questo motivo all'avvio del programma è necessario
-l'intervento del \textit{link-loader} il cui compito è
-caricare in memoria le librerie condivise eventualmente assenti, ed effettuare
-poi il collegamento dinamico del codice del programma alle funzioni di
-libreria da esso utilizzate prima di metterlo in esecuzione.
+l'intervento del \textit{link-loader} il cui compito è caricare in memoria le
+librerie condivise eventualmente assenti, ed effettuare poi il collegamento
+dinamico del codice del programma alle funzioni di libreria da esso utilizzate
+prima di metterlo in esecuzione.
 
 Il funzionamento di \cmd{ld-linux.so} è controllato da alcune variabili di
-ambiente e dal contenuto del file \conffile{/etc/ld.so.conf}, che consentono
-di elencare le directory un cui cercare le librerie e determinare quali
-verranno utilizzate.  In particolare con la variabile di ambiente
+ambiente e dal contenuto del file \conffile{/etc/ld.so.conf} che consentono di
+elencare le directory un cui cercare le librerie e determinare quali verranno
+utilizzate.  In particolare con la variabile di ambiente
 \envvar{LD\_LIBRARY\_PATH} si possono indicare ulteriori directory rispetto a
 quelle di sistema in cui inserire versioni personali delle librerie che hanno
 la precedenza su quelle di sistema, mentre con la variabile di ambiente
@@ -213,27 +213,28 @@ definizioni.
     & ANSI C& POSIX& \\
     \hline
     \hline
-    \headfile{assert.h}&$\bullet$&    --   & Verifica le asserzioni fatte in un
-                                             programma.\\ 
-    \headfile{ctype.h} &$\bullet$&    --   & Tipi standard.\\
-    \headfile{dirent.h}&   --    &$\bullet$& Manipolazione delle directory.\\
-    \headfile{errno.h} &   --    &$\bullet$& Errori di sistema.\\
-    \headfile{fcntl.h} &   --    &$\bullet$& Controllo sulle opzioni dei file.\\
-    \headfile{limits.h}&   --    &$\bullet$& Limiti e parametri del sistema.\\
-    \headfile{malloc.h}&$\bullet$&    --   & Allocazione della memoria.\\
-    \headfile{setjmp.h}&$\bullet$&    --   & Salti non locali.\\
-    \headfile{signal.h}&   --    &$\bullet$& Gestione dei segnali.\\
-    \headfile{stdarg.h}&$\bullet$&    --   & Gestione di funzioni a argomenti
+    \headfiled{assert.h}&$\bullet$&    --   & Verifica le asserzioni fatte in un
+                                              programma.\\ 
+    \headfiled{ctype.h} &$\bullet$&    --   & Tipi standard.\\
+    \headfiled{dirent.h}&   --    &$\bullet$& Manipolazione delle directory.\\
+    \headfiled{errno.h} &   --    &$\bullet$& Errori di sistema.\\
+    \headfiled{fcntl.h} &   --    &$\bullet$& Controllo sulle opzioni dei
+                                              file.\\ 
+    \headfiled{limits.h}&   --    &$\bullet$& Limiti e parametri del sistema.\\
+    \headfiled{malloc.h}&$\bullet$&    --   & Allocazione della memoria.\\
+    \headfiled{setjmp.h}&$\bullet$&    --   & Salti non locali.\\
+    \headfiled{signal.h}&   --    &$\bullet$& Gestione dei segnali.\\
+    \headfiled{stdarg.h}&$\bullet$&    --   & Gestione di funzioni a argomenti
                                              variabili.\\ 
-    \headfile{stdio.h} &$\bullet$&    --   & I/O bufferizzato in standard ANSI
-                                             C.\\ 
-    \headfile{stdlib.h}&$\bullet$&    --   & Definizioni della libreria
-                                             standard.\\ 
-    \headfile{string.h}&$\bullet$&    --   & Manipolazione delle stringhe.\\
-    \headfile{time.h}  &   --    &$\bullet$& Gestione dei tempi.\\
-    \headfile{times.h} &$\bullet$&    --   & Gestione dei tempi.\\
-    \headfile{unistd.h}&   --    &$\bullet$& Unix standard library.\\
-    \headfile{utmp.h}  &   --    &$\bullet$& Registro connessioni utenti.\\
+    \headfiled{stdio.h} &$\bullet$&    --   & I/O bufferizzato in standard ANSI
+                                              C.\\ 
+    \headfiled{stdlib.h}&$\bullet$&    --   & Definizioni della libreria
+                                              standard.\\ 
+    \headfiled{string.h}&$\bullet$&    --   & Manipolazione delle stringhe.\\
+    \headfiled{time.h}  &   --    &$\bullet$& Gestione dei tempi.\\
+    \headfiled{times.h} &$\bullet$&    --   & Gestione dei tempi.\\
+    \headfiled{unistd.h}&   --    &$\bullet$& Unix standard library.\\
+    \headfiled{utmp.h}  &   --    &$\bullet$& Registro connessioni utenti.\\
     \hline
   \end{tabular}
   \caption{Elenco dei principali \textit{header file} definiti dagli standard
@@ -273,7 +274,7 @@ esempio si avrà che:
   ``\texttt{TC}'' e con ``\texttt{B}'' seguito da un numero,
 \item in \headfile{grp.h} vengono riservati i nomi che iniziano con
   ``\texttt{gr\_}'',
-\item in \headfile{pwd.h}vengono riservati i nomi che iniziano con
+\item in \headfile{pwd.h} vengono riservati i nomi che iniziano con
   ``\texttt{pw\_}'',
 \end{itemize*}
 
@@ -291,18 +292,28 @@ una qualunque funzione ordinaria, la situazione è totalmente diversa
 nell'esecuzione del programma. Una funzione ordinaria infatti viene eseguita,
 esattamente come il codice che si è scritto nel corpo del programma, in
 \textit{user space}. Quando invece si esegue una \textit{system call}
-l'esecuzione ordinaria del programma viene interrotta, i dati forniti (come
-argomenti della chiamata) vengono trasferiti al kernel che esegue il codice
-della \textit{system call} (che è codice del kernel) in \textit{kernel space}.
+l'esecuzione ordinaria del programma viene interrotta con quello che viene
+usualmente chiamato un \itindex{context~switch} \textit{context
+  switch};\footnote{in realtà si parla più comunemente di \textit{context
+    switch} quando l'esecuzione di un processo viene interrotta dal kernel
+  (tramite lo \textit{scheduler}) per metterne in esecuzione un altro, ma il
+  concetto generale resta lo stesso: l'esecuzione del proprio codice in
+  \textit{user space} viene interrotta e lo stato del processo deve essere
+  salvato per poterne riprendere l'esecuzione in un secondo tempo.}  il
+contesto di esecuzione del processo viene salvato in modo da poterne
+riprendere in seguito l'esecuzione ed i dati forniti (come argomenti della
+chiamata) vengono trasferiti al kernel che esegue il codice della
+\textit{system call} (che è codice del kernel) in \textit{kernel space}; al
+completamento della \textit{system call} i dati salvati nel \textit{context
+  switch} saranno usati per riprendere l'esecuzione ordinaria del programma.
 
 Dato che il passaggio dei dati ed il salvataggio del contesto di esecuzione
-del programma che consentirà di riprenderne l'esecuzione ordinaria al
-completamento della \textit{system call} sono operazioni critiche per le
-prestazioni del sistema, per rendere il più veloce possibile questa
-operazione, usualmente chiamata \textit{context switch} sono state sviluppate
-una serie di ottimizzazioni che richiedono alcune preparazioni abbastanza
-complesse dei dati, che in genere dipendono dall'architettura del processore
-sono scritte direttamente in \textit{assembler}.
+sono operazioni critiche per le prestazioni del sistema, per rendere il più
+veloce possibile questa operazione sono state sviluppate una serie di
+ottimizzazioni che richiedono alcune preparazioni abbastanza complesse dei
+dati, che in genere dipendono dall'architettura del processore e sono scritte
+direttamente in \textit{assembler}.
+
 
 %
 % TODO:trattare qui, quando sarà il momento vsyscall e vDSO, vedi:
@@ -324,14 +335,19 @@ associazione, e lavorare a basso livello con una specifica versione, oppure si
 può voler utilizzare una \textit{system call} che non è stata ancora associata
 ad una funzione di libreria.  In tal caso, per evitare di dover effettuare
 esplicitamente le operazioni di preparazione citate, all'interno della
-\textsl{glibc} è fornita una specifica funzione, \funcd{syscall}, che consente
-eseguire direttamente una \textit{system call}; il suo prototipo, accessibile
-se si è definita la macro \macro{\_GNU\_SOURCE}, è:
+\textsl{glibc} è fornita una specifica funzione,
+\funcd{syscall},\footnote{fino a prima del kernel 2.6.18 per l'esecuzione
+  diretta delle \textit{system call} erano disponibili anche una serie di
+  macro \texttt{\_syscall\textsl{N}} (con $N$ pari al numero di argomenti
+  della \textit{system call}); queste sono deprecate e pertanto non ne
+  parleremo ulteriormente.} che consente eseguire direttamente una
+\textit{system call}; il suo prototipo, accessibile se si è definita la macro
+\macro{\_GNU\_SOURCE}, è:
 
 \begin{funcproto}{
   \fhead{unistd.h}
   \fhead{sys/syscall.h}
-  \fdecl{int syscall(int number, ...)}
+  \fdecl{long syscall(int number, ...)}
   \fdesc{Esegue la \textit{system call} indicata da \param{number}.}
 }
 {La funzione ritorna un intero dipendente dalla \textit{system call} invocata,
@@ -352,7 +368,7 @@ dall'architettura,\footnote{in genere le vecchie \textit{system call} non
 ciascuna \textit{system call} viene in genere identificata da una costante
 nella forma \texttt{SYS\_*} dove al prefisso viene aggiunto il nome che spesso
 corrisponde anche alla omonima funzione di libreria. Queste costanti sono
-definite nel file \headfile{sys/syscall.h}, ma si possono anche usare
+definite nel file \headfiled{sys/syscall.h}, ma si possono anche usare
 direttamente valori numerici.
 
 
@@ -365,7 +381,7 @@ linguaggio C all'interno della stessa, o se si richiede esplicitamente la
 chiusura invocando direttamente la funzione \func{exit}. Queste due modalità
 sono assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera
 trasparente anche quando \code{main} ritorna, passandogli come argomento il
-valore di ritorno (che essendo .
+valore indicato da \instruction{return}.
 
 La funzione \funcd{exit}, che è completamente generale, essendo definita dallo
 standard ANSI C, è quella che deve essere invocata per una terminazione
@@ -390,7 +406,7 @@ vedremo a breve) che completa la terminazione del processo.
 
 \itindbeg{exit~status}
 
-Il valore dell'argomento \param{status} o il valore di ritorno di \code{main},
+Il valore dell'argomento \param{status} o il valore di ritorno di \code{main}
 costituisce quello che viene chiamato lo \textsl{stato di uscita}
 (l'\textit{exit status}) del processo. In generale si usa questo valore per
 fornire al processo padre (come vedremo in sez.~\ref{sec:proc_wait}) delle
@@ -399,22 +415,22 @@ terminato.
 
 Anche se l'argomento \param{status} (ed il valore di ritorno di \code{main})
 sono numeri interi di tipo \ctyp{int}, si deve tener presente che il valore
-dello stato di uscita viene comunque troncato ad 8 bit,
-per cui deve essere sempre compreso fra 0 e 255. Si tenga presente che se si
-raggiunge la fine della funzione \code{main} senza ritornare esplicitamente si
-ha un valore di uscita indefinito, è pertanto consigliabile di concludere
-sempre in maniera esplicita detta funzione.
-
-Non esiste un valore significato intrinseco della stato di uscita, ma una
-convenzione in uso pressoché universale è quella di restituire 0 in caso di
-successo e 1 in caso di fallimento. Una eccezione a questa convenzione è per i
-programmi che effettuano dei confronti (come \cmd{diff}), che usano 0 per
-indicare la corrispondenza, 1 per indicare la non corrispondenza e 2 per
-indicare l'incapacità di effettuare il confronto. 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é le convenzioni citate non siano seguite universalmente è
-una buona idea tenerle presenti ed adottarle a seconda dei casi.
+dello stato di uscita viene comunque troncato ad 8 bit, per cui deve essere
+sempre compreso fra 0 e 255. Si tenga presente che se si raggiunge la fine
+della funzione \code{main} senza ritornare esplicitamente si ha un valore di
+uscita indefinito, è pertanto consigliabile di concludere sempre in maniera
+esplicita detta funzione.
+
+Non esiste un significato intrinseco della stato di uscita, ma una convenzione
+in uso pressoché universale è quella di restituire 0 in caso di successo e 1
+in caso di fallimento. Una eccezione a questa convenzione è per i programmi
+che effettuano dei confronti (come \cmd{diff}), che usano 0 per indicare la
+corrispondenza, 1 per indicare la non corrispondenza e 2 per indicare
+l'incapacità di effettuare il confronto. 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é le
+convenzioni citate non siano seguite universalmente è una buona idea tenerle
+presenti ed adottarle a seconda dei casi.
 
 Si tenga presente inoltre che non è una buona idea usare eventuali codici di
 errore restituiti nella variabile \var{errno} (vedi sez.~\ref{sec:sys_errors})
@@ -436,8 +452,12 @@ i valori 0 e 1.
 Una forma alternativa per effettuare una terminazione esplicita di un
 programma è quella di chiamare direttamente la \textit{system call}
 \funcd{\_exit},\footnote{la stessa è definita anche come \funcd{\_Exit} in
-  \headfile{stdlib.h}.} che restituisce il controllo direttamente al kernel,
-concludendo immediatamente il processo, il suo prototipo è:
+  \headfile{stdlib.h}, inoltre a partire dalla \acr{glibc} 2.3 usando questa
+  funzione viene invocata \func{exit\_group} che termina tutti i
+  \textit{thread} del processo e non solo quello corrente (fintanto che non si
+  usano i \textit{thread}\unavref{, vedi sez.~\ref{cha:threads},} questo non
+  fa nessuna differenza).} che restituisce il controllo direttamente al
+kernel, concludendo immediatamente il processo, il suo prototipo è:
 
 \begin{funcproto}{ \fhead{unistd.h} \fdecl{void \_exit(int status)}
     \fdesc{Causa la conclusione immediata del programma.}  } {La funzione non
@@ -453,8 +473,8 @@ sez.~\ref{sec:file_unix_interface} e
 sez.~\ref{sec:files_std_interface}). Infine fa sì che ogni figlio del processo
 sia adottato da \cmd{init} (vedi sez.~\ref{sec:proc_termination}), manda un
 segnale \signal{SIGCHLD} al processo padre (vedi
-sez.~\ref{sec:sig_job_control}) e ritorna lo stato di uscita specificato
-in \param{status} che può essere raccolto usando la funzione \func{wait} (vedi
+sez.~\ref{sec:sig_job_control}) e salva lo stato di uscita specificato in
+\param{status} che può essere raccolto usando la funzione \func{wait} (vedi
 sez.~\ref{sec:proc_wait}).
 
 Si tenga presente infine che oltre alla conclusione ``\textsl{normale}''
@@ -468,12 +488,12 @@ funzione \func{abort}; torneremo su questo in sez.~\ref{sec:proc_termination}.
 \label{sec:proc_atexit}
 
 Un'esigenza comune che si incontra è quella di dover effettuare una serie di
-operazioni di pulizia (ad esempio salvare dei dati, ripristinare delle
-impostazioni, eliminare dei file temporanei, ecc.) prima della conclusione di
-un programma. In genere queste operazioni vengono fatte in un'apposita sezione
-del programma, ma quando si realizza una libreria diventa antipatico dover
-richiedere una chiamata esplicita ad una funzione di pulizia al programmatore
-che la utilizza.
+operazioni di pulizia prima della conclusione di un programma, ad esempio
+salvare dei dati, ripristinare delle impostazioni, eliminare dei file
+temporanei, ecc. In genere queste operazioni vengono fatte in un'apposita
+sezione del programma, ma quando si realizza una libreria diventa antipatico
+dover richiedere una chiamata esplicita ad una funzione di pulizia al
+programmatore che la utilizza.
 
 È invece molto meno soggetto ad errori, e completamente trasparente
 all'utente, avere la possibilità di fare effettuare automaticamente la
@@ -502,10 +522,13 @@ opportuna funzione di pulizia da chiamare all'uscita del programma, che non
 deve prendere argomenti e non deve ritornare niente. In sostanza deve la
 funzione di pulizia dovrà essere 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
-definita su altri sistemi,\footnote{non essendo prevista dallo standard POSIX
-  è in genere preferibile evitarne l'uso.} il suo prototipo è:
+Un'estensione di \func{atexit} è la funzione \funcd{on\_exit}, che la
+\acr{glibc} include per compatibilità con SunOS ma che non è detto sia
+definita su altri sistemi,\footnote{la funzione è disponibile dalla
+  \acr{glibc} 2.19 definendo la macro \macro{\_DEFAULT\_SOURCE}, mentre in
+  precedenza erano necessarie \macro{\_BSD\_SOURCE} o \macro{\_SVID\_SOURCE};
+  non essendo prevista dallo standard POSIX è in generale preferibile evitarne
+  l'uso.} il suo prototipo è:
 
 \begin{funcproto}{ 
 \fhead{stdlib.h} 
@@ -575,44 +598,44 @@ normalmente un programma è riportato in fig.~\ref{fig:proc_prog_start_stop}.
 
 \begin{figure}[htb]
   \centering
-%  \includegraphics[width=9cm]{img/proc_beginend}
-  \begin{tikzpicture}[>=stealth]
-    \filldraw[fill=black!35] (-0.3,0) rectangle (12,1);
-    \draw(5.5,0.5) node {\large{\textsf{kernel}}};
+  \includegraphics[width=9cm]{img/proc_beginend}
+  \begin{tikzpicture}[>=stealth]
+    \filldraw[fill=black!35] (-0.3,0) rectangle (12,1);
+    \draw(5.5,0.5) node {\large{\textsf{kernel}}};
 
-    \filldraw[fill=black!15] (1.5,2) rectangle (4,3);
-    \draw (2.75,2.5) node {\texttt{ld-linux.so}};
-    \draw [->] (2.75,1) -- (2.75,2);
-    \draw (2.75,1.5) node [anchor=west]{\texttt{execve}};
+    \filldraw[fill=black!15] (1.5,2) rectangle (4,3);
+    \draw (2.75,2.5) node {\texttt{ld-linux.so}};
+    \draw [->] (2.75,1) -- (2.75,2);
+    \draw (2.75,1.5) node [anchor=west]{\texttt{execve}};
 
-    \filldraw[fill=black!15,rounded corners] (1.5,4) rectangle (4,5);
-    \draw (2.75,4.5) node {\texttt{main}};
+    \filldraw[fill=black!15,rounded corners] (1.5,4) rectangle (4,5);
+    \draw (2.75,4.5) node {\texttt{main}};
 
-    \draw [<->, dashed] (2.75,3) -- (2.75,4);
-    \draw [->] (1.5,4.5) -- (0.3,4.5) -- (0.3,1);
-    \draw (0.9,4.5) node [anchor=south] {\texttt{\_exit}};
+    \draw [<->, dashed] (2.75,3) -- (2.75,4);
+    \draw [->] (1.5,4.5) -- (0.3,4.5) -- (0.3,1);
+    \draw (0.9,4.5) node [anchor=south] {\texttt{\_exit}};
 
-    \filldraw[fill=black!15,rounded corners] (1.5,6) rectangle (4,7);
-    \draw (2.75,6.5) node {\texttt{funzione}};
+    \filldraw[fill=black!15,rounded corners] (1.5,6) rectangle (4,7);
+    \draw (2.75,6.5) node {\texttt{funzione}};
 
-    \draw [<->, dashed] (2.75,5) -- (2.75,6);
-    \draw [->] (1.5,6.5) -- (0.05,6.5) -- (0.05,1);
-    \draw (0.9,6.5) node [anchor=south] {\texttt{\_exit}};
+    \draw [<->, dashed] (2.75,5) -- (2.75,6);
+    \draw [->] (1.5,6.5) -- (0.05,6.5) -- (0.05,1);
+    \draw (0.9,6.5) node [anchor=south] {\texttt{\_exit}};
 
-    \draw (6.75,4.5) node (exit) [rectangle,fill=black!15,minimum width=2.5cm,minimum height=1cm,rounded corners, draw]{\texttt{exit}};
+    \draw (6.75,4.5) node (exit) [rectangle,fill=black!15,minimum width=2.5cm,minimum height=1cm,rounded corners, draw]{\texttt{exit}};
 
-    \draw[->] (4,6.5) -- node[anchor=south west]{\texttt{exit}} (exit);
-    \draw[->] (4,4.5) -- node[anchor=south]{\texttt{exit}} (exit);
-    \draw[->] (exit) -- node[anchor=east]{\texttt{\_exit}}(6.75,1);
+    \draw[->] (4,6.5) -- node[anchor=south west]{\texttt{exit}} (exit);
+    \draw[->] (4,4.5) -- node[anchor=south]{\texttt{exit}} (exit);
+    \draw[->] (exit) -- node[anchor=east]{\texttt{\_exit}}(6.75,1);
 
-    \draw (10,4.5) node (exithandler1) [rectangle,fill=black!15,rounded corners, draw]{\textsf{exit handler}};
-    \draw (10,5.5) node (exithandler2) [rectangle,fill=black!15,rounded corners, draw]{\textsf{exit handler}};
-    \draw (10,3.5) node (stream) [rectangle,fill=black!15,rounded corners, draw]{\textsf{chiusura stream}};
+    \draw (10,4.5) node (exithandler1) [rectangle,fill=black!15,rounded corners, draw]{\textsf{exit handler}};
+    \draw (10,5.5) node (exithandler2) [rectangle,fill=black!15,rounded corners, draw]{\textsf{exit handler}};
+    \draw (10,3.5) node (stream) [rectangle,fill=black!15,rounded corners, draw]{\textsf{chiusura stream}};
 
-    \draw[<->, dashed] (exithandler1) -- (exit);
-    \draw[<->, dashed] (exithandler2) -- (exit);
-    \draw[<->, dashed] (stream) -- (exit);
-  \end{tikzpicture}
+    \draw[<->, dashed] (exithandler1) -- (exit);
+    \draw[<->, dashed] (exithandler2) -- (exit);
+    \draw[<->, dashed] (stream) -- (exit);
+  \end{tikzpicture}
   \caption{Schema dell'avvio e della conclusione di un programma.}
   \label{fig:proc_prog_start_stop}
 \end{figure}
@@ -721,11 +744,11 @@ riposte nella \textit{swap}.
 
 \itindend{page~fault} 
 
-Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed
-in genere il sistema è molto efficiente in questo lavoro; quando però ci siano
-esigenze specifiche di prestazioni è possibile usare delle funzioni che
-permettono di bloccare il meccanismo della paginazione e mantenere fisse delle
-pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}).
+Normalmente questo è il prezzo da pagare per avere un \textit{multitasking}
+reale, ed in genere il sistema è molto efficiente in questo lavoro; quando
+però ci siano esigenze specifiche di prestazioni è possibile usare delle
+funzioni che permettono di bloccare il meccanismo della paginazione e
+mantenere fisse delle pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}).
 
 \index{paginazione|)}
 \index{memoria~virtuale|)}
@@ -837,27 +860,27 @@ programma C viene suddiviso nei seguenti segmenti:
 
 \begin{figure}[htb]
   \centering
-%  \includegraphics[height=12cm]{img/memory_layout}
-  \begin{tikzpicture}
-  \draw (0,0) rectangle (4,1);
-  \draw (2,0.5) node {\textit{text}};
-  \draw (0,1) rectangle (4,2.5);
-  \draw (2,1.75) node {dati inizializzati};
-  \draw (0,2.5) rectangle (4,5);
-  \draw (2,3.75) node {dati non inizializzati};
-  \draw (0,5) rectangle (4,9);
-  \draw[dashed] (0,6) -- (4,6);
-  \draw[dashed] (0,8) -- (4,8);
-  \draw (2,5.5) node {\textit{heap}};
-  \draw (2,8.5) node {\textit{stack}};
-  \draw [->] (2,6) -- (2,6.5);
-  \draw [->] (2,8) -- (2,7.5);
-  \draw (0,9) rectangle (4,10);
-  \draw (2,9.5) node {\textit{environment}};
-  \draw (4,0) node [anchor=west] {\texttt{0x08000000}};
-  \draw (4,5) node [anchor=west] {\texttt{0x08xxxxxx}};
-  \draw (4,9) node [anchor=west] {\texttt{0xC0000000}};
-  \end{tikzpicture} 
+  \includegraphics[height=10cm]{img/memory_layout}
+  \begin{tikzpicture}
+  \draw (0,0) rectangle (4,1);
+  \draw (2,0.5) node {\textit{text}};
+  \draw (0,1) rectangle (4,2.5);
+  \draw (2,1.75) node {dati inizializzati};
+  \draw (0,2.5) rectangle (4,5);
+  \draw (2,3.75) node {dati non inizializzati};
+  \draw (0,5) rectangle (4,9);
+  \draw[dashed] (0,6) -- (4,6);
+  \draw[dashed] (0,8) -- (4,8);
+  \draw (2,5.5) node {\textit{heap}};
+  \draw (2,8.5) node {\textit{stack}};
+  \draw [->] (2,6) -- (2,6.5);
+  \draw [->] (2,8) -- (2,7.5);
+  \draw (0,9) rectangle (4,10);
+  \draw (2,9.5) node {\textit{environment}};
+  \draw (4,0) node [anchor=west] {\texttt{0x08000000}};
+  \draw (4,5) node [anchor=west] {\texttt{0x08xxxxxx}};
+  \draw (4,9) node [anchor=west] {\texttt{0xC0000000}};
+  \end{tikzpicture} 
   \caption{Disposizione tipica dei segmenti di memoria di un processo.}
   \label{fig:proc_mem_layout}
 \end{figure}
@@ -943,7 +966,7 @@ in caso di successo e \val{NULL} in caso di fallimento, nel qual caso
 
 In genere si usano \func{malloc} e \func{calloc} per allocare dinamicamente
 un'area di memoria.\footnote{queste funzioni presentano un comportamento
-  diverso fra le \acr{glibc} e le \acr{uClib} quando il valore di \param{size}
+  diverso fra la \acr{glibc} e la \acr{uClib} quando il valore di \param{size}
   è nullo.  Nel primo caso viene comunque restituito un puntatore valido,
   anche se non è chiaro a cosa esso possa fare riferimento, nel secondo caso
   viene restituito \val{NULL}. Il comportamento è analogo con
@@ -975,9 +998,9 @@ essere esplicitamente rilasciata usando la funzione \funcd{free},\footnote{le
 
 Questa funzione vuole come argomento \var{ptr} il puntatore restituito da una
 precedente chiamata ad una qualunque delle funzioni di allocazione che non sia
-già stato liberato da un'altra chiamata a \func{free}. Se il valore
-di \param{ptr} è \val{NULL} la funzione non fa niente, mentre se l'area di
-memoria era già stata liberata da un precedente chiamata il comportamento
+già stato liberato da un'altra chiamata a \func{free}. Se il valore di
+\param{ptr} è \val{NULL} la funzione non fa niente, mentre se l'area di
+memoria era già stata liberata da una precedente chiamata il comportamento
 della funzione è dichiarato indefinito, ma in genere comporta la corruzione
 dei dati di gestione dell'allocazione, che può dar luogo a problemi gravi, ad
 esempio un \textit{segmentation fault} in una successiva chiamata di una di
@@ -1168,7 +1191,7 @@ programma\footnote{questo comporta anche il fatto che non è possibile
 modificare il puntatore nello \textit{stack} e non c'è modo di sapere se se ne
 sono superate le dimensioni, per cui in caso di fallimento nell'allocazione il
 comportamento del programma può risultare indefinito, dando luogo ad una
-\textit{segment violation} la prima volta che cercherà di accedere alla
+\textit{segment violation} la prima volta che si cerchi di accedere alla
 memoria non effettivamente disponibile.
 
 \index{segmento!dati|(}
@@ -1223,12 +1246,12 @@ segmento dati\footnote{in questo caso si tratta soltanto di una funzione di
   caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
 \end{funcproto}
 
-La funzione incrementa la dimensione dello \textit{heap} di un
-programma del valore indicato dall'argomento \param{increment}, restituendo il
-nuovo indirizzo finale dello stesso.  L'argomento è definito come di tipo
-\type{intptr\_t}, ma a seconda della versione delle librerie e del sistema può
-essere indicato con una serie di tipi equivalenti come \ctyp{ptrdiff\_t},
-\ctyp{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzione
+La funzione incrementa la dimensione dello \textit{heap} di un programma del
+valore indicato dall'argomento \param{increment}, restituendo il nuovo
+indirizzo finale dello stesso.  L'argomento è definito come di tipo
+\typed{intptr\_t}, ma a seconda della versione delle librerie e del sistema
+può essere indicato con una serie di tipi equivalenti come \type{ptrdiff\_t},
+\type{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzione
 permette di ottenere l'attuale posizione della fine del segmento dati.
 
 Queste due funzioni sono state deliberatamente escluse dallo standard POSIX.1
@@ -1285,7 +1308,7 @@ memoria virtuale è disponibile una apposita funzione di sistema,
 \funcd{mincore}, che però non è standardizzata da POSIX e pertanto non è
 disponibile su tutte le versioni di kernel unix-like;\footnote{nel caso di
   Linux devono essere comunque definite le macro \macro{\_BSD\_SOURCE} e
-  \macro{\_SVID\_SOURCE}.}  il suo prototipo è:
+  \macro{\_SVID\_SOURCE} o \macro{\_DEFAULT\_SOURCE}.}  il suo prototipo è:
 
 \begin{funcproto}{
 \fhead{unistd.h}
@@ -1321,6 +1344,11 @@ processo,\footnote{in caso contrario si avrà un errore di \errcode{ENOMEM};
   positivo di grandi dimensioni.}  ma il risultato verrà comunque fornito per
 l'intervallo compreso fino al multiplo successivo.
 
+% TODO: verificare i cambiamenti di sematica con il kernel 5.0 (restrizione
+% solo alle pagine relative al processo stesso) vedi:
+% https://lwn.net/Articles/776034/,
+% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=574823bfab82d9d8fa47f422778043fbb4b4f50e 
+
 I risultati della funzione vengono forniti nel vettore puntato da \param{vec},
 che deve essere allocato preventivamente e deve essere di dimensione
 sufficiente a contenere tanti byte quante sono le pagine contenute
@@ -1331,7 +1359,7 @@ la pagina di memoria corrispondente è al momento residente in memoria, o
 cancellato altrimenti. Il comportamento sugli altri bit è indefinito, essendo
 questi al momento riservati per usi futuri. Per questo motivo in genere è
 comunque opportuno inizializzare a zero il contenuto del vettore, così che le
-pagine attualmente residenti in memoria saranno indicata da un valore non
+pagine attualmente residenti in memoria saranno indicate da un valore non
 nullo del byte corrispondente.
 
 Dato che lo stato della memoria di un processo può cambiare continuamente, il
@@ -1402,11 +1430,15 @@ loro prototipi sono:
 {Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ in caso di
   errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EINVAL}] \param{len} non è un valore positivo.
+  \item[\errcode{EAGAIN}] una parte o tutto l'intervallo richiesto non può
+    essere bloccato per una mancanza temporanea di risorse.
+  \item[\errcode{EINVAL}] \param{len} non è un valore positivo o la somma con
+    \param{addr} causa un overflow.
   \item[\errcode{ENOMEM}] alcuni indirizzi dell’intervallo specificato non
-    corrispondono allo spazio di indirizzi del processo o si è superato il
-    limite di \const{RLIMIT\_MEMLOCK} per un processo non privilegiato (solo
-    per kernel a partire dal 2.6.9). 
+    corrispondono allo spazio di indirizzi del processo o con \func{mlock} si
+    è superato il limite di \const{RLIMIT\_MEMLOCK} per un processo non
+    privilegiato (solo per kernel a partire dal 2.6.9) o si è superato il
+    limite di regioni di memoria con attributi diversi.
   \item[\errcode{EPERM}] il processo non è privilegiato (per kernel precedenti
     il 2.6.9) o si ha un limite nullo per \const{RLIMIT\_MEMLOCK} e
     il processo non è privilegiato (per kernel a partire dal 2.6.9).
@@ -1415,12 +1447,13 @@ loro prototipi sono:
 
 Le due funzioni permettono rispettivamente di bloccare e sbloccare la
 paginazione per l'intervallo di memoria iniziante all'indirizzo \param{addr} e
-lungo \param{len} byte.  Tutte le pagine che contengono una parte
-dell'intervallo bloccato sono mantenute in RAM per tutta la durata del
-blocco. Con kernel diversi da Linux si può ottenere un errore di
-\errcode{EINVAL} se \param{addr} non è un multiplo della dimensione delle
-pagine di memoria, pertanto se si ha a cuore la portabilità si deve avere cura
-di allinearne correttamente il valore.
+lungo \param{len} byte.  Al ritorno di \func{mlock} tutte le pagine che
+contengono una parte dell'intervallo bloccato sono garantite essere in RAM e
+vi verranno mantenute per tutta la durata del blocco. Con kernel diversi da
+Linux si può ottenere un errore di \errcode{EINVAL} se \param{addr} non è un
+multiplo della dimensione delle pagine di memoria, pertanto se si ha a cuore
+la portabilità si deve avere cura di allinearne correttamente il valore. Il
+blocco viene rimosso chiamando \func{munlock}.
 
 Altre due funzioni di sistema, \funcd{mlockall} e \funcd{munlockall},
 consentono di bloccare genericamente la paginazione per l'intero spazio di
@@ -1440,7 +1473,7 @@ indirizzi di un processo.  I prototipi di queste funzioni sono:
 
 L'argomento \param{flags} di \func{mlockall} permette di controllarne il
 comportamento; esso deve essere specificato come maschera binaria dei valori
-espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
+espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}. 
 
 \begin{table}[htb]
   \footnotesize
@@ -1454,6 +1487,8 @@ espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
                            spazio di indirizzi del processo.\\
     \constd{MCL\_FUTURE} & blocca tutte le pagine che verranno mappate nello
                            spazio di indirizzi del processo.\\
+    \constd{MCL\_ONFAULT}& esegue il blocco delle pagine selezionate solo
+                           quando vengono utilizzate (dal kernel 4.4).\\
    \hline
   \end{tabular}
   \caption{Valori e significato dell'argomento \param{flags} della funzione
@@ -1464,26 +1499,73 @@ espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
 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 \textit{stack}, lo \textit{heap} e pure le funzioni di libreria chiamate, i
-file mappati in memoria, i dati del kernel mappati in user space, la memoria
-condivisa.  L'uso dell'argomento \param{flags} permette di selezionare con
-maggior finezza le pagine da bloccare, ad esempio usando \const{MCL\_FUTURE}
-ci si può limitare a tutte le pagine allocate a partire dalla chiamata della
-funzione.
-
-In ogni caso un processo \textit{real-time} che deve entrare in una sezione
-critica (vedi sez.~\ref{sec:proc_race_cond}) deve provvedere a riservare
-memoria sufficiente prima dell'ingresso, per scongiurare l'occorrenza di un
-eventuale \textit{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 \textit{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 \textit{stack}, dopo di che, per essere
-sicuri che esse siano state effettivamente portate in memoria, ci si scrive
-sopra.
+file mappati in memoria, i dati del kernel mappati in \textit{user space}, la
+memoria condivisa.  L'uso dell'argomento \param{flags} permette di selezionare
+con maggior finezza le pagine da bloccare, ad esempio usando
+\const{MCL\_FUTURE} ci si può limitare a tutte le pagine allocate a partire
+dalla chiamata della funzione, mentre \const{MCL\_CURRENT} blocca tutte quelle
+correntemente mappate. L'uso di \func{munlockall} invece sblocca sempre tutte
+le pagine di memoria correntemente mappate nello spazio di indirizzi del
+programma.
+
+A partire dal kernel 4.4 alla funzione \func{mlockall} è stato aggiunto un
+altro flag, \const{MCL\_ONFAULT}, che può essere abbinato a entrambi gli altri
+due flag, e consente di modificare il comportamento della funzione per
+ottenere migliori prestazioni.
+
+Il problema che si presenta infatti è che eseguire un \textit{memory lock} per
+un intervallo ampio di memoria richiede che questa venga comunque allocata in
+RAM, con altrettanti \textit{page fault} che ne assicurino la presenza; questo
+vale per tutto l'intervallo e può avere un notevole costo in termini di
+prestazioni, anche quando poi, nell'esecuzione del programma, venisse usata
+solo una piccola parte dello stesso. L'uso di \const{MCL\_ONFAULT} previene il
+\textit{page faulting} immediato di tutto l'intervallo, le pagine
+dell'intervallo verranno bloccate, ma solo quando un \textit{page fault}
+dovuto all'accesso ne richiede l'allocazione effettiva in RAM.
+
+Questo stesso comportamento non è ottenibile con \func{mlock}, che non dispone
+di un argomento \param{flag} che consenta di richiederlo, per questo sempre
+con il kernel 4.4 è stata aggiunta una ulteriore funzione di sistema,
+\funcd{mlock2}, il cui prototipo è:
+
+\begin{funcproto}{
+  \fhead{sys/mman.h} 
+  \fdecl{int mlock2(const void *addr, size\_t len, int flags)}
+  \fdesc{Blocca la paginazione su un intervallo di memoria.}
+}
+{Le funzione ritornano $0$ in caso di successo e $-1$ in caso di errore, nel
+  qual caso \var{errno} assume gli stessi valori di \func{mlock} con
+  l'aggiunta id un possibile \errcode{EINVAL} anche se si è indicato un valore
+  errato di \param{flags}.}
+\end{funcproto}
+
+% NOTA: per mlock2, introdotta con il kernel 4.4 (vedi
+% http://lwn.net/Articles/650538/)
+
+Indicando un valore nullo per \param{flags} il comportamento della funzione è
+identico a quello di \func{mlock}, l'unico altro valore possibile è
+\constd{MLOCK\_ONFAULT} che ha lo stesso effetto sull'allocazione delle pagine
+in RAM già descritto per \const{MCL\_ONFAULT}.
+
+Si tenga presente che un processo \textit{real-time} che intende usare il
+\textit{memory locking} con \func{mlockall} per prevenire l'avvenire di un
+eventuale \textit{page fault} ed il conseguente rallentamento (probabilmente
+inaccettabile) dei tempi di esecuzione, deve comunque avere delle accortezze.
+In particolare si deve assicurare di aver preventivamente bloccato una
+quantità di spazio nello \textit{stack} sufficiente a garantire l'esecuzione
+di tutte le funzioni che hanno i requisiti di criticità sui tempi. Infatti,
+anche usando \const{MCL\_FUTURE}, in caso di allocazione di una nuova pagina
+nello \textit{stack} durante l'esecuzione di una funzione (precedentemente non
+usata e quindi non bloccata) si potrebbe avere un \textit{page fault}.
+
+In genere si ovvia a questa problematica chiamando inizialmente una funzione
+che definisca una quantità sufficientemente ampia di variabili automatiche
+(che si ricordi vengono allocate nello \textit{stack}) e ci scriva, in modo da
+esser sicuri che le corrispondenti pagine vengano mappate nello spazio di
+indirizzi del processo, per poi bloccarle. La scrittura è necessaria perché il
+kernel usa il meccanismo di \textit{copy on write} (vedi
+sez.~\ref{sec:proc_fork}) e le pagine potrebbero non essere allocate
+immediatamente.
 
 \itindend{memory~locking}
 \index{memoria~virtuale|)} 
@@ -1511,8 +1593,9 @@ tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
 funzione specifica.
 
 Tradizionalmente per rispondere a questa esigenza sono state create due
-funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
-rispettivi prototipi sono:
+funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete, cui si
+aggiunge \funcd{pvalloc} come estensione GNU, anch'essa obsoleta; i rispettivi
+prototipi sono:
 
 \begin{funcproto}{ 
 \fhead{malloc.h} 
@@ -1522,6 +1605,9 @@ rispettivi prototipi sono:
 \fdecl{void *memalign(size\_t boundary, size\_t size)}
 \fdesc{Alloca un blocco di memoria allineato ad un multiplo
   di \param{boundary}.} 
+\fdecl{void *pvalloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+  memoria.}  
 }
 {Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
   caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
@@ -1533,21 +1619,23 @@ rispettivi prototipi sono:
 \end{funcproto}
 
 Le funzioni restituiscono il puntatore al buffer di memoria allocata di
-dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo
-di \param{boundary} mentre per \func{valloc} un multiplo della dimensione di
-una pagina di memoria. Nel caso della versione fornita dalla \acr{glibc} la
-memoria allocata con queste funzioni deve essere liberata con \func{free},
-cosa che non è detto accada con altre implementazioni.
+dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo di
+\param{boundary} mentre per \func{valloc} un multiplo della dimensione di una
+pagina di memoria; lo stesso vale per \func{pvalloc} che però arrotonda
+automaticamente la dimensione dell'allocazione al primo multiplo di una
+pagina. Nel caso della versione fornita dalla \acr{glibc} la memoria allocata
+con queste funzioni deve essere liberata con \func{free}, cosa che non è detto
+accada con altre implementazioni.
 
 Nessuna delle due funzioni ha una chiara standardizzazione e nessuna delle due
 compare in POSIX.1, inoltre ci sono indicazioni discordi sui file che ne
 contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
-  \headfile{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4}
+  \headfile{stdlib.h}, mentre sia la \acr{glibc} che le precedenti \acr{libc4}
   e \acr{libc5} la dichiarano in \headfile{malloc.h}, lo stesso vale per
   \func{memalign} che in alcuni sistemi è dichiarata in \headfile{stdlib.h}.}
 per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
-nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
-prototipo è:
+nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d e
+disponibile dalla \acr{glibc} 2.1.91; il suo prototipo è:
 
 \begin{funcproto}{ 
 \fhead{stdlib.h} 
@@ -1559,7 +1647,7 @@ prototipo è:
   caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
   assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EINVAL}] \param{alignment} non è potenza di due e multiplo
+  \item[\errcode{EINVAL}] \param{alignment} non è potenza di due o un multiplo
     di \code{sizeof(void *)}.
   \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
   \end{errlist}}
@@ -1571,10 +1659,26 @@ indicato da \param{memptr}. La funzione fallisce nelle stesse condizioni delle
 due funzioni precedenti, ma a loro differenza restituisce direttamente come
 valore di ritorno il codice di errore.  Come per le precedenti la memoria
 allocata con \func{posix\_memalign} deve essere disallocata con \func{free},
-che in questo caso però è quanto richiesto dallo standard.  Si tenga presente
-infine che nessuna di queste funzioni inizializza il buffer di memoria
-allocato, il loro comportamento cioè è analogo, allineamento a parte, a quello
-di \func{malloc}.
+che in questo caso però è quanto richiesto dallo standard.
+
+Dalla versione 2.16 della \acr{glibc} è stata aggiunta anche la funzione
+\funcd{aligned\_alloc}, prevista dallo standard C11 (e disponibile definendo
+\const{\_ISOC11\_SOURCE}), il cui prototipo è:
+
+\begin{funcproto}{ 
+\fhead{malloc.h} 
+\fdecl{void *aligned\_alloc(size\_t alignment, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+  di \param{alignment}.} 
+}
+{La funzione ha gli stessi valori di ritorno e codici di errore di
+  \func{memalign}.}
+\end{funcproto}
+
+La funzione è identica a \func{memalign} ma richiede che \param{size} sia un
+multiplo di \param{alignment}.  Infine si tenga presente infine che nessuna di
+queste funzioni inizializza il buffer di memoria allocato, il loro
+comportamento cioè è analogo, allineamento a parte, a quello di \func{malloc}.
 
 Un secondo caso in cui risulta estremamente utile poter avere un maggior
 controllo delle modalità di allocazione della memoria è quello in cui cercano
@@ -1600,7 +1704,7 @@ suo prototipo è:
 \fdecl{int mcheck(void (*abortfn) (enum mcheck\_status status))}
 \fdesc{Attiva i controlli di consistenza delle allocazioni di memoria.}   
 }
-{La funzione ritorna $0$ in caso di successo e $-1$ per un errorre;
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore;
   \var{errno} non viene impostata.} 
 \end{funcproto}
 
@@ -1715,34 +1819,32 @@ contengono degli spazi evitando di spezzarli in parole diverse.
 
 \begin{figure}[htb]
   \centering
-%  \includegraphics[width=13cm]{img/argv_argc}
-%  \includegraphics[width=13cm]{img/argv_argc}
-  \begin{tikzpicture}[>=stealth]
-  \draw (0.5,2.5) rectangle (3.5,3);
-  \draw (2,2.75) node {\texttt{argc = 5}};
-  \draw (5,2.5) rectangle (8,3);
-  \draw (6.5,2.75) node {\texttt{argv[0]}};
-  \draw [->] (8,2.75) -- (9,2.75);
-  \draw (9,2.75) node [anchor=west] {\texttt{"touch"}};
-  \draw (5,2) rectangle (8,2.5);
-  \draw (6.5,2.25) node {\texttt{argv[1]}};
-  \draw [->] (8,2.25) -- (9,2.25);
-  \draw (9,2.25) node [anchor=west] {\texttt{"-r"}};
-  \draw (5,1.5) rectangle (8,2);
-  \draw (6.5,1.75) node {\texttt{argv[2]}};
-  \draw [->] (8,1.75) -- (9,1.75);
-  \draw (9,1.75) node [anchor=west] {\texttt{"riferimento.txt"}};
-  \draw (5,1.0) rectangle (8,1.5);
-  \draw (6.5,1.25) node {\texttt{argv[3]}};
-  \draw [->] (8,1.25) -- (9,1.25);
-  \draw (9,1.25) node [anchor=west] {\texttt{"-m"}};
-  \draw (5,0.5) rectangle (8,1.0);
-  \draw (6.5,0.75) node {\texttt{argv[4]}};
-  \draw [->] (8,0.75) -- (9,0.75);
-  \draw (9,0.75) node [anchor=west] {\texttt{"questofile.txt"}};
-  \draw (4.25,3.5) node{\texttt{"touch -r riferimento.txt -m questofile.txt"}};
-
-  \end{tikzpicture}
+  \includegraphics[width=13cm]{img/argv_argc}
+  % \begin{tikzpicture}[>=stealth]
+  % \draw (0.5,2.5) rectangle (3.5,3);
+  % \draw (2,2.75) node {\texttt{argc = 5}};
+  % \draw (5,2.5) rectangle (8,3);
+  % \draw (6.5,2.75) node {\texttt{argv[0]}};
+  % \draw [->] (8,2.75) -- (9,2.75);
+  % \draw (9,2.75) node [anchor=west] {\texttt{"touch"}};
+  % \draw (5,2) rectangle (8,2.5);
+  % \draw (6.5,2.25) node {\texttt{argv[1]}};
+  % \draw [->] (8,2.25) -- (9,2.25);
+  % \draw (9,2.25) node [anchor=west] {\texttt{"-r"}};
+  % \draw (5,1.5) rectangle (8,2);
+  % \draw (6.5,1.75) node {\texttt{argv[2]}};
+  % \draw [->] (8,1.75) -- (9,1.75);
+  % \draw (9,1.75) node [anchor=west] {\texttt{"riferimento.txt"}};
+  % \draw (5,1.0) rectangle (8,1.5);
+  % \draw (6.5,1.25) node {\texttt{argv[3]}};
+  % \draw [->] (8,1.25) -- (9,1.25);
+  % \draw (9,1.25) node [anchor=west] {\texttt{"-m"}};
+  % \draw (5,0.5) rectangle (8,1.0);
+  % \draw (6.5,0.75) node {\texttt{argv[4]}};
+  % \draw [->] (8,0.75) -- (9,0.75);
+  % \draw (9,0.75) node [anchor=west] {\texttt{"questofile.txt"}};
+  % \draw (4.25,3.5) node{\texttt{"touch -r riferimento.txt -m questofile.txt"}};
+  % \end{tikzpicture}
   \caption{Esempio dei valori di \param{argv} e \param{argc} generati nella 
     scansione di una riga di comando.}
   \label{fig:proc_argv_argc}
@@ -1768,9 +1870,11 @@ tali: un elemento di \param{argv} successivo al primo che inizia con il
 carattere ``\texttt{-}'' e che non sia un singolo ``\texttt{-}'' o un
 ``\texttt{-{}-}'' viene considerato un'opzione.  In genere le opzioni sono
 costituite da una lettera singola (preceduta dal carattere ``\texttt{-}'') e
-possono avere o no un parametro associato. Un esempio tipico può essere quello
-mostrato in fig.~\ref{fig:proc_argv_argc}. In quel caso le opzioni sono
-\cmd{-r} e \cmd{-m} e la prima vuole un parametro mentre la seconda no
+possono avere o no un parametro associato.
+
+Un esempio tipico può essere quello mostrato in
+fig.~\ref{fig:proc_argv_argc}. In quel caso le opzioni sono \cmd{-r} e
+\cmd{-m} e la prima vuole un parametro mentre la seconda no
 (\cmd{questofile.txt} è un argomento del programma, non un parametro di
 \cmd{-m}).
 
@@ -1811,16 +1915,6 @@ ritornato il carattere ``\texttt{:}'', infine se viene incontrato il valore
 ``\texttt{-{}-}'' la scansione viene considerata conclusa, anche se vi sono
 altri elementi di \param{argv} che cominciano con il carattere ``\texttt{-}''.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{\codesamplewidth}
-  \includecodesample{listati/option_code.c}
-  \end{minipage}
-  \normalsize
-  \caption{Esempio di codice per la gestione delle opzioni.}
-  \label{fig:proc_options_code}
-\end{figure}
-
 Quando \func{getopt} trova un'opzione fra quelle indicate in \param{optstring}
 essa ritorna il valore numerico del carattere, in questo modo si possono
 eseguire azioni specifiche usando uno \instruction{switch}; la funzione
@@ -1835,6 +1929,16 @@ inoltre inizializza alcune variabili globali:
 \item \var{int optopt} contiene il carattere dell'opzione non riconosciuta.
 \end{itemize*}
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+  \includecodesample{listati/option_code.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice per la gestione delle opzioni.}
+  \label{fig:proc_options_code}
+\end{figure}
+
 In fig.~\ref{fig:proc_options_code} si è mostrata la sezione del programma
 \file{fork\_test.c}, che useremo nel prossimo capitolo per effettuare dei test
 sulla creazione dei processi, deputata alla decodifica delle opzioni a riga di
@@ -1900,34 +2004,34 @@ più comuni che normalmente sono definite dal sistema, è riportato in
 fig.~\ref{fig:proc_envirno_list}.
 \begin{figure}[htb]
   \centering
-%  \includegraphics[width=15 cm]{img/environ_var}
-  \begin{tikzpicture}[>=stealth]
-  \draw (2,3.5) node {\textsf{Environment pointer}};
-  \draw (6,3.5) node {\textsf{Environment list}};
-  \draw (10.5,3.5) node {\textsf{Environment string}};
-  \draw (0.5,2.5) rectangle (3.5,3);
-  \draw (2,2.75) node {\texttt{environ}};
-  \draw [->] (3.5,2.75) -- (4.5,2.75);
-  \draw (4.5,2.5) rectangle (7.5,3);
-  \draw (6,2.75) node {\texttt{environ[0]}};
-  \draw (4.5,2) rectangle (7.5,2.5);
-  \draw (6,2.25) node {\texttt{environ[1]}};
-  \draw (4.5,1.5) rectangle (7.5,2);
-  \draw (4.5,1) rectangle (7.5,1.5);
-  \draw (4.5,0.5) rectangle (7.5,1);
-  \draw (4.5,0) rectangle (7.5,0.5);
-  \draw (6,0.25) node {\texttt{NULL}};
-  \draw [->] (7.5,2.75) -- (8.5,2.75);
-  \draw (8.5,2.75) node[right] {\texttt{HOME=/home/piccardi}};
-  \draw [->] (7.5,2.25) -- (8.5,2.25);
-  \draw (8.5,2.25) node[right] {\texttt{PATH=:/bin:/usr/bin}};
-  \draw [->] (7.5,1.75) -- (8.5,1.75);
-  \draw (8.5,1.75) node[right] {\texttt{SHELL=/bin/bash}};
-  \draw [->] (7.5,1.25) -- (8.5,1.25);
-  \draw (8.5,1.25) node[right] {\texttt{EDITOR=emacs}};
-  \draw [->] (7.5,0.75) -- (8.5,0.75);
-  \draw (8.5,0.75) node[right] {\texttt{OSTYPE=linux-gnu}};
-  \end{tikzpicture}
+  \includegraphics[width=13cm]{img/environ_var}
+  \begin{tikzpicture}[>=stealth]
+  \draw (2,3.5) node {\textsf{Environment pointer}};
+  \draw (6,3.5) node {\textsf{Environment list}};
+  \draw (10.5,3.5) node {\textsf{Environment string}};
+  \draw (0.5,2.5) rectangle (3.5,3);
+  \draw (2,2.75) node {\texttt{environ}};
+  \draw [->] (3.5,2.75) -- (4.5,2.75);
+  \draw (4.5,2.5) rectangle (7.5,3);
+  \draw (6,2.75) node {\texttt{environ[0]}};
+  \draw (4.5,2) rectangle (7.5,2.5);
+  \draw (6,2.25) node {\texttt{environ[1]}};
+  \draw (4.5,1.5) rectangle (7.5,2);
+  \draw (4.5,1) rectangle (7.5,1.5);
+  \draw (4.5,0.5) rectangle (7.5,1);
+  \draw (4.5,0) rectangle (7.5,0.5);
+  \draw (6,0.25) node {\texttt{NULL}};
+  \draw [->] (7.5,2.75) -- (8.5,2.75);
+  \draw (8.5,2.75) node[right] {\texttt{HOME=/home/piccardi}};
+  \draw [->] (7.5,2.25) -- (8.5,2.25);
+  \draw (8.5,2.25) node[right] {\texttt{PATH=:/bin:/usr/bin}};
+  \draw [->] (7.5,1.75) -- (8.5,1.75);
+  \draw (8.5,1.75) node[right] {\texttt{SHELL=/bin/bash}};
+  \draw [->] (7.5,1.25) -- (8.5,1.25);
+  \draw (8.5,1.25) node[right] {\texttt{EDITOR=emacs}};
+  \draw [->] (7.5,0.75) -- (8.5,0.75);
+  \draw (8.5,0.75) node[right] {\texttt{OSTYPE=linux-gnu}};
+  \end{tikzpicture}
   \caption{Esempio di lista delle variabili di ambiente.}
   \label{fig:proc_envirno_list}
 \end{figure}
@@ -2052,7 +2156,7 @@ stringa che ne contiene il valore, nella forma ``\texttt{NOME=valore}''.
 
 Oltre a questa funzione di lettura, che è l'unica definita dallo standard ANSI
 C, nell'evoluzione dei sistemi Unix ne sono state proposte altre, da
-utilizzare per impostare, modificare e per cancellare le variabili di
+utilizzare per impostare, modificare e cancellare le variabili di
 ambiente. Uno schema delle funzioni previste nei vari standard e disponibili
 in Linux è riportato in tab.~\ref{tab:proc_env_func}. Tutte le funzioni sono
 state comunque inserite nello standard POSIX.1-2001, ad eccetto di
@@ -2091,12 +2195,12 @@ sostituendo il relativo puntatore;\footnote{il comportamento è lo stesso delle
   vecchie \acr{libc4} e \acr{libc5}; nella \acr{glibc}, dalla versione 2.0
   alla 2.1.1, veniva invece fatta una copia, seguendo il comportamento di
   BSD4.4; dato che questo può dar luogo a perdite di memoria e non rispetta lo
-  standard il comportamento è stato modificato a partire dalle 2.1.2,
+  standard il comportamento è stato modificato a partire dalla 2.1.2,
   eliminando anche, sempre in conformità a SUSv2, l'attributo \direct{const}
   dal prototipo.}  pertanto ogni cambiamento alla stringa in questione si
 riflette automaticamente sull'ambiente, e quindi si deve evitare di passare a
 questa funzione una variabile automatica (per evitare i problemi esposti in
-sez.~\ref{sec:proc_var_passing}). Benché non sia richiesto dallo standard
+sez.~\ref{sec:proc_var_passing}). Benché non sia richiesto dallo standard,
 nelle versioni della \acr{glibc} a partire dalla 2.1 la funzione è rientrante
 (vedi sez.~\ref{sec:proc_reentrant}).
 
@@ -2212,7 +2316,7 @@ versione ``\textsl{sicura}'' da zero.
 %\label{sec:proc_opt_extended}
 
 %Oltre alla modalità ordinaria di gestione delle opzioni trattata in
-%sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità
+%sez.~\ref{sec:proc_opt_handling} la \acr{glibc} fornisce una modalità
 %alternativa costituita dalle cosiddette \textit{long-options}, che consente di
 %esprimere le opzioni in una forma più descrittiva che nel caso più generale è
 %qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''.
@@ -2232,8 +2336,8 @@ Benché questo non sia un libro sul linguaggio C, è opportuno affrontare alcune
 delle problematiche generali che possono emergere nella programmazione con
 questo linguaggio e di quali precauzioni o accorgimenti occorre prendere per
 risolverle. Queste problematiche non sono specifiche di sistemi unix-like o
-multitasking, ma avendo trattato in questo capitolo il comportamento dei
-processi visti come entità a sé stanti, le riportiamo qui.
+\textit{multitasking}, ma avendo trattato in questo capitolo il comportamento
+dei processi visti come entità a sé stanti, le riportiamo qui.
 
 
 \subsection{Il passaggio di variabili e valori di ritorno nelle funzioni}
@@ -2389,10 +2493,10 @@ una lista degli argomenti, la sua definizione è:
 }
 \end{funcbox}}
 
-La macro inizializza il puntatore alla lista di argomenti \param{ap} che
-deve essere una apposita variabile di tipo \type{va\_list}; il
+La macro inizializza il puntatore alla lista di argomenti \param{ap} che deve
+essere una apposita variabile di tipo \type{va\_list}; il
 parametro \param{last} deve indicare il nome dell'ultimo degli argomenti fissi
-dichiarati nel prototipo della funzione \textit{variadic}. 
+dichiarati nel prototipo della funzione \textit{variadic}.
 
 \macrobeg{va\_arg}
 
@@ -2441,8 +2545,7 @@ Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
 successive chiamate a \macro{va\_arg} non funzioneranno.  Nel caso del
 \cmd{gcc} l'uso di \macro{va\_end} può risultare inutile, ma è comunque
 necessario usarla per chiarezza del codice, per compatibilità con diverse
-implementazioni e per eventuali eventuali modifiche future a questo
-comportamento.
+implementazioni e per eventuali modifiche future a questo comportamento.
 
 Riassumendo la procedura da seguire per effettuare l'estrazione degli
 argomenti di una funzione \textit{variadic} è la seguente:
@@ -2484,15 +2587,15 @@ assolutamente normale pensare di poter effettuare questa operazione.
 \index{tipo!opaco|(}
 
 In generale però possono esistere anche realizzazioni diverse, ed è per questo
-motivo che invece che di un semplice puntatore viene \type{va\_list} è quello
-che viene chiamato un \textsl{tipo opaco}. Si chiamano così quei tipi di dati,
-in genere usati da una libreria, la cui struttura interna non deve essere
-vista dal programma chiamante (da cui deriva il nome opaco) che li devono
-utilizzare solo attraverso dalle opportune funzioni di gestione.
+motivo che invece che un semplice puntatore, \typed{va\_list} è quello che
+viene chiamato un \textsl{tipo opaco}. Si chiamano così quei tipi di dati, in
+genere usati da una libreria, la cui struttura interna non deve essere vista
+dal programma chiamante (da cui deriva il nome opaco) che li devono utilizzare
+solo attraverso dalle opportune funzioni di gestione.
 
 \index{tipo!opaco|)}
 
-Per questo motivo una variabile di tipo \type{va\_list} non può essere
+Per questo motivo una variabile di tipo \typed{va\_list} non può essere
 assegnata direttamente ad un'altra variabile dello stesso tipo, ma lo standard
 ISO C99\footnote{alcuni sistemi che non hanno questa macro provvedono al suo
   posto \macrod{\_\_va\_copy} che era il nome proposto in una bozza dello
@@ -2597,7 +2700,7 @@ di salvare il contesto dello \textit{stack} è \funcd{setjmp}, il cui prototipo
   
 Quando si esegue la funzione il contesto corrente dello \textit{stack} viene
 salvato nell'argomento \param{env}, una variabile di tipo
-\type{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di
+\typed{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di
   \textsl{tipo opaco}.}  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.
@@ -2655,10 +2758,11 @@ dei seguenti casi:
 \item come espressione a sé stante.
 \end{itemize*}
 
-In generale, dato che l'unica differenza fra la chiamata diretta e quella
-ottenuta nell'uscita con un \func{longjmp} è costituita dal valore di ritorno
-di \func{setjmp}, pertanto quest'ultima viene usualmente chiamata all'interno
-di un una istruzione \instr{if} che permetta di distinguere i due casi.
+In generale, dato che l'unica differenza fra il risultato di una chiamata
+diretta di \func{setjmp} e quello ottenuto nell'uscita con un \func{longjmp} è
+costituita dal valore di ritorno della funzione, quest'ultima viene usualmente
+chiamata all'interno di un una istruzione \instr{if} che permetta di
+distinguere i due casi.
 
 Uno dei punti critici dei salti non-locali è quello del valore delle
 variabili, ed in particolare quello delle variabili automatiche della funzione
@@ -2686,19 +2790,23 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva
 \index{salto~non-locale|)}
 
 
+% TODO trattare qui le restartable sequences (vedi
+% https://lwn.net/Articles/664645/ e https://lwn.net/Articles/650333/) se e
+% quando saranno introdotte
+
 \subsection{La \textit{endianness}}
 \label{sec:endianness}
 
 \itindbeg{endianness} 
 
 Un altro dei problemi di programmazione che può dar luogo ad effetti
-imprevisti è quello relativo alla cosiddetta \textit{endianness}.  Questa è una
-caratteristica generale dell'architettura hardware di un computer che dipende
-dal fatto che la rappresentazione di un numero binario può essere fatta in due
-modi, chiamati rispettivamente \textit{big endian} e \textit{little endian} a
-seconda di come i singoli bit vengono aggregati per formare le variabili
-intere (ed in genere in diretta corrispondenza a come sono poi in realtà
-cablati sui bus interni del computer).
+imprevisti è quello relativo alla cosiddetta \textit{endianness}.  Questa è
+una caratteristica generale dell'architettura hardware di un computer che
+dipende dal fatto che la rappresentazione di un numero binario può essere
+fatta in due modi, chiamati rispettivamente \textit{big endian} e
+\textit{little endian}, a seconda di come i singoli bit vengono aggregati per
+formare le variabili intere (ed in genere in diretta corrispondenza a come
+sono poi in realtà cablati sui bus interni del computer).
 
 \begin{figure}[!htb]
   \centering \includegraphics[height=3cm]{img/endianness}
@@ -2797,12 +2905,11 @@ il valore del confronto delle due variabili.
 
 In generale non ci si deve preoccupare della \textit{endianness} all'interno
 di un programma fintanto che questo non deve generare o manipolare dei dati
-che sono scambiati con altre macchine, ad esempio tramite via rete o tramite
-dei file binari. Nel primo caso la scelta è già stata fatta nella
-standardizzazione dei protocolli, che hanno adottato il \textit{big endian}
-(che viene detto anche per questo \textit{network order} e vedremo in
-sez.~\ref{sec:sock_func_ord} le funzioni di conversione che devono essere
-usate.
+che sono scambiati con altre macchine, ad esempio via rete o tramite dei file
+binari. Nel primo caso la scelta è già stata fatta nella standardizzazione dei
+protocolli, che hanno adottato il \textit{big endian} (che viene detto anche
+per questo \textit{network order}); vedremo in sez.~\ref{sec:sock_func_ord} le
+funzioni di conversione che devono essere usate.
 
 Nel secondo caso occorre sapere quale \textit{endianness} è stata usata nei
 dati memorizzati sul file e tenerne conto nella rilettura e nella
@@ -2827,7 +2934,7 @@ basterà scegliere una volta per tutte quale usare e attenersi alla scelta.
 % LocalWords:  capability MEMLOCK limits getpagesize RLIMIT munlock sys const
 % LocalWords:  addr len EINVAL EPERM mlockall munlockall flags l'OR CURRENT IFS
 % LocalWords:  argc argv parsing questofile txt getopt optstring switch optarg
-% LocalWords:  optind opterr optopt POSIXLY CORRECT long options NdA
+% LocalWords:  optind opterr optopt POSIXLY CORRECT long options NdA group
 % LocalWords:  option parameter list environ PATH HOME XPG tab LOGNAME LANG PWD
 % LocalWords:  TERM PAGER TMPDIR getenv name SVr setenv unsetenv putenv opz gcc
 % LocalWords:  clearenv libc value overwrite string reference result argument
@@ -2844,7 +2951,8 @@ basterà scegliere una volta per tutte quale usare e attenersi alla scelta.
 % LocalWords:  is to LC SIG str mem wcs assert ctype dirent fcntl signal stdio
 % LocalWords:  times library utmp syscall number Filesystem Hierarchy pathname
 % LocalWords:  context assembler sysconf fork Dinamic huge segmentation program
-% LocalWords:  break  store Using
+% LocalWords:  break store using intptr ssize overflow ONFAULT faulting alloc
+%  LocalWords:  scheduler pvalloc aligned ISOC ABCDEF
 
 %%% Local Variables: 
 %%% mode: latex