Passaggio a UTF-8 dei sorgenti
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 839f9dafa468a7eca5f9a5dce6bb805fa237d526..bb9e0b06cece8f401be8ca380b54c8c570ef5960 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2005 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2011 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",
@@ -8,19 +8,20 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
+
 \chapter{La comunicazione fra processi}
 \label{cha:IPC}
 
 
-Uno degli aspetti fondamentali della programmazione in un sistema unix-like è
+Uno degli aspetti fondamentali della programmazione in un sistema unix-like è
 la comunicazione fra processi. In questo capitolo affronteremo solo i
-meccanismi più elementari che permettono di mettere in comunicazione processi
+meccanismi più elementari che permettono di mettere in comunicazione processi
 diversi, come quelli tradizionali che coinvolgono \textit{pipe} e
 \textit{fifo} e i meccanismi di intercomunicazione di System V e quelli POSIX.
 
 Tralasceremo invece tutte le problematiche relative alla comunicazione
 attraverso la rete (e le relative interfacce) che saranno affrontate in
-dettaglio in un secondo tempo.  Non affronteremo neanche meccanismi più
+dettaglio in un secondo tempo.  Non affronteremo neanche meccanismi più
 complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) e CORBA
 (\textit{Common Object Request Brocker Architecture}) che in genere sono
 implementati con un ulteriore livello sopra i meccanismi elementari.
@@ -30,44 +31,45 @@ implementati con un ulteriore livello sopra i meccanismi elementari.
 \label{sec:ipc_unix}
 
 Il primo meccanismo di comunicazione fra processi introdotto nei sistemi Unix,
-è quello delle cosiddette \textit{pipe}; esse costituiscono una delle
+è quello delle cosiddette \textit{pipe}; esse costituiscono una delle
 caratteristiche peculiari del sistema, in particolar modo dell'interfaccia a
 linea di comando. In questa sezione descriveremo le sue basi, le funzioni che
-ne gestiscono l'uso e le varie forme in cui si è evoluto.
+ne gestiscono l'uso e le varie forme in cui si è evoluto.
 
 
 \subsection{Le \textit{pipe} standard}
 \label{sec:ipc_pipes}
 
 Le \textit{pipe} nascono sostanzialmente con Unix, e sono il primo, e tuttora
-uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
+uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
 sostanza di una coppia di file descriptor\footnote{si tenga presente che
   le pipe sono oggetti creati dal kernel e non risiedono su disco.} connessi
-fra di loro in modo che se quanto scrive su di uno si può rileggere
-dall'altro. Si viene così a costituire un canale di comunicazione tramite i
+fra di loro in modo che se quanto scrive su di uno si può rileggere
+dall'altro. Si viene così a costituire un canale di comunicazione tramite i
 due file descriptor, nella forma di un \textsl{tubo} (da cui il nome)
 attraverso cui fluiscono i dati.
 
 La funzione che permette di creare questa speciale coppia di file descriptor
-associati ad una \textit{pipe} è appunto \funcd{pipe}, ed il suo prototipo è:
+associati ad una \textit{pipe} è appunto \funcd{pipe}, ed il suo prototipo è:
 \begin{prototype}{unistd.h}
 {int pipe(int filedes[2])} 
   
 Crea una coppia di file descriptor associati ad una \textit{pipe}.
   
   \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, nel qual caso \var{errno} potrà assumere i valori \errval{EMFILE},
+    errore, nel qual caso \var{errno} potrà assumere i valori \errval{EMFILE},
     \errval{ENFILE} e \errval{EFAULT}.}
 \end{prototype}
 
 La funzione restituisce la coppia di file descriptor nel vettore
-\param{filedes}; il primo è aperto in lettura ed il secondo in scrittura. Come
-accennato concetto di funzionamento di una pipe è semplice: quello che si
+\param{filedes}; il primo è aperto in lettura ed il secondo in scrittura. Come
+accennato concetto di funzionamento di una pipe è semplice: quello che si
 scrive nel file descriptor aperto in scrittura viene ripresentato tale e quale
 nel file descriptor aperto in lettura. I file descriptor infatti non sono
-connessi a nessun file reale, ma ad un buffer nel kernel, la cui dimensione è
-specificata dal parametro di sistema \const{PIPE\_BUF}, (vedi
-sez.~\ref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
+connessi a nessun file reale, ma, come accennato in
+sez.~\ref{sec:file_sendfile_splice}, ad un buffer nel kernel, la cui
+dimensione è specificata dal parametro di sistema \const{PIPE\_BUF}, (vedi
+sez.~\ref{sec:sys_file_limits}). Lo schema di funzionamento di una pipe è
 illustrato in fig.~\ref{fig:ipc_pipe_singular}, in cui sono illustrati i due
 capi della pipe, associati a ciascun file descriptor, con le frecce che
 indicano la direzione del flusso dei dati.
@@ -80,13 +82,13 @@ indicano la direzione del flusso dei dati.
 \end{figure}
 
 Chiaramente creare una pipe all'interno di un singolo processo non serve a
-niente; se però ricordiamo quanto esposto in sez.~\ref{sec:file_sharing}
-riguardo al comportamento dei file descriptor nei processi figli, è immediato
+niente; se però ricordiamo quanto esposto in sez.~\ref{sec:file_sharing}
+riguardo al comportamento dei file descriptor nei processi figli, è immediato
 capire come una pipe possa diventare un meccanismo di intercomunicazione. Un
 processo figlio infatti condivide gli stessi file descriptor del padre,
 compresi quelli associati ad una pipe (secondo la situazione illustrata in
 fig.~\ref{fig:ipc_pipe_fork}). In questo modo se uno dei processi scrive su un
-capo della pipe, l'altro può leggere.
+capo della pipe, l'altro può leggere.
 
 \begin{figure}[htb]
   \centering
@@ -96,32 +98,32 @@ capo della pipe, l'altro pu
   \label{fig:ipc_pipe_fork}
 \end{figure}
 
-Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
-comunicazione fra processi attraverso una pipe, utilizzando le proprietà
-ordinarie dei file, ma ci mostra anche qual è il principale\footnote{Stevens
-  in \cite{APUE} riporta come limite anche il fatto che la comunicazione è
-  unidirezionale, ma in realtà questo è un limite facilmente superabile usando
-  una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i
+Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
+comunicazione fra processi attraverso una pipe, utilizzando le proprietà
+ordinarie dei file, ma ci mostra anche qual è il principale\footnote{Stevens
+  in \cite{APUE} riporta come limite anche il fatto che la comunicazione è
+  unidirezionale, ma in realtà questo è un limite facilmente superabile usando
+  una coppia di pipe.} limite nell'uso delle pipe. È necessario infatti che i
 processi possano condividere i file descriptor della pipe, e per questo essi
-devono comunque essere \textsl{parenti} (dall'inglese \textit{siblings}), cioè
-o derivare da uno stesso processo padre in cui è avvenuta la creazione della
-pipe, o, più comunemente, essere nella relazione padre/figlio.
+devono comunque essere \textsl{parenti} (dall'inglese \textit{siblings}), cioè
+o derivare da uno stesso processo padre in cui è avvenuta la creazione della
+pipe, o, più comunemente, essere nella relazione padre/figlio.
 
-A differenza di quanto avviene con i file normali, la lettura da una pipe può
+A differenza di quanto avviene con i file normali, la lettura da una pipe può
 essere bloccante (qualora non siano presenti dati), inoltre se si legge da una
-pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
-(vale a dire che la funzione \func{read} ritornerà restituendo 0).  Se invece
-si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
-processo riceverà il segnale \const{SIGPIPE}, e la funzione di scrittura
-restituirà un errore di \errcode{EPIPE} (al ritorno del gestore, o qualora il
+pipe il cui capo in scrittura è stato chiuso, si avrà la ricezione di un EOF
+(vale a dire che la funzione \func{read} ritornerà restituendo 0).  Se invece
+si esegue una scrittura su una pipe il cui capo in lettura non è aperto il
+processo riceverà il segnale \const{SIGPIPE}, e la funzione di scrittura
+restituirà un errore di \errcode{EPIPE} (al ritorno del gestore, o qualora il
 segnale sia ignorato o bloccato).
 
-La dimensione del buffer della pipe (\const{PIPE\_BUF}) ci dà inoltre un'altra
+La dimensione del buffer della pipe (\const{PIPE\_BUF}) ci dà inoltre un'altra
 importante informazione riguardo il comportamento delle operazioni di lettura
 e scrittura su di una pipe; esse infatti sono atomiche fintanto che la
-quantità di dati da scrivere non supera questa dimensione. Qualora ad esempio
-si effettui una scrittura di una quantità di dati superiore l'operazione verrà
-effettuata in più riprese, consentendo l'intromissione di scritture effettuate
+quantità di dati da scrivere non supera questa dimensione. Qualora ad esempio
+si effettui una scrittura di una quantità di dati superiore l'operazione verrà
+effettuata in più riprese, consentendo l'intromissione di scritture effettuate
 da altri processi.
 
 
@@ -129,10 +131,10 @@ da altri processi.
 \label{sec:ipc_pipe_use}
 
 Per capire meglio il funzionamento delle pipe faremo un esempio di quello che
-è il loro uso più comune, analogo a quello effettuato della shell, e che
+è il loro uso più comune, analogo a quello effettuato della shell, e che
 consiste nell'inviare l'output di un processo (lo standard output) sull'input
-di un'altro. Realizzeremo il programma di esempio nella forma di un
-\textit{CGI}\footnote{Un CGI (\textit{Common Gateway Interface}) è un
+di un altro. Realizzeremo il programma di esempio nella forma di un
+\textit{CGI}\footnote{un CGI (\textit{Common Gateway Interface}) è un
   programma che permette la creazione dinamica di un oggetto da inserire
   all'interno di una pagina HTML.}  per Apache, che genera una immagine JPEG
 di un codice a barre, specificato come argomento in ingresso.
@@ -147,15 +149,15 @@ solito ha la forma:
 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
 che ne descrive il mime-type) sullo standard output, in modo che il web-server
 possa reinviarlo al browser che ha effettuato la richiesta, che in questo modo
-è in grado di visualizzarlo opportunamente.
+è in grado di visualizzarlo opportunamente.
 
 Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
-\cmd{gs}, il primo infatti è in grado di generare immagini PostScript di
+\cmd{gs}, il primo infatti è in grado di generare immagini PostScript di
 codici a barre corrispondenti ad una qualunque stringa, mentre il secondo
 serve per poter effettuare la conversione della stessa immagine in formato
 JPEG. Usando una pipe potremo inviare l'output del primo sull'input del
 secondo, secondo lo schema mostrato in fig.~\ref{fig:ipc_pipe_use}, in cui la
-direzione del flusso dei dati è data dalle frecce continue.
+direzione del flusso dei dati è data dalle frecce continue.
 
 \begin{figure}[htb]
   \centering
@@ -166,29 +168,28 @@ direzione del flusso dei dati 
   \label{fig:ipc_pipe_use}
 \end{figure}
 
-Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
-intermedio su un file temporaneo. Questo però non tiene conto del fatto che un
-\textit{CGI} deve poter gestire più richieste in concorrenza, e si avrebbe una
-evidente \textit{race condition}\itindex{race~condition} in caso di accesso
+Si potrebbe obiettare che sarebbe molto più semplice salvare il risultato
+intermedio su un file temporaneo. Questo però non tiene conto del fatto che un
+\textit{CGI} deve poter gestire più richieste in concorrenza, e si avrebbe una
+evidente \itindex{race~condition} \textit{race condition} in caso di accesso
 simultaneo a detto file.\footnote{il problema potrebbe essere superato
   determinando in anticipo un nome appropriato per il file temporaneo, che
   verrebbe utilizzato dai vari sotto-processi, e cancellato alla fine della
-  loro esecuzione; ma a questo le cose non sarebbero più tanto semplici.}
-L'uso di una pipe invece permette di risolvere il problema in maniera semplice
-ed elegante, oltre ad essere molto più efficiente, dato che non si deve
-scrivere su disco.
+  loro esecuzione; ma a questo punto le cose non sarebbero più tanto
+  semplici.}  L'uso di una pipe invece permette di risolvere il problema in
+maniera semplice ed elegante, oltre ad essere molto più efficiente, dato che
+non si deve scrivere su disco.
 
-Il programma ci servirà anche come esempio dell'uso delle funzioni di
+Il programma ci servirà anche come esempio dell'uso delle funzioni di
 duplicazione dei file descriptor che abbiamo trattato in
-sez.~\ref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
-funzioni infatti che è possibile dirottare gli stream standard dei processi
+sez.~\ref{sec:file_dup}, in particolare di \func{dup2}. È attraverso queste
+funzioni infatti che è possibile dirottare gli stream standard dei processi
 (che abbiamo visto in sez.~\ref{sec:file_std_descr} e
 sez.~\ref{sec:file_std_stream}) sulla pipe. In
 fig.~\ref{fig:ipc_barcodepage_code} abbiamo riportato il corpo del programma,
-il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
+il cui codice completo è disponibile nel file \file{BarCodePage.c} che si
 trova nella directory dei sorgenti.
 
-
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
@@ -200,18 +201,18 @@ trova nella directory dei sorgenti.
   \label{fig:ipc_barcodepage_code}
 \end{figure}
 
-La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
+La prima operazione del programma (\texttt{\small 4--12}) è quella di creare
 le due pipe che serviranno per la comunicazione fra i due comandi utilizzati
 per produrre il codice a barre; si ha cura di controllare la riuscita della
 chiamata, inviando in caso di errore un messaggio invece dell'immagine
-richiesta.\footnote{la funzione \func{WriteMess} non è riportata in
+richiesta.\footnote{la funzione \func{WriteMess} non è riportata in
   fig.~\ref{fig:ipc_barcodepage_code}; essa si incarica semplicemente di
   formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
   \textit{mime type}, e formattando il messaggio in HTML, in modo che
   quest'ultimo possa essere visualizzato correttamente da un browser.}
 
-Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
-primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
+Una volta create le pipe, il programma può creare (\texttt{\small 13-17}) il
+primo processo figlio, che si incaricherà (\texttt{\small 19--25}) di eseguire
 \cmd{barcode}. Quest'ultimo legge dallo standard input una stringa di
 caratteri, la converte nell'immagine PostScript del codice a barre ad essa
 corrispondente, e poi scrive il risultato direttamente sullo standard output.
@@ -229,54 +230,54 @@ output (\texttt{\small 23}).
 
 In questo modo all'esecuzione (\texttt{\small 25}) di \cmd{barcode} (cui si
 passa in \var{size} la dimensione della pagina per l'immagine) quest'ultimo
-leggerà dalla prima pipe la stringa da codificare che gli sarà inviata dal
-padre, e scriverà l'immagine PostScript del codice a barre sulla seconda.
+leggerà dalla prima pipe la stringa da codificare che gli sarà inviata dal
+padre, e scriverà l'immagine PostScript del codice a barre sulla seconda.
 
 Al contempo una volta lanciato il primo figlio, il processo padre prima chiude
 (\texttt{\small 26}) il capo inutilizzato della prima pipe (quello in input) e
 poi scrive (\texttt{\small 27}) la stringa da convertire sul capo in output,
-così che \cmd{barcode} possa riceverla dallo standard input. A questo punto
-l'uso della prima pipe da parte del padre è finito ed essa può essere
+così che \cmd{barcode} possa riceverla dallo standard input. A questo punto
+l'uso della prima pipe da parte del padre è finito ed essa può essere
 definitivamente chiusa (\texttt{\small 28}), si attende poi (\texttt{\small
   29}) che l'esecuzione di \cmd{barcode} sia completata.
 
-Alla conclusione della sua esecuzione \cmd{barcode} avrà inviato l'immagine
+Alla conclusione della sua esecuzione \cmd{barcode} avrà inviato l'immagine
 PostScript del codice a barre sul capo in scrittura della seconda pipe; a
-questo punto si può eseguire la seconda conversione, da PS a JPEG, usando il
+questo punto si può eseguire la seconda conversione, da PS a JPEG, usando il
 programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un secondo
-processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo programma
+processo figlio, che poi (\texttt{\small 35--42}) eseguirà questo programma
 leggendo l'immagine PostScript creata da \cmd{barcode} dallo standard input,
 per convertirla in JPEG.
 
-Per fare tutto ciò anzitutto si chiude (\texttt{\small 37}) il capo in
+Per fare tutto ciò anzitutto si chiude (\texttt{\small 37}) il capo in
 scrittura della seconda pipe, e se ne collega (\texttt{\small 38}) il capo in
 lettura allo standard input. Per poter formattare l'output del programma in
 maniera utilizzabile da un browser, si provvede anche \texttt{\small 40}) alla
 scrittura dell'apposita stringa di identificazione del mime-type in testa allo
-standard output. A questo punto si può invocare \texttt{\small 41}) \cmd{gs},
+standard output. A questo punto si può invocare \texttt{\small 41}) \cmd{gs},
 provvedendo gli appositi switch che consentono di leggere il file da
 convertire dallo standard input e di inviare la conversione sullo standard
 output.
 
 Per completare le operazioni il processo padre chiude (\texttt{\small 44}) il
 capo in scrittura della seconda pipe, e attende la conclusione del figlio
-(\texttt{\small 45}); a questo punto può (\texttt{\small 46}) uscire. Si tenga
-conto che l'operazione di chiudere il capo in scrittura della seconda pipe è
+(\texttt{\small 45}); a questo punto può (\texttt{\small 46}) uscire. Si tenga
+conto che l'operazione di chiudere il capo in scrittura della seconda pipe è
 necessaria, infatti, se non venisse chiusa, \cmd{gs}, che legge il suo
 standard input da detta pipe, resterebbe bloccato in attesa di ulteriori dati
-in ingresso (l'unico modo che un programma ha per sapere che l'input è
-terminato è rilevare che lo standard input è stato chiuso), e la \func{wait}
+in ingresso (l'unico modo che un programma ha per sapere che l'input è
+terminato è rilevare che lo standard input è stato chiuso), e la \func{wait}
 non ritornerebbe.
 
 
 \subsection{Le funzioni \func{popen} e \func{pclose}}
 \label{sec:ipc_popen}
 
-Come si è visto la modalità più comune di utilizzo di una pipe è quella di
+Come si è visto la modalità più comune di utilizzo di una pipe è quella di
 utilizzarla per fare da tramite fra output ed input di due programmi invocati
 in sequenza; per questo motivo lo standard POSIX.2 ha introdotto due funzioni
 che permettono di sintetizzare queste operazioni. La prima di esse si chiama
-\funcd{popen} ed il suo prototipo è:
+\funcd{popen} ed il suo prototipo è:
 \begin{prototype}{stdio.h}
 {FILE *popen(const char *command, const char *type)}
 
@@ -286,27 +287,27 @@ stream restituito come valore di ritorno.
   
 \bodydesc{La funzione restituisce l'indirizzo dello stream associato alla pipe
   in caso di successo e \val{NULL} per un errore, nel qual caso \var{errno}
-  potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
-  e \func{fork} o \errcode{EINVAL} se \param{type} non è valido.}
+  potrà assumere i valori relativi alle sottostanti invocazioni di \func{pipe}
+  e \func{fork} o \errcode{EINVAL} se \param{type} non è valido.}
 \end{prototype}
 
 La funzione crea una pipe, esegue una \func{fork}, ed invoca il programma
 \param{command} attraverso la shell (in sostanza esegue \file{/bin/sh} con il
 flag \code{-c}); l'argomento \param{type} deve essere una delle due stringhe
-\verb|"w"| o \verb|"r"|, per indicare se la pipe sarà collegata allo standard
+\verb|"w"| o \verb|"r"|, per indicare se la pipe sarà collegata allo standard
 input o allo standard output del comando invocato.
 
 La funzione restituisce il puntatore allo stream associato alla pipe creata,
-che sarà aperto in sola lettura (e quindi associato allo standard output del
+che sarà aperto in sola lettura (e quindi associato allo standard output del
 programma indicato) in caso si sia indicato \code{"r"}, o in sola scrittura (e
 quindi associato allo standard input) in caso di \code{"w"}.
 
-Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
-stream visti in cap.~\ref{cha:files_std_interface}, anche se è collegato ad
-una pipe e non ad un file, e viene sempre aperto in modalità
+Lo stream restituito da \func{popen} è identico a tutti gli effetti ai file
+stream visti in cap.~\ref{cha:files_std_interface}, anche se è collegato ad
+una pipe e non ad un file, e viene sempre aperto in modalità
 \textit{fully-buffered} (vedi sez.~\ref{sec:file_buffering}); l'unica
-differenza con gli usuali stream è che dovrà essere chiuso dalla seconda delle
-due nuove funzioni, \funcd{pclose}, il cui prototipo è:
+differenza con gli usuali stream è che dovrà essere chiuso dalla seconda delle
+due nuove funzioni, \funcd{pclose}, il cui prototipo è:
 \begin{prototype}{stdio.h}
 {int pclose(FILE *stream)}
 
@@ -323,55 +324,55 @@ attendendo la terminazione del processo ad essa associato.
 
 Per illustrare l'uso di queste due funzioni riprendiamo il problema
 precedente: il programma mostrato in fig.~\ref{fig:ipc_barcodepage_code} per
-quanto funzionante, è (volutamente) codificato in maniera piuttosto complessa,
-inoltre nella pratica sconta un problema di \cmd{gs} che non è in
+quanto funzionante, è (volutamente) codificato in maniera piuttosto complessa,
+inoltre nella pratica sconta un problema di \cmd{gs} che non è in
 grado\footnote{nella versione GNU Ghostscript 6.53 (2002-02-13).} di
 riconoscere correttamente l'Encapsulated PostScript, per cui deve essere usato
 il PostScript e tutte le volte viene generata una pagina intera, invece che
 una immagine delle dimensioni corrispondenti al codice a barre.
 
 Se si vuole generare una immagine di dimensioni appropriate si deve usare un
-approccio diverso. Una possibilità sarebbe quella di ricorrere ad ulteriore
-programma, \cmd{epstopsf}, per convertire in PDF un file EPS (che può essere
+approccio diverso. Una possibilità sarebbe quella di ricorrere ad ulteriore
+programma, \cmd{epstopsf}, per convertire in PDF un file EPS (che può essere
 generato da \cmd{barcode} utilizzando lo switch \cmd{-E}).  Utilizzando un PDF
 al posto di un EPS \cmd{gs} esegue la conversione rispettando le dimensioni
 originarie del codice a barre e produce un JPEG di dimensioni corrette.
 
-Questo approccio però non funziona, per via di una delle caratteristiche
-principali delle pipe. Per poter effettuare la conversione di un PDF infatti è
+Questo approccio però non funziona, per via di una delle caratteristiche
+principali delle pipe. Per poter effettuare la conversione di un PDF infatti è
 necessario, per la struttura del formato, potersi spostare (con \func{lseek})
 all'interno del file da convertire; se si esegue la conversione con \cmd{gs}
-su un file regolare non ci sono problemi, una pipe però è rigidamente
+su un file regolare non ci sono problemi, una pipe però è rigidamente
 sequenziale, e l'uso di \func{lseek} su di essa fallisce sempre con un errore
 di \errcode{ESPIPE}, rendendo impossibile la conversione.  Questo ci dice che
-in generale la concatenazione di vari programmi funzionerà soltanto quando
+in generale la concatenazione di vari programmi funzionerà soltanto quando
 tutti prevedono una lettura sequenziale del loro input.
 
-Per questo motivo si è dovuto utilizzare un procedimento diverso, eseguendo
+Per questo motivo si è dovuto utilizzare un procedimento diverso, eseguendo
 prima la conversione (sempre con \cmd{gs}) del PS in un altro formato
-intermedio, il PPM,\footnote{il \textit{Portable PixMap file format} è un
-  formato usato spesso come formato intermedio per effettuare conversioni, è
+intermedio, il PPM,\footnote{il \textit{Portable PixMap file format} è un
+  formato usato spesso come formato intermedio per effettuare conversioni, è
   infatti molto facile da manipolare, dato che usa caratteri ASCII per
-  memorizzare le immagini, anche se per questo è estremamente inefficiente.}
-dal quale poi si può ottenere un'immagine di dimensioni corrette attraverso
-vari programmi di manipolazione (\cmd{pnmcrop}, \cmd{pnmmargin}) che può
+  memorizzare le immagini, anche se per questo è estremamente inefficiente.}
+dal quale poi si può ottenere un'immagine di dimensioni corrette attraverso
+vari programmi di manipolazione (\cmd{pnmcrop}, \cmd{pnmmargin}) che può
 essere infine trasformata in PNG (con \cmd{pnm2png}).
 
-In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
+In questo caso però occorre eseguire in sequenza ben quattro comandi diversi,
 inviando l'output di ciascuno all'input del successivo, per poi ottenere il
 risultato finale sullo standard output: un caso classico di utilizzazione
 delle pipe, in cui l'uso di \func{popen} e \func{pclose} permette di
 semplificare notevolmente la stesura del codice.
 
 Nel nostro caso, dato che ciascun processo deve scrivere il suo output sullo
-standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
-scrittura. Il codice del nuovo programma è riportato in
-fig.~\ref{fig:ipc_barcode_code}.  Come si può notare l'ordine di invocazione
-dei programmi è l'inverso di quello in cui ci si aspetta che vengano
+standard input del successivo, occorrerà usare \func{popen} aprendo la pipe in
+scrittura. Il codice del nuovo programma è riportato in
+fig.~\ref{fig:ipc_barcode_code}.  Come si può notare l'ordine di invocazione
+dei programmi è l'inverso di quello in cui ci si aspetta che vengano
 effettivamente eseguiti. Questo non comporta nessun problema dato che la
-lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
-per primo, si bloccherà in attesa di ricevere sullo standard input il
-risultato dell'elaborazione del precedente, benché quest'ultimo venga invocato
+lettura su una pipe è bloccante, per cui ciascun processo, per quanto lanciato
+per primo, si bloccherà in attesa di ricevere sullo standard input il
+risultato dell'elaborazione del precedente, benché quest'ultimo venga invocato
 dopo.
 
 \begin{figure}[!htb]
@@ -384,26 +385,26 @@ dopo.
   \label{fig:ipc_barcode_code}
 \end{figure}
 
-Nel nostro caso il primo passo (\texttt{\small 14}) è scrivere il mime-type
-sullo standard output; a questo punto il processo padre non necessita più di
-eseguire ulteriori operazioni sullo standard output e può tranquillamente
+Nel nostro caso il primo passo (\texttt{\small 14}) è scrivere il mime-type
+sullo standard output; a questo punto il processo padre non necessita più di
+eseguire ulteriori operazioni sullo standard output e può tranquillamente
 provvedere alla redirezione.
 
-Dato che i vari programmi devono essere lanciati in successione, si è
+Dato che i vari programmi devono essere lanciati in successione, si è
 approntato un ciclo (\texttt{\small 15--19}) che esegue le operazioni in
 sequenza: prima crea una pipe (\texttt{\small 17}) per la scrittura eseguendo
 il programma con \func{popen}, in modo che essa sia collegata allo standard
 input, e poi redirige (\texttt{\small 18}) lo standard output su detta pipe.
 
-In questo modo il primo processo ad essere invocato (che è l'ultimo della
-catena) scriverà ancora sullo standard output del processo padre, ma i
+In questo modo il primo processo ad essere invocato (che è l'ultimo della
+catena) scriverà ancora sullo standard output del processo padre, ma i
 successivi, a causa di questa redirezione, scriveranno sulla pipe associata
 allo standard input del processo invocato nel ciclo precedente.
 
-Alla fine tutto quello che resta da fare è lanciare (\texttt{\small 21}) il
-primo processo della catena, che nel caso è \cmd{barcode}, e scrivere
-(\texttt{\small 23}) la stringa del codice a barre sulla pipe, che è collegata
-al suo standard input, infine si può eseguire (\texttt{\small 24--27}) un
+Alla fine tutto quello che resta da fare è lanciare (\texttt{\small 21}) il
+primo processo della catena, che nel caso è \cmd{barcode}, e scrivere
+(\texttt{\small 23}) la stringa del codice a barre sulla pipe, che è collegata
+al suo standard input, infine si può eseguire (\texttt{\small 24--27}) un
 ciclo che chiuda, nell'ordine inverso rispetto a quello in cui le si sono
 create, tutte le pipe create con \func{pclose}.
 
@@ -411,60 +412,60 @@ create, tutte le pipe create con \func{pclose}.
 \subsection{Le \textit{pipe} con nome, o \textit{fifo}}
 \label{sec:ipc_named_pipe}
 
-Come accennato in sez.~\ref{sec:ipc_pipes} il problema delle \textit{pipe} è
+Come accennato in sez.~\ref{sec:ipc_pipes} il problema delle \textit{pipe} è
 che esse possono essere utilizzate solo da processi con un progenitore comune
 o nella relazione padre/figlio; per superare questo problema lo standard
 POSIX.1 ha definito dei nuovi oggetti, le \textit{fifo}, che hanno le stesse
 caratteristiche delle pipe, ma che invece di essere strutture interne del
 kernel, visibili solo attraverso un file descriptor, sono accessibili
-attraverso un inode\index{inode} che risiede sul filesystem, così che i
+attraverso un \index{inode} inode che risiede sul filesystem, così che i
 processi le possono usare senza dovere per forza essere in una relazione di
 \textsl{parentela}.
 
 Utilizzando una \textit{fifo} tutti i dati passeranno, come per le pipe,
 attraverso un apposito buffer nel kernel, senza transitare dal filesystem;
-l'inode\index{inode} allocato sul filesystem serve infatti solo a fornire un
+\index{inode} l'inode allocato sul filesystem serve infatti solo a fornire un
 punto di riferimento per i processi, che permetta loro di accedere alla stessa
-fifo; il comportamento delle funzioni di lettura e scrittura è identico a
+fifo; il comportamento delle funzioni di lettura e scrittura è identico a
 quello illustrato per le pipe in sez.~\ref{sec:ipc_pipes}.
 
-Abbiamo già visto in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e
+Abbiamo già visto in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e
 \func{mkfifo} che permettono di creare una fifo; per utilizzarne una un
-processo non avrà che da aprire il relativo file speciale o in lettura o
-scrittura; nel primo caso sarà collegato al capo di uscita della fifo, e dovrà
-leggere, nel secondo al capo di ingresso, e dovrà scrivere.
+processo non avrà che da aprire il relativo file speciale o in lettura o
+scrittura; nel primo caso sarà collegato al capo di uscita della fifo, e dovrà
+leggere, nel secondo al capo di ingresso, e dovrà scrivere.
 
-Il kernel crea una singola pipe per ciascuna fifo che sia stata aperta, che può
-essere acceduta contemporaneamente da più processi, sia in lettura che in
+Il kernel crea una singola pipe per ciascuna fifo che sia stata aperta, che può
+essere acceduta contemporaneamente da più processi, sia in lettura che in
 scrittura. Dato che per funzionare deve essere aperta in entrambe le
 direzioni, per una fifo di norma la funzione \func{open} si blocca se viene
-eseguita quando l'altro capo non è aperto.
+eseguita quando l'altro capo non è aperto.
 
-Le fifo però possono essere anche aperte in modalità \textsl{non-bloccante},
-nel qual caso l'apertura del capo in lettura avrà successo solo quando anche
-l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà
-l'errore di \errcode{ENXIO} fintanto che non verrà aperto il capo in lettura.
+Le fifo però possono essere anche aperte in modalità \textsl{non-bloccante},
+nel qual caso l'apertura del capo in lettura avrà successo solo quando anche
+l'altro capo è aperto, mentre l'apertura del capo in scrittura restituirà
+l'errore di \errcode{ENXIO} fintanto che non verrà aperto il capo in lettura.
 
-In Linux è possibile aprire le fifo anche in lettura/scrittura,\footnote{lo
+In Linux è possibile aprire le fifo anche in lettura/scrittura,\footnote{lo
   standard POSIX lascia indefinito il comportamento in questo caso.}
-operazione che avrà sempre successo immediato qualunque sia la modalità di
-apertura (bloccante e non bloccante); questo può essere utilizzato per aprire
+operazione che avrà sempre successo immediato qualunque sia la modalità di
+apertura (bloccante e non bloccante); questo può essere utilizzato per aprire
 comunque una fifo in scrittura anche se non ci sono ancora processi il
-lettura; è possibile anche usare la fifo all'interno di un solo processo, nel
-qual caso però occorre stare molto attenti alla possibili situazioni di
+lettura; è possibile anche usare la fifo all'interno di un solo processo, nel
+qual caso però occorre stare molto attenti alla possibili situazioni di
 stallo.\footnote{se si cerca di leggere da una fifo che non contiene dati si
-  avrà un deadlock\itindex{deadlock} immediato, dato che il processo si blocca
-  e non potrà quindi mai eseguire le funzioni di scrittura.}
+  avrà un \itindex{deadlock} deadlock immediato, dato che il processo si
+  blocca e non potrà quindi mai eseguire le funzioni di scrittura.}
 
-Per la loro caratteristica di essere accessibili attraverso il filesystem, è
+Per la loro caratteristica di essere accessibili attraverso il filesystem, è
 piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle
-situazioni un processo deve ricevere informazioni da altri. In questo caso è
+situazioni un processo deve ricevere informazioni da altri. In questo caso è
 fondamentale che le operazioni di scrittura siano atomiche; per questo si deve
-sempre tenere presente che questo è vero soltanto fintanto che non si supera
+sempre tenere presente che questo è vero soltanto fintanto che non si supera
 il limite delle dimensioni di \const{PIPE\_BUF} (si ricordi quanto detto in
 sez.~\ref{sec:ipc_pipes}).
 
-A parte il caso precedente, che resta probabilmente il più comune, Stevens
+A parte il caso precedente, che resta probabilmente il più comune, Stevens
 riporta in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
 \begin{itemize}
 \item Da parte dei comandi di shell, per evitare la creazione di file
@@ -472,25 +473,25 @@ riporta in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
   sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}).
   
 \item Come canale di comunicazione fra client ed server (il modello
-  \textit{client-server} è illustrato in sez.~\ref{sec:net_cliserv}).
+  \textit{client-server} è illustrato in sez.~\ref{sec:net_cliserv}).
 \end{itemize}
 
-Nel primo caso quello che si fa è creare tante fifo, da usare come standard
+Nel primo caso quello che si fa è creare tante fifo, da usare come standard
 input, quanti sono i processi a cui i vogliono inviare i dati, questi ultimi
 saranno stati posti in esecuzione ridirigendo lo standard input dalle fifo, si
-potrà poi eseguire il processo che fornisce l'output replicando quest'ultimo,
+potrà poi eseguire il processo che fornisce l'output replicando quest'ultimo,
 con il comando \cmd{tee}, sulle varie fifo.
 
-Il secondo caso è relativamente semplice qualora si debba comunicare con un
+Il secondo caso è relativamente semplice qualora si debba comunicare con un
 processo alla volta (nel qual caso basta usare due fifo, una per leggere ed
-una per scrivere), le cose diventano invece molto più complesse quando si
+una per scrivere), le cose diventano invece molto più complesse quando si
 vuole effettuare una comunicazione fra il server ed un numero imprecisato di
-client; se il primo infatti può ricevere le richieste attraverso una fifo
-``\textsl{nota}'', per le risposte non si può fare altrettanto, dato che, per
+client; se il primo infatti può ricevere le richieste attraverso una fifo
+``\textsl{nota}'', per le risposte non si può fare altrettanto, dato che, per
 la struttura sequenziale delle fifo, i client dovrebbero sapere, prima di
 leggerli, quando i dati inviati sono destinati a loro.
 
-Per risolvere questo problema, si può usare un'architettura come quella
+Per risolvere questo problema, si può usare un'architettura come quella
 illustrata in fig.~\ref{fig:ipc_fifo_server_arch} in cui i client inviano le
 richieste al server su una fifo nota mentre le risposte vengono reinviate dal
 server a ciascuno di essi su una fifo temporanea creata per l'occasione.
@@ -507,12 +508,12 @@ Come esempio di uso questa architettura e dell'uso delle fifo, abbiamo scritto
 un server di \textit{fortunes}, che restituisce, alle richieste di un client,
 un detto a caso estratto da un insieme di frasi; sia il numero delle frasi
 dell'insieme, che i file da cui esse vengono lette all'avvio, sono importabili
-da riga di comando. Il corpo principale del server è riportato in
-fig.~\ref{fig:ipc_fifo_server}, dove si è tralasciata la parte che tratta la
+da riga di comando. Il corpo principale del server è riportato in
+fig.~\ref{fig:ipc_fifo_server}, dove si è tralasciata la parte che tratta la
 gestione delle opzioni a riga di comando, che effettua il settaggio delle
 variabili \var{fortunefilename}, che indica il file da cui leggere le frasi,
 ed \var{n}, che indica il numero di frasi tenute in memoria, ad un valore
-diverso da quelli preimpostati. Il codice completo è nel file
+diverso da quelli preimpostati. Il codice completo è nel file
 \file{FortuneServer.c}.
 
 \begin{figure}[!htb]
@@ -530,80 +531,81 @@ Il server richiede (\texttt{\small 12}) che sia stata impostata una dimensione
 dell'insieme delle frasi non nulla, dato che l'inizializzazione del vettore
 \var{fortune} avviene solo quando questa dimensione viene specificata, la
 presenza di un valore nullo provoca l'uscita dal programma attraverso la
-routine (non riportata) che ne stampa le modalità d'uso.  Dopo di che installa
-(\texttt{\small 13--15}) la funzione che gestisce i segnali di interruzione
-(anche questa non è riportata in fig.~\ref{fig:ipc_fifo_server}) che si limita
-a rimuovere dal filesystem la fifo usata dal server per comunicare.
+funzione (non riportata) che ne stampa le modalità d'uso.  Dopo di che
+installa (\texttt{\small 13--15}) la funzione che gestisce i segnali di
+interruzione (anche questa non è riportata in fig.~\ref{fig:ipc_fifo_server})
+che si limita a rimuovere dal filesystem la fifo usata dal server per
+comunicare.
 
 Terminata l'inizializzazione (\texttt{\small 16}) si effettua la chiamata alla
 funzione \code{FortuneParse} che legge dal file specificato in
 \var{fortunefilename} le prime \var{n} frasi e le memorizza (allocando
 dinamicamente la memoria necessaria) nel vettore di puntatori \var{fortune}.
-Anche il codice della funzione non è riportato, in quanto non direttamente
+Anche il codice della funzione non è riportato, in quanto non direttamente
 attinente allo scopo dell'esempio.
 
-Il passo successivo (\texttt{\small 17--22}) è quello di creare con
-\func{mkfifo} la fifo nota sulla quale il server ascolterà le richieste,
-qualora si riscontri un errore il server uscirà (escludendo ovviamente il caso
+Il passo successivo (\texttt{\small 17--22}) è quello di creare con
+\func{mkfifo} la fifo nota sulla quale il server ascolterà le richieste,
+qualora si riscontri un errore il server uscirà (escludendo ovviamente il caso
 in cui la funzione \func{mkfifo} fallisce per la precedente esistenza della
 fifo).
 
-Una volta che si è certi che la fifo di ascolto esiste la procedura di
-inizializzazione è completata. A questo punto si può chiamare (\texttt{\small
+Una volta che si è certi che la fifo di ascolto esiste la procedura di
+inizializzazione è completata. A questo punto si può chiamare (\texttt{\small
   23}) la funzione \func{daemon} per far proseguire l'esecuzione del programma
-in background come demone.  Si può quindi procedere (\texttt{\small 24--33})
+in background come demone.  Si può quindi procedere (\texttt{\small 24--33})
 alla apertura della fifo: si noti che questo viene fatto due volte, prima in
 lettura e poi in scrittura, per evitare di dover gestire all'interno del ciclo
-principale il caso in cui il server è in ascolto ma non ci sono client che
-effettuano richieste.  Si ricordi infatti che quando una fifo è aperta solo
+principale il caso in cui il server è in ascolto ma non ci sono client che
+effettuano richieste.  Si ricordi infatti che quando una fifo è aperta solo
 dal capo in lettura, l'esecuzione di \func{read} ritorna con zero byte (si ha
-cioè una condizione di end-of-file).
+cioè una condizione di end-of-file).
 
-Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque
+Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque
 client non apre a sua volta la fifo nota in scrittura per effettuare la sua
-richiesta. Pertanto all'inizio non ci sono problemi, il client però, una volta
-ricevuta la risposta, uscirà, chiudendo tutti i file aperti, compresa la fifo.
+richiesta. Pertanto all'inizio non ci sono problemi, il client però, una volta
+ricevuta la risposta, uscirà, chiudendo tutti i file aperti, compresa la fifo.
 A questo punto il server resta (se non ci sono altri client che stanno
 effettuando richieste) con la fifo chiusa sul lato in lettura, ed in questo
-stato la funzione \func{read} non si bloccherà in attesa di input, ma
-ritornerà in continuazione, restituendo un end-of-file.\footnote{Si è usata
-  questa tecnica per compatibilità, Linux infatti supporta l'apertura delle
+stato la funzione \func{read} non si bloccherà in attesa di input, ma
+ritornerà in continuazione, restituendo un end-of-file.\footnote{si è usata
+  questa tecnica per compatibilità, Linux infatti supporta l'apertura delle
   fifo in lettura/scrittura, per cui si sarebbe potuto effettuare una singola
   apertura con \const{O\_RDWR}, la doppia apertura comunque ha il vantaggio
-  che non si può scrivere per errore sul capo aperto in sola lettura.}
+  che non si può scrivere per errore sul capo aperto in sola lettura.}
 
 Per questo motivo, dopo aver eseguito l'apertura in lettura (\texttt{\small
   24--28}),\footnote{di solito si effettua l'apertura del capo in lettura di
-  una fifo in modalità non bloccante, per evitare il rischio di uno stallo: se
-  infatti nessuno apre la fifo in scrittura il processo non ritornerà mai
-  dalla \func{open}. Nel nostro caso questo rischio non esiste, mentre è
+  una fifo in modalità non bloccante, per evitare il rischio di uno stallo: se
+  infatti nessuno apre la fifo in scrittura il processo non ritornerà mai
+  dalla \func{open}. Nel nostro caso questo rischio non esiste, mentre è
   necessario potersi bloccare in lettura in attesa di una richiesta.} si
 esegue una seconda apertura in scrittura (\texttt{\small 29--32}), scartando
-il relativo file descriptor, che non sarà mai usato, in questo modo però la
-fifo resta comunque aperta anche in scrittura, cosicché le successive chiamate
+il relativo file descriptor, che non sarà mai usato, in questo modo però la
+fifo resta comunque aperta anche in scrittura, cosicché le successive chiamate
 a \func{read} possono bloccarsi.
 
-A questo punto si può entrare nel ciclo principale del programma che fornisce
+A questo punto si può entrare nel ciclo principale del programma che fornisce
 le risposte ai client (\texttt{\small 34--50}); questo viene eseguito
 indefinitamente (l'uscita del server viene effettuata inviando un segnale, in
-modo da passare attraverso la routine di chiusura che cancella la fifo).
+modo da passare attraverso la funzione di chiusura che cancella la fifo).
 
-Il server è progettato per accettare come richieste dai client delle stringhe
+Il server è progettato per accettare come richieste dai client delle stringhe
 che contengono il nome della fifo sulla quale deve essere inviata la risposta.
 Per cui prima (\texttt{\small 35--39}) si esegue la lettura dalla stringa di
-richiesta dalla fifo nota (che a questo punto si bloccherà tutte le volte che
+richiesta dalla fifo nota (che a questo punto si bloccherà tutte le volte che
 non ci sono richieste). Dopo di che, una volta terminata la stringa
 (\texttt{\small 40}) e selezionato (\texttt{\small 41}) un numero casuale per
-ricavare la frase da inviare, si procederà (\texttt{\small 42--46})
+ricavare la frase da inviare, si procederà (\texttt{\small 42--46})
 all'apertura della fifo per la risposta, che poi \texttt{\small 47--48}) vi
-sarà scritta. Infine (\texttt{\small 49}) si chiude la fifo di risposta che
-non serve più.
+sarà scritta. Infine (\texttt{\small 49}) si chiude la fifo di risposta che
+non serve più.
 
-Il codice del client è invece riportato in fig.~\ref{fig:ipc_fifo_client},
-anche in questo caso si è omessa la gestione delle opzioni e la funzione che
+Il codice del client è invece riportato in fig.~\ref{fig:ipc_fifo_client},
+anche in questo caso si è omessa la gestione delle opzioni e la funzione che
 stampa a video le informazioni di utilizzo ed esce, riportando solo la sezione
 principale del programma e le definizioni delle variabili. Il codice completo
-è nel file \file{FortuneClient.c} dei sorgenti allegati.
+è nel file \file{FortuneClient.c} dei sorgenti allegati.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -616,64 +618,66 @@ principale del programma e le definizioni delle variabili. Il codice completo
   \label{fig:ipc_fifo_client}
 \end{figure}
 
-La prima istruzione (\texttt{\small 12}) compone il nome della fifo che dovrà
+La prima istruzione (\texttt{\small 12}) compone il nome della fifo che dovrà
 essere utilizzata per ricevere la risposta dal server.  Si usa il \acr{pid}
 del processo per essere sicuri di avere un nome univoco; dopo di che
 (\texttt{\small 13-18}) si procede alla creazione del relativo file, uscendo
-in caso di errore (a meno che il file non sia già presente sul filesystem).
+in caso di errore (a meno che il file non sia già presente sul filesystem).
 
-A questo punto il client può effettuare l'interrogazione del server, per
+A questo punto il client può effettuare l'interrogazione del server, per
 questo prima si apre la fifo nota (\texttt{\small 19--23}), e poi ci si scrive
 (\texttt{\small 24}) la stringa composta in precedenza, che contiene il nome
 della fifo da utilizzare per la risposta. Infine si richiude la fifo del
-server che a questo punto non serve più (\texttt{\small 25}).
+server che a questo punto non serve più (\texttt{\small 25}).
 
-Inoltrata la richiesta si può passare alla lettura della risposta; anzitutto
+Inoltrata la richiesta si può passare alla lettura della risposta; anzitutto
 si apre (\texttt{\small 26--30}) la fifo appena creata, da cui si deve
 riceverla, dopo di che si effettua una lettura (\texttt{\small 31})
-nell'apposito buffer; si è supposto, come è ragionevole, che le frasi inviate
+nell'apposito buffer; si è supposto, come è ragionevole, che le frasi inviate
 dal server siano sempre di dimensioni inferiori a \const{PIPE\_BUF},
-tralasciamo la gestione del caso in cui questo non è vero. Infine si stampa
+tralasciamo la gestione del caso in cui questo non è vero. Infine si stampa
 (\texttt{\small 32}) a video la risposta, si chiude (\texttt{\small 33}) la
 fifo e si cancella (\texttt{\small 34}) il relativo file.
 Si noti come la fifo per la risposta sia stata aperta solo dopo aver inviato
-la richiesta, se non si fosse fatto così si avrebbe avuto uno stallo, in
+la richiesta, se non si fosse fatto così si avrebbe avuto uno stallo, in
 quanto senza la richiesta, il server non avrebbe potuto aprirne il capo in
 scrittura e l'apertura si sarebbe bloccata indefinitamente.
 
 Verifichiamo allora il comportamento dei nostri programmi, in questo, come in
 altri esempi precedenti, si fa uso delle varie funzioni di servizio, che sono
 state raccolte nella libreria \file{libgapil.so}, per poter usare quest'ultima
-occorrerà definire la speciale variabile di ambiente \code{LD\_LIBRARY\_PATH}
+occorrerà definire la speciale variabile di ambiente \code{LD\_LIBRARY\_PATH}
 in modo che il linker dinamico possa accedervi.
 
-In generale questa variabile indica il \itindex{pathname}\textit{pathname}
+In generale questa variabile indica il \itindex{pathname} \textit{pathname}
 della directory contenente la libreria. Nell'ipotesi (che daremo sempre per
 verificata) che si facciano le prove direttamente nella directory dei sorgenti
 (dove di norma vengono creati sia i programmi che la libreria), il comando da
-dare sarà \code{export LD\_LIBRARY\_PATH=./}; a questo punto potremo lanciare
+dare sarà \code{export LD\_LIBRARY\_PATH=./}; a questo punto potremo lanciare
 il server, facendogli leggere una decina di frasi, con:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ./fortuned -n10
-\end{verbatim}
+\end{Verbatim}
+%$
 
 Avendo usato \func{daemon} per eseguire il server in background il comando
-ritornerà immediatamente, ma potremo verificare con \cmd{ps} che in effetti il
+ritornerà immediatamente, ma potremo verificare con \cmd{ps} che in effetti il
 programma resta un esecuzione in background, e senza avere associato un
 terminale di controllo (si ricordi quanto detto in sez.~\ref{sec:sess_daemon}):
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ps aux
 ...
 piccardi 27489  0.0  0.0  1204  356 ?        S    01:06   0:00 ./fortuned -n10
 piccardi 27492  3.0  0.1  2492  764 pts/2    R    01:08   0:00 ps aux
-\end{verbatim}%$
-e si potrà verificare anche che in \file{/tmp} è stata creata la fifo di
+\end{Verbatim}
+%$
+e si potrà verificare anche che in \file{/tmp} è stata creata la fifo di
 ascolto \file{fortune.fifo}. A questo punto potremo interrogare il server con
-il programma client; otterremo così:
-\begin{verbatim}
+il programma client; otterremo così:
+\begin{Verbatim}
 [piccardi@gont sources]$ ./fortune
 Linux ext2fs has been stable for a long time, now it's time to break it
-        -- Linuxkongreß '95 in Berlin
+        -- Linuxkongreß '95 in Berlin
 [piccardi@gont sources]$ ./fortune
 Let's call it an accidental feature.
         --Larry Wall
@@ -688,28 +692,28 @@ Let's call it an accidental feature.
         -- William E. Roadcap
 [piccardi@gont sources]$ ./fortune
 Linux ext2fs has been stable for a long time, now it's time to break it
-        -- Linuxkongreß '95 in Berlin
-\end{verbatim}%$
+        -- Linuxkongreß '95 in Berlin
+\end{Verbatim}
+%$
 e ripetendo varie volte il comando otterremo, in ordine casuale, le dieci
 frasi tenute in memoria dal server.
 
-Infine per chiudere il server basterà inviare un segnale di terminazione con
+Infine per chiudere il server basterà inviare un segnale di terminazione con
 \code{killall fortuned} e potremo verificare che il gestore del segnale ha
 anche correttamente cancellato la fifo di ascolto da \file{/tmp}.
 
-Benché il nostro sistema client-server funzioni, la sua struttura è piuttosto
+Benché il nostro sistema client-server funzioni, la sua struttura è piuttosto
 complessa e continua ad avere vari inconvenienti\footnote{lo stesso Stevens,
   che esamina questa architettura in \cite{APUE}, nota come sia impossibile
-  per il server sapere se un client è andato in crash, con la possibilità di
+  per il server sapere se un client è andato in crash, con la possibilità di
   far restare le fifo temporanee sul filesystem, di come sia necessario
-  intercettare \const{SIGPIPE} dato che un client può terminare dopo aver
+  intercettare \const{SIGPIPE} dato che un client può terminare dopo aver
   fatto una richiesta, ma prima che la risposta sia inviata (cosa che nel
-  nostro esempio non è stata fatta).}; in generale infatti l'interfaccia delle
-fifo non è adatta a risolvere questo tipo di problemi, che possono essere
-affrontati in maniera più semplice ed efficace o usando i
-\textit{socket}\index{socket} (che tratteremo in dettaglio a partire da
-cap.~\ref{cha:socket_intro}) o ricorrendo a meccanismi di comunicazione
-diversi, come quelli che esamineremo in seguito.
+  nostro esempio non è stata fatta).}; in generale infatti l'interfaccia delle
+fifo non è adatta a risolvere questo tipo di problemi, che possono essere
+affrontati in maniera più semplice ed efficace o usando i socket (che
+tratteremo in dettaglio a partire da cap.~\ref{cha:socket_intro}) o ricorrendo
+a meccanismi di comunicazione diversi, come quelli che esamineremo in seguito.
 
 
 
@@ -717,79 +721,78 @@ diversi, come quelli che esamineremo in seguito.
 \label{sec:ipc_socketpair}
 
 Un meccanismo di comunicazione molto simile alle pipe, ma che non presenta il
-problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti
+problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti
 \textsl{socket locali} (o \textit{Unix domain socket}). Tratteremo l'argomento
-dei \textit{socket}\index{socket} in cap.~\ref{cha:socket_intro},\footnote{si
-  tratta comunque di oggetti di comunicazione che, come le pipe, sono
-  utilizzati attraverso dei file descriptor.} nell'ambito dell'interfaccia
-generale che essi forniscono per la programmazione di rete; e vedremo anche
+dei socket in cap.~\ref{cha:socket_intro},\footnote{si tratta comunque di
+  oggetti di comunicazione che, come le pipe, sono utilizzati attraverso dei
+  file descriptor.} nell'ambito dell'interfaccia generale che essi forniscono
+per la programmazione di rete; e vedremo anche
 (in~sez.~\ref{sec:sock_sa_local}) come si possono definire dei file speciali
-(di tipo \textit{socket}, analoghi a quello associati alle fifo) cui si accede
-però attraverso quella medesima interfaccia; vale però la pena esaminare qui
-una modalità di uso dei socket locali\footnote{la funzione \func{socketpair} è
-  stata introdotta in BSD4.4, ma è supportata in genere da qualunque sistema
+(di tipo socket, analoghi a quello associati alle fifo) cui si accede però
+attraverso quella medesima interfaccia; vale però la pena esaminare qui una
+modalità di uso dei socket locali\footnote{la funzione \func{socketpair} è
+  stata introdotta in BSD4.4, ma è supportata in genere da qualunque sistema
   che fornisca l'interfaccia dei socket.} che li rende sostanzialmente
 identici ad una pipe bidirezionale.
 
 La funzione \funcd{socketpair} infatti consente di creare una coppia di file
-descriptor connessi fra di loro (tramite un socket\index{socket}, appunto),
-senza dover ricorrere ad un file speciale sul filesystem, i descrittori sono
-del tutto analoghi a quelli che si avrebbero con una chiamata a \func{pipe},
-con la sola differenza è che in questo caso il flusso dei dati può essere
-effettuato in entrambe le direzioni. Il prototipo della funzione è:
+descriptor connessi fra di loro (tramite un socket, appunto), senza dover
+ricorrere ad un file speciale sul filesystem, i descrittori sono del tutto
+analoghi a quelli che si avrebbero con una chiamata a \func{pipe}, con la sola
+differenza è che in questo caso il flusso dei dati può essere effettuato in
+entrambe le direzioni. Il prototipo della funzione è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/socket.h} 
   
   \funcdecl{int socketpair(int domain, int type, int protocol, int sv[2])}
   
-  Crea una coppia di socket\index{socket} connessi fra loro.
+  Crea una coppia di socket connessi fra loro.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EAFNOSUPPORT}] I socket\index{socket} locali non sono
-    supportati.
-  \item[\errcode{EPROTONOSUPPORT}] Il protocollo specificato non è supportato.
-  \item[\errcode{EOPNOTSUPP}] Il protocollo specificato non supporta la
-  creazione di coppie di socket\index{socket}.
+  \item[\errcode{EAFNOSUPPORT}] i socket locali non sono supportati.
+  \item[\errcode{EPROTONOSUPPORT}] il protocollo specificato non è supportato.
+  \item[\errcode{EOPNOTSUPP}] il protocollo specificato non supporta la
+  creazione di coppie di socket.
   \end{errlist}
   ed inoltre \errval{EMFILE},  \errval{EFAULT}.
 }
 \end{functions}
 
 La funzione restituisce in \param{sv} la coppia di descrittori connessi fra di
-loro: quello che si scrive su uno di essi sarà ripresentato in input
+loro: quello che si scrive su uno di essi sarà ripresentato in input
 sull'altro e viceversa. Gli argomenti \param{domain}, \param{type} e
-\param{protocol} derivano dall'interfaccia dei socket\index{socket} (vedi
-sez.~\ref{sec:sock_creation}) che è quella che fornisce il substrato per
+\param{protocol} derivano dall'interfaccia dei socket (vedi
+sez.~\ref{sec:sock_creation}) che è quella che fornisce il substrato per
 connettere i due descrittori, ma in questo caso i soli valori validi che
 possono essere specificati sono rispettivamente \const{AF\_UNIX},
 \const{SOCK\_STREAM} e \val{0}.
 
-L'utilità di chiamare questa funzione per evitare due chiamate a \func{pipe}
-può sembrare limitata; in realtà l'utilizzo di questa funzione (e dei
-socket\index{socket} locali in generale) permette di trasmettere attraverso le
-linea non solo dei dati, ma anche dei file descriptor: si può cioè passare da
-un processo ad un altro un file descriptor, con una sorta di duplicazione
-dello stesso non all'interno di uno stesso processo, ma fra processi distinti
-(torneremo su questa funzionalità in sez.~\ref{sec:xxx_fd_passing}).
+L'utilità di chiamare questa funzione per evitare due chiamate a \func{pipe}
+può sembrare limitata; in realtà l'utilizzo di questa funzione (e dei socket
+locali in generale) permette di trasmettere attraverso le linea non solo dei
+dati, ma anche dei file descriptor: si può cioè passare da un processo ad un
+altro un file descriptor, con una sorta di duplicazione dello stesso non
+all'interno di uno stesso processo, ma fra processi distinti (torneremo su
+questa funzionalità in sez.~\ref{sec:sock_fd_passing}).
 
 
 \section{Il sistema di comunicazione fra processi di System V}
 \label{sec:ipc_sysv}
 
-Benché le pipe e le fifo siano ancora ampiamente usate, esse scontano il
-limite fondamentale che il meccanismo di comunicazione che forniscono è
+Benché le pipe e le fifo siano ancora ampiamente usate, esse scontano il
+limite fondamentale che il meccanismo di comunicazione che forniscono è
 rigidamente sequenziale: una situazione in cui un processo scrive qualcosa che
-molti altri devono poter leggere non può essere implementata con una pipe.
+molti altri devono poter leggere non può essere implementata con una pipe.
 
 Per questo nello sviluppo di System V vennero introdotti una serie di nuovi
 oggetti per la comunicazione fra processi ed una nuova interfaccia di
-programmazione, che fossero in grado di garantire una maggiore flessibilità.
+programmazione, che fossero in grado di garantire una maggiore flessibilità.
 In questa sezione esamineremo come Linux supporta quello che viene chiamato il
 \textsl{Sistema di comunicazione fra processi} di System V, cui da qui in
-avanti faremo riferimento come \textit{SysV IPC} (dove IPC è la sigla di
+avanti faremo riferimento come \textit{SysV IPC} (dove IPC è la sigla di
 \textit{Inter-Process Comunication}).
 
 
@@ -797,42 +800,42 @@ avanti faremo riferimento come \textit{SysV IPC} (dove IPC 
 \subsection{Considerazioni generali}
 \label{sec:ipc_sysv_generic}
 
-La principale caratteristica del \textit{SysV IPC} è quella di essere basato
+La principale caratteristica del \textit{SysV IPC} è quella di essere basato
 su oggetti permanenti che risiedono nel kernel. Questi, a differenza di quanto
 avviene per i file descriptor, non mantengono un contatore dei riferimenti, e
-non vengono cancellati dal sistema una volta che non sono più in uso.
+non vengono cancellati dal sistema una volta che non sono più in uso.
 
-Questo comporta due problemi: il primo è che, al contrario di quanto avviene
+Questo comporta due problemi: il primo è che, al contrario di quanto avviene
 per pipe e fifo, la memoria allocata per questi oggetti non viene rilasciata
-automaticamente quando non c'è più nessuno che li utilizzi, ed essi devono
+automaticamente quando non c'è più nessuno che li utilizzi, ed essi devono
 essere cancellati esplicitamente, se non si vuole che restino attivi fino al
-riavvio del sistema. Il secondo problema è che, dato che non c'è, come per i
+riavvio del sistema. Il secondo problema è che, dato che non c'è, come per i
 file, un contatore del numero di riferimenti che ne indichi l'essere in uso,
 essi possono essere cancellati anche se ci sono dei processi che li stanno
 utilizzando, con tutte le conseguenze (negative) del caso.
 
-Un'ulteriore caratteristica negativa è che gli oggetti usati nel \textit{SysV
+Un'ulteriore caratteristica negativa è che gli oggetti usati nel \textit{SysV
   IPC} vengono creati direttamente dal kernel, e sono accessibili solo
-specificando il relativo \textsl{identificatore}. Questo è un numero
+specificando il relativo \textsl{identificatore}. Questo è un numero
 progressivo (un po' come il \acr{pid} dei processi) che il kernel assegna a
 ciascuno di essi quanto vengono creati (sul procedimento di assegnazione
 torneremo in sez.~\ref{sec:ipc_sysv_id_use}). L'identificatore viene restituito
-dalle funzioni che creano l'oggetto, ed è quindi locale al processo che le ha
+dalle funzioni che creano l'oggetto, ed è quindi locale al processo che le ha
 eseguite. Dato che l'identificatore viene assegnato dinamicamente dal kernel
-non è possibile prevedere quale sarà, né utilizzare un qualche valore statico,
-si pone perciò il problema di come processi diversi possono accedere allo
+non è possibile prevedere quale sarà, né utilizzare un qualche valore statico,
+si pone perciò il problema di come processi diversi possono accedere allo
 stesso oggetto.
 
 Per risolvere il problema nella struttura \struct{ipc\_perm} che il kernel
 associa a ciascun oggetto, viene mantenuto anche un campo apposito che
 contiene anche una \textsl{chiave}, identificata da una variabile del tipo
 primitivo \type{key\_t}, da specificare in fase di creazione dell'oggetto, e
-tramite la quale è possibile ricavare l'identificatore.\footnote{in sostanza
+tramite la quale è possibile ricavare l'identificatore.\footnote{in sostanza
   si sposta il problema dell'accesso dalla classificazione in base
   all'identificatore alla classificazione in base alla chiave, una delle tante
   complicazioni inutili presenti nel \textit{SysV IPC}.} Oltre la chiave, la
-struttura, la cui definizione è riportata in fig.~\ref{fig:ipc_ipc_perm},
-mantiene varie proprietà ed informazioni associate all'oggetto.
+struttura, la cui definizione è riportata in fig.~\ref{fig:ipc_ipc_perm},
+mantiene varie proprietà ed informazioni associate all'oggetto.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -846,25 +849,25 @@ mantiene varie propriet
 \end{figure}
 
 Usando la stessa chiave due processi diversi possono ricavare l'identificatore
-associato ad un oggetto ed accedervi. Il problema che sorge a questo punto è
+associato ad un oggetto ed accedervi. Il problema che sorge a questo punto è
 come devono fare per accordarsi sull'uso di una stessa chiave. Se i processi
-sono \textsl{imparentati} la soluzione è relativamente semplice, in tal caso
-infatti si può usare il valore speciale \texttt{IPC\_PRIVATE} per creare un
-nuovo oggetto nel processo padre, l'identificatore così ottenuto sarà
-disponibile in tutti i figli, e potrà essere passato come argomento attraverso
+sono \textsl{imparentati} la soluzione è relativamente semplice, in tal caso
+infatti si può usare il valore speciale \texttt{IPC\_PRIVATE} per creare un
+nuovo oggetto nel processo padre, l'identificatore così ottenuto sarà
+disponibile in tutti i figli, e potrà essere passato come argomento attraverso
 una \func{exec}.
 
-Però quando i processi non sono \textsl{imparentati} (come capita tutte le
-volte che si ha a che fare con un sistema client-server) tutto questo non è
+Però quando i processi non sono \textsl{imparentati} (come capita tutte le
+volte che si ha a che fare con un sistema client-server) tutto questo non è
 possibile; si potrebbe comunque salvare l'identificatore su un file noto, ma
 questo ovviamente comporta lo svantaggio di doverselo andare a rileggere.  Una
-alternativa più efficace è quella che i programmi usino un valore comune per
-la chiave (che ad esempio può essere dichiarato in un header comune), ma c'è
-sempre il rischio che questa chiave possa essere stata già utilizzata da
+alternativa più efficace è quella che i programmi usino un valore comune per
+la chiave (che ad esempio può essere dichiarato in un header comune), ma c'è
+sempre il rischio che questa chiave possa essere stata già utilizzata da
 qualcun altro.  Dato che non esiste una convenzione su come assegnare queste
 chiavi in maniera univoca l'interfaccia mette a disposizione una funzione
 apposita, \funcd{ftok}, che permette di ottenere una chiave specificando il
-nome di un file ed un numero di versione; il suo prototipo è:
+nome di un file ed un numero di versione; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -874,44 +877,45 @@ nome di un file ed un numero di versione; il suo prototipo 
   Restituisce una chiave per identificare un oggetto del \textit{SysV IPC}.
   
   \bodydesc{La funzione restituisce la chiave in caso di successo e -1
-    altrimenti, nel qual caso \var{errno} sarà uno dei possibili codici di
+    altrimenti, nel qual caso \var{errno} sarà uno dei possibili codici di
     errore di \func{stat}.}
 \end{functions}
 
 La funzione determina un valore della chiave sulla base di \param{pathname},
-che deve specificare il \itindex{pathname}\textit{pathname} di un file
+che deve specificare il \itindex{pathname} \textit{pathname} di un file
 effettivamente esistente e di un numero di progetto \param{proj\_id)}, che di
 norma viene specificato come carattere, dato che ne vengono utilizzati solo
 gli 8 bit meno significativi.\footnote{nelle libc4 e libc5, come avviene in
-  SunOS, l'argomento \param{proj\_id} è dichiarato tipo \ctyp{char}, le
+  SunOS, l'argomento \param{proj\_id} è dichiarato tipo \ctyp{char}, le
   \acr{glibc} usano il prototipo specificato da XPG4, ma vengono lo stesso
   utilizzati gli 8 bit meno significativi.}
 
-Il problema è che anche così non c'è la sicurezza che il valore della chiave
-sia univoco, infatti esso è costruito combinando il byte di \param{proj\_id)}
-con i 16 bit meno significativi dell'inode\index{inode} del file
+Il problema è che anche così non c'è la sicurezza che il valore della chiave
+sia univoco, infatti esso è costruito combinando il byte di \param{proj\_id)}
+con i 16 bit meno significativi \index{inode} dell'inode del file
 \param{pathname} (che vengono ottenuti attraverso \func{stat}, da cui derivano
 i possibili errori), e gli 8 bit meno significativi del numero del dispositivo
-su cui è il file.  Diventa perciò relativamente facile ottenere delle
-collisioni, specie se i file sono su dispositivi con lo stesso \textit{minor
-  number}, come \file{/dev/hda1} e \file{/dev/sda1}.
+su cui è il file.  Diventa perciò relativamente facile ottenere delle
+collisioni, specie se i file sono su dispositivi con lo stesso
+\itindex{minor~number} \textit{minor number}, come \file{/dev/hda1} e
+\file{/dev/sda1}.
 
-In genere quello che si fa è utilizzare un file comune usato dai programmi che
+In genere quello che si fa è utilizzare un file comune usato dai programmi che
 devono comunicare (ad esempio un header comune, o uno dei programmi che devono
 usare l'oggetto in questione), utilizzando il numero di progetto per ottenere
 le chiavi che interessano. In ogni caso occorre sempre controllare, prima di
-creare un oggetto, che la chiave non sia già stata utilizzata. Se questo va
+creare un oggetto, che la chiave non sia già stata utilizzata. Se questo va
 bene in fase di creazione, le cose possono complicarsi per i programmi che
 devono solo accedere, in quanto, a parte gli eventuali controlli sugli altri
-attributi di \struct{ipc\_perm}, non esiste una modalità semplice per essere
+attributi di \struct{ipc\_perm}, non esiste una modalità semplice per essere
 sicuri che l'oggetto associato ad una certa chiave sia stato effettivamente
 creato da chi ci si aspetta.
 
-Questo è, insieme al fatto che gli oggetti sono permanenti e non mantengono un
+Questo è, insieme al fatto che gli oggetti sono permanenti e non mantengono un
 contatore di riferimenti per la cancellazione automatica, il principale
-problema del \textit{SysV IPC}. Non esiste infatti una modalità chiara per
+problema del \textit{SysV IPC}. Non esiste infatti una modalità chiara per
 identificare un oggetto, come sarebbe stato se lo si fosse associato ad in
-file, e tutta l'interfaccia è inutilmente complessa.  Per questo ne è stata
+file, e tutta l'interfaccia è inutilmente complessa.  Per questo ne è stata
 effettuata una revisione completa nello standard POSIX.1b, che tratteremo in
 sez.~\ref{sec:ipc_posix}.
 
@@ -923,21 +927,21 @@ Oltre alle chiavi, abbiamo visto che ad ogni oggetto sono associate in
 \struct{ipc\_perm} ulteriori informazioni, come gli identificatori del creatore
 (nei campi \var{cuid} e \var{cgid}) e del proprietario (nei campi \var{uid} e
 \var{gid}) dello stesso, e un insieme di permessi (nel campo \var{mode}). In
-questo modo è possibile definire un controllo di accesso sugli oggetti di IPC,
+questo modo è possibile definire un controllo di accesso sugli oggetti di IPC,
 simile a quello che si ha per i file (vedi sez.~\ref{sec:file_perm_overview}).
 
-Benché questo controllo di accesso sia molto simile a quello dei file, restano
-delle importanti differenze. La prima è che il permesso di esecuzione non
-esiste (e se specificato viene ignorato), per cui si può parlare solo di
-permessi di lettura e scrittura (nel caso dei semafori poi quest'ultimo è più
+Benché questo controllo di accesso sia molto simile a quello dei file, restano
+delle importanti differenze. La prima è che il permesso di esecuzione non
+esiste (e se specificato viene ignorato), per cui si può parlare solo di
+permessi di lettura e scrittura (nel caso dei semafori poi quest'ultimo è più
 propriamente un permesso di modifica). I valori di \var{mode} sono gli stessi
 ed hanno lo stesso significato di quelli riportati in
-tab.~\ref{tab:file_mode_flags}\footnote{se però si vogliono usare le costanti
-  simboliche ivi definite occorrerà includere il file \file{sys/stat.h},
+tab.~\ref{tab:file_mode_flags}\footnote{se però si vogliono usare le costanti
+  simboliche ivi definite occorrerà includere il file \file{sys/stat.h},
   alcuni sistemi definiscono le costanti \const{MSG\_R} (\texttt{0400}) e
   \const{MSG\_W} (\texttt{0200}) per indicare i permessi base di lettura e
   scrittura per il proprietario, da utilizzare, con gli opportuni shift, pure
-  per il gruppo e gli altri, in Linux, visto la loro scarsa utilità, queste
+  per il gruppo e gli altri, in Linux, visto la loro scarsa utilità, queste
   costanti non sono definite.} e come per i file definiscono gli accessi per
 il proprietario, il suo gruppo e tutti gli altri.
 
@@ -947,47 +951,47 @@ rispettivamente al valore dell'user-ID e del group-ID effettivo del processo
 che ha chiamato la funzione, ma, mentre i campi \var{uid} e \var{gid} possono
 essere cambiati, i campi \var{cuid} e \var{cgid} restano sempre gli stessi.
 
-Il controllo di accesso è effettuato a due livelli. Il primo livello è nelle
+Il controllo di accesso è effettuato a due livelli. Il primo livello è nelle
 funzioni che richiedono l'identificatore di un oggetto data la chiave. Queste
 specificano tutte un argomento \param{flag}, in tal caso quando viene
 effettuata la ricerca di una chiave, qualora \param{flag} specifichi dei
 permessi, questi vengono controllati e l'identificatore viene restituito solo
 se corrispondono a quelli dell'oggetto. Se ci sono dei permessi non presenti
-in \var{mode} l'accesso sarà negato. Questo controllo però è di utilità
-indicativa, dato che è sempre possibile specificare per \param{flag} un valore
-nullo, nel qual caso l'identificatore sarà restituito comunque.
+in \var{mode} l'accesso sarà negato. Questo controllo però è di utilità
+indicativa, dato che è sempre possibile specificare per \param{flag} un valore
+nullo, nel qual caso l'identificatore sarà restituito comunque.
 
-Il secondo livello di controllo è quello delle varie funzioni che accedono
+Il secondo livello di controllo è quello delle varie funzioni che accedono
 direttamente (in lettura o scrittura) all'oggetto. In tal caso lo schema dei
-controlli è simile a quello dei file, ed avviene secondo questa sequenza:
-\begin{itemize}
-\item se il processo ha i privilegi di amministratore l'accesso è sempre
+controlli è simile a quello dei file, ed avviene secondo questa sequenza:
+\begin{itemize*}
+\item se il processo ha i privilegi di amministratore l'accesso è sempre
   consentito. 
 \item se l'user-ID effettivo del processo corrisponde o al valore del campo
   \var{cuid} o a quello del campo \var{uid} ed il permesso per il proprietario
-  in \var{mode} è appropriato\footnote{per appropriato si intende che è
+  in \var{mode} è appropriato\footnote{per appropriato si intende che è
     impostato il permesso di scrittura per le operazioni di scrittura e quello
-    di lettura per le operazioni di lettura.} l'accesso è consentito.
+    di lettura per le operazioni di lettura.} l'accesso è consentito.
 \item se il group-ID effettivo del processo corrisponde o al
   valore del campo \var{cgid} o a quello del campo \var{gid} ed il permesso
-  per il gruppo in \var{mode} è appropriato l'accesso è consentito.
-\item se il permesso per gli altri è appropriato l'accesso è consentito.
-\end{itemize}
-solo se tutti i controlli elencati falliscono l'accesso è negato. Si noti che
+  per il gruppo in \var{mode} è appropriato l'accesso è consentito.
+\item se il permesso per gli altri è appropriato l'accesso è consentito.
+\end{itemize*}
+solo se tutti i controlli elencati falliscono l'accesso è negato. Si noti che
 a differenza di quanto avviene per i permessi dei file, fallire in uno dei
 passi elencati non comporta il fallimento dell'accesso. Un'ulteriore
-differenza rispetto a quanto avviene per i file è che per gli oggetti di IPC
-il valore di \var{umask} (si ricordi quanto esposto in
-sez.~\ref{sec:file_umask}) non ha alcun significato.
+differenza rispetto a quanto avviene per i file è che per gli oggetti di IPC
+il valore di \itindex{umask} \textit{umask} (si ricordi quanto esposto in
+sez.~\ref{sec:file_perm_management}) non ha alcun significato.
 
 
 \subsection{Gli identificatori ed il loro utilizzo}
 \label{sec:ipc_sysv_id_use}
 
-L'unico campo di \struct{ipc\_perm} del quale non abbiamo ancora parlato è
-\var{seq}, che in fig.~\ref{fig:ipc_ipc_perm} è qualificato con un criptico
-``\textsl{numero di sequenza}'', ne parliamo adesso dato che esso è
-strettamente attinente alle modalità con cui il kernel assegna gli
+L'unico campo di \struct{ipc\_perm} del quale non abbiamo ancora parlato è
+\var{seq}, che in fig.~\ref{fig:ipc_ipc_perm} è qualificato con un criptico
+``\textsl{numero di sequenza}'', ne parliamo adesso dato che esso è
+strettamente attinente alle modalità con cui il kernel assegna gli
 identificatori degli oggetti del sistema di IPC.
 
 Quando il sistema si avvia, alla creazione di ogni nuovo oggetto di IPC viene
@@ -999,37 +1003,38 @@ dimensioni (inferiori al numero massimo di oggetti disponibili).
 
 Questo va benissimo nel caso dei file descriptor, che sono locali ad un
 processo, ma qui il comportamento varrebbe per tutto il sistema, e per
-processi del tutto scorrelati fra loro. Così si potrebbero avere situazioni
+processi del tutto scorrelati fra loro. Così si potrebbero avere situazioni
 come quella in cui un server esce e cancella le sue code di messaggi, ed il
 relativo identificatore viene immediatamente assegnato a quelle di un altro
-server partito subito dopo, con la possibilità che i client del primo non
+server partito subito dopo, con la possibilità che i client del primo non
 facciano in tempo ad accorgersi dell'avvenuto, e finiscano con l'interagire
 con gli oggetti del secondo, con conseguenze imprevedibili.
 
 Proprio per evitare questo tipo di situazioni il sistema usa il valore di
 \var{seq} per provvedere un meccanismo che porti gli identificatori ad
-assumere tutti i valori possibili, rendendo molto più lungo il periodo in cui
-un identificatore può venire riutilizzato.
+assumere tutti i valori possibili, rendendo molto più lungo il periodo in cui
+un identificatore può venire riutilizzato.
 
 Il sistema dispone sempre di un numero fisso di oggetti di IPC,\footnote{fino
   al kernel 2.2.x questi valori, definiti dalle costanti \const{MSGMNI},
   \const{SEMMNI} e \const{SHMMNI}, potevano essere cambiati (come tutti gli
   altri limiti relativi al \textit{SysV IPC}) solo con una ricompilazione del
   kernel, andando a modificarne la definizione nei relativi header file.  A
-  partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo
-  scrivendo sui file \file{shmmni}, \file{msgmni} e \file{sem} di
-  \file{/proc/sys/kernel} o con l'uso di \func{sysctl}.} e per ciascuno di
+  partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo
+  scrivendo sui file \procrelfile{/proc/sys/kernel}{shmmni},
+  \procrelfile{/proc/sys/kernel}{msgmni} e \procrelfile{/proc/sys/kernel}{sem}
+  di \file{/proc/sys/kernel} o con l'uso di \func{sysctl}.} e per ciascuno di
 essi viene mantenuto in \var{seq} un numero di sequenza progressivo che viene
 incrementato di uno ogni volta che l'oggetto viene cancellato. Quando
-l'oggetto viene creato usando uno spazio che era già stato utilizzato in
+l'oggetto viene creato usando uno spazio che era già stato utilizzato in
 precedenza per restituire l'identificatore al numero di oggetti presenti viene
 sommato il valore di \var{seq} moltiplicato per il numero massimo di oggetti
 di quel tipo,\footnote{questo vale fino ai kernel della serie 2.2.x, dalla
-  serie 2.4.x viene usato lo stesso fattore per tutti gli oggetti, esso è dato
+  serie 2.4.x viene usato lo stesso fattore per tutti gli oggetti, esso è dato
   dalla costante \const{IPCMNI}, definita in \file{include/linux/ipc.h}, che
   indica il limite massimo per il numero di tutti oggetti di IPC, ed il cui
-  valore è 32768.}  si evita così il riutilizzo degli stessi numeri, e si fa
-sì che l'identificatore assuma tutti i valori possibili.
+  valore è 32768.}  si evita così il riutilizzo degli stessi numeri, e si fa
+sì che l'identificatore assuma tutti i valori possibili.
 
 \begin{figure}[!htb]
   \footnotesize \centering
   \label{fig:ipc_sysv_idtest}
 \end{figure}
 
-In fig.~\ref{fig:ipc_sysv_idtest} è riportato il codice di un semplice
+In fig.~\ref{fig:ipc_sysv_idtest} è riportato il codice di un semplice
 programma di test che si limita a creare un oggetto (specificato a riga di
 comando), stamparne il numero di identificatore e cancellarlo per un numero
-specificato di volte. Al solito non si è riportato il codice della gestione
+specificato di volte. Al solito non si è riportato il codice della gestione
 delle opzioni a riga di comando, che permette di specificare quante volte
 effettuare il ciclo \var{n}, e su quale tipo di oggetto eseguirlo.
 
@@ -1053,42 +1058,44 @@ La figura non riporta il codice di selezione delle opzioni, che permette di
 inizializzare i valori delle variabili \var{type} al tipo di oggetto voluto, e
 \var{n} al numero di volte che si vuole effettuare il ciclo di creazione,
 stampa, cancellazione. I valori di default sono per l'uso delle code di
-messaggi e un ciclo di 5 volte. Se si lancia il comando si otterrà qualcosa
+messaggi e un ciclo di 5 volte. Se si lancia il comando si otterrà qualcosa
 del tipo:
-\begin{verbatim}
+\begin{Verbatim}
 piccardi@gont sources]$ ./ipctestid
 Identifier Value 0 
 Identifier Value 32768 
 Identifier Value 65536 
 Identifier Value 98304 
 Identifier Value 131072 
-\end{verbatim}%$
+\end{Verbatim}
+%$
 il che ci mostra che abbiamo un kernel della serie 2.4.x nel quale non avevamo
 ancora usato nessuna coda di messaggi. Se ripetiamo il comando otterremo
 ancora:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ./ipctestid
 Identifier Value 163840 
 Identifier Value 196608 
 Identifier Value 229376 
 Identifier Value 262144 
 Identifier Value 294912 
-\end{verbatim}%$
-che ci mostra come il valore di \var{seq} sia in effetti una quantità
+\end{Verbatim}
+%$
+che ci mostra come il valore di \var{seq} sia in effetti una quantità
 mantenuta staticamente all'interno del sistema.
 
 
 \subsection{Code di messaggi}
 \label{sec:ipc_sysv_mq}
 
-Il primo oggetto introdotto dal \textit{SysV IPC} è quello delle code di
+Il primo oggetto introdotto dal \textit{SysV IPC} è quello delle code di
 messaggi.  Le code di messaggi sono oggetti analoghi alle pipe o alle fifo,
-anche se la loro struttura è diversa, ed il loro scopo principale è appunto
+anche se la loro struttura è diversa, ed il loro scopo principale è appunto
 quello di permettere a processi diversi di scambiarsi dei dati.
 
 La funzione che permette di richiedere al sistema l'identificatore di una coda
-di messaggi esistente (o di crearne una se questa non esiste) è
-\funcd{msgget}; il suo prototipo è:
+di messaggi esistente (o di crearne una se questa non esiste) è
+\funcd{msgget}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1099,17 +1106,17 @@ di messaggi esistente (o di crearne una se questa non esiste) 
   Restituisce l'identificatore di una coda di messaggi.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+    in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EACCES}] Il processo chiamante non ha i privilegi per accedere
+  \item[\errcode{EACCES}] il processo chiamante non ha i privilegi per accedere
   alla coda richiesta.  
-  \item[\errcode{EEXIST}] Si è richiesta la creazione di una coda che già
+  \item[\errcode{EEXIST}] si è richiesta la creazione di una coda che già
   esiste, ma erano specificati sia \const{IPC\_CREAT} che \const{IPC\_EXCL}. 
-  \item[\errcode{EIDRM}] La coda richiesta è marcata per essere cancellata.
-  \item[\errcode{ENOENT}] Si è cercato di ottenere l'identificatore di una coda
+  \item[\errcode{EIDRM}] la coda richiesta è marcata per essere cancellata.
+  \item[\errcode{ENOENT}] si è cercato di ottenere l'identificatore di una coda
     di messaggi specificando una chiave che non esiste e \const{IPC\_CREAT}
     non era specificato.
-  \item[\errcode{ENOSPC}] Si è cercato di creare una coda di messaggi quando è
+  \item[\errcode{ENOSPC}] si è cercato di creare una coda di messaggi quando è
     stato superato il limite massimo di code (\const{MSGMNI}).
   \end{errlist}
   ed inoltre \errval{ENOMEM}.
@@ -1118,27 +1125,27 @@ di messaggi esistente (o di crearne una se questa non esiste) 
 
 Le funzione (come le analoghe che si usano per gli altri oggetti) serve sia a
 ottenere l'identificatore di una coda di messaggi esistente, che a crearne una
-nuova. L'argomento \param{key} specifica la chiave che è associata
+nuova. L'argomento \param{key} specifica la chiave che è associata
 all'oggetto, eccetto il caso in cui si specifichi il valore
-\const{IPC\_PRIVATE}, nel qual caso la coda è creata ex-novo e non vi è
+\const{IPC\_PRIVATE}, nel qual caso la coda è creata ex-novo e non vi è
 associata alcuna chiave, il processo (ed i suoi eventuali figli) potranno
 farvi riferimento solo attraverso l'identificatore.
 
 Se invece si specifica un valore diverso da \const{IPC\_PRIVATE}\footnote{in
   Linux questo significa un valore diverso da zero.} l'effetto della funzione
-dipende dal valore di \param{flag}, se questo è nullo la funzione si limita ad
+dipende dal valore di \param{flag}, se questo è nullo la funzione si limita ad
 effettuare una ricerca sugli oggetti esistenti, restituendo l'identificatore
 se trova una corrispondenza, o fallendo con un errore di \errcode{ENOENT} se
 non esiste o di \errcode{EACCES} se si sono specificati dei permessi non
 validi.
 
-Se invece si vuole creare una nuova coda di messaggi \param{flag} non può
+Se invece si vuole creare una nuova coda di messaggi \param{flag} non può
 essere nullo e deve essere fornito come maschera binaria, impostando il bit
 corrispondente al valore \const{IPC\_CREAT}. In questo caso i nove bit meno
 significativi di \param{flag} saranno usati come permessi per il nuovo
 oggetto, secondo quanto illustrato in sez.~\ref{sec:ipc_sysv_access_control}.
-Se si imposta anche il bit corrispondente a \const{IPC\_EXCL} la funzione avrà
-successo solo se l'oggetto non esiste già, fallendo con un errore di
+Se si imposta anche il bit corrispondente a \const{IPC\_EXCL} la funzione avrà
+successo solo se l'oggetto non esiste già, fallendo con un errore di
 \errcode{EEXIST} altrimenti.
 
 Si tenga conto che l'uso di \const{IPC\_PRIVATE} non impedisce ad altri
@@ -1160,7 +1167,7 @@ coda.
     \hline
     \hline
     \const{MSGMNI}&   16& \file{msgmni} & Numero massimo di code di
-                                          messaggi. \\
+                                          messaggi.\\
     \const{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo
                                           messaggio.\\
     \const{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di 
@@ -1173,35 +1180,36 @@ coda.
 
 Le code di messaggi sono caratterizzate da tre limiti fondamentali, definiti
 negli header e corrispondenti alle prime tre costanti riportate in
-tab.~\ref{tab:ipc_msg_limits}, come accennato però in Linux è possibile
+tab.~\ref{tab:ipc_msg_limits}, come accennato però in Linux è possibile
 modificare questi limiti attraverso l'uso di \func{sysctl} o scrivendo nei
-file \file{msgmax}, \file{msgmnb} e \file{msgmni} di \file{/proc/sys/kernel/}.
-
+file \procrelfile{/proc/sys/kernel}{msgmax},
+\procrelfile{/proc/sys/kernel}{msgmnb} e
+\procrelfile{/proc/sys/kernel}{msgmni} di \file{/proc/sys/kernel/}.
 
 \begin{figure}[htb]
-  \centering \includegraphics[width=15cm]{img/mqstruct}
+  \centering \includegraphics[width=13cm]{img/mqstruct}
   \caption{Schema della struttura di una coda messaggi.}
   \label{fig:ipc_mq_schema}
 \end{figure}
 
 
-Una coda di messaggi è costituita da una \itindex{linked~list}\textit{linked
-  list};\footnote{una \textit{linked list} è una tipica struttura di dati,
-  organizzati in una lista in cui ciascun elemento contiene un puntatore al
-  successivo. In questo modo la struttura è veloce nell'estrazione ed
-  immissione dei dati dalle estremità dalla lista (basta aggiungere un
-  elemento in testa o in coda ed aggiornare un puntatore), e relativamente
-  veloce da attraversare in ordine sequenziale (seguendo i puntatori), è
-  invece relativamente lenta nell'accesso casuale e nella ricerca.}  i nuovi
-messaggi vengono inseriti in coda alla lista e vengono letti dalla cima, in
-fig.~\ref{fig:ipc_mq_schema} si è riportato lo schema con cui queste strutture
-vengono mantenute dal kernel.\footnote{lo schema illustrato in
-  fig.~\ref{fig:ipc_mq_schema} è in realtà una semplificazione di quello usato
-  effettivamente fino ai kernel della serie 2.2.x, nei kernel della serie
-  2.4.x la gestione delle code di messaggi è stata modificata ed è effettuata
-  in maniera diversa; abbiamo mantenuto lo schema precedente in quanto
-  illustra comunque in maniera più che adeguata i principi di funzionamento
-  delle code di messaggi.}
+Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked
+  list};\footnote{una \itindex{linked~list} \textit{linked list} è una tipica
+  struttura di dati, organizzati in una lista in cui ciascun elemento contiene
+  un puntatore al successivo. In questo modo la struttura è veloce
+  nell'estrazione ed immissione dei dati dalle estremità dalla lista (basta
+  aggiungere un elemento in testa o in coda ed aggiornare un puntatore), e
+  relativamente veloce da attraversare in ordine sequenziale (seguendo i
+  puntatori), è invece relativamente lenta nell'accesso casuale e nella
+  ricerca.}  i nuovi messaggi vengono inseriti in coda alla lista e vengono
+letti dalla cima, in fig.~\ref{fig:ipc_mq_schema} si è riportato lo schema con
+cui queste strutture vengono mantenute dal kernel.\footnote{lo schema
+  illustrato in fig.~\ref{fig:ipc_mq_schema} è in realtà una semplificazione
+  di quello usato effettivamente fino ai kernel della serie 2.2.x, nei kernel
+  della serie 2.4.x la gestione delle code di messaggi è stata modificata ed è
+  effettuata in maniera diversa; abbiamo mantenuto lo schema precedente in
+  quanto illustra comunque in maniera più che adeguata i principi di
+  funzionamento delle code di messaggi.}
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1214,12 +1222,12 @@ vengono mantenute dal kernel.\footnote{lo schema illustrato in
   \label{fig:ipc_msqid_ds}
 \end{figure}
 
-A ciascuna coda è associata una struttura \struct{msgid\_ds}, la cui
-definizione, è riportata in fig.~\ref{fig:ipc_msqid_ds}. In questa struttura il
+A ciascuna coda è associata una struttura \struct{msgid\_ds}, la cui
+definizione, è riportata in fig.~\ref{fig:ipc_msqid_ds}. In questa struttura il
 kernel mantiene le principali informazioni riguardo lo stato corrente della
 coda.\footnote{come accennato questo vale fino ai kernel della serie 2.2.x,
-  essa viene usata nei kernel della serie 2.4.x solo per compatibilità in
-  quanto è quella restituita dalle funzioni dell'interfaccia.  Si noti come ci
+  essa viene usata nei kernel della serie 2.4.x solo per compatibilità in
+  quanto è quella restituita dalle funzioni dell'interfaccia.  Si noti come ci
   sia una differenza con i campi mostrati nello schema di
   fig.~\ref{fig:ipc_mq_schema} che sono presi dalla definizione di
   \file{linux/msg.h}, e fanno riferimento alla definizione della omonima
@@ -1239,7 +1247,7 @@ gli altri campi invece:
   rispettivamente il \acr{pid} dell'ultimo processo che ha inviato o ricevuto
   un messaggio sulla coda, sono inizializzati a 0.
 \item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono
-  rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo
+  rispettivamente il tempo in cui è stato inviato o ricevuto l'ultimo
   messaggio sulla coda, sono inizializzati a 0.
 \item il campo \var{msg\_ctime}, che esprime il tempo di creazione della coda,
   viene inizializzato al tempo corrente.
@@ -1248,15 +1256,15 @@ gli altri campi invece:
   del sistema (\const{MSGMNB}).
 \item i campi \var{msg\_first} e \var{msg\_last} che esprimono l'indirizzo del
   primo e ultimo messaggio sono inizializzati a \val{NULL} e
-  \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
+  \var{msg\_cbytes}, che esprime la dimensione in byte dei messaggi presenti è
   inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
   e non devono essere utilizzati da programmi in user space).
 \end{itemize*}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
 effettuate con la funzione \funcd{msgctl}, che (come le analoghe \func{semctl}
-e \func{shmctl}) fa le veci di quello che \func{ioctl} è per i file; il suo
-prototipo è:
+e \func{shmctl}) fa le veci di quello che \func{ioctl} è per i file; il suo
+prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1266,14 +1274,14 @@ prototipo 
   
   Esegue l'operazione specificata da \param{cmd} sulla coda \param{msqid}.
   
-  \bodydesc{La funzione restituisce 0 in caso di successo o -1 in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \bodydesc{La funzione restituisce 0 in caso di successo o $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EACCES}] Si è richiesto \const{IPC\_STAT} ma processo
+  \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma processo
     chiamante non ha i privilegi di lettura sulla coda.
-  \item[\errcode{EIDRM}] La coda richiesta è stata cancellata.
-  \item[\errcode{EPERM}] Si è richiesto \const{IPC\_SET} o \const{IPC\_RMID} ma
-    il processo non ha i privilegi, o si è richiesto di aumentare il valore di
+  \item[\errcode{EIDRM}] la coda richiesta è stata cancellata.
+  \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID} ma
+    il processo non ha i privilegi, o si è richiesto di aumentare il valore di
     \var{msg\_qbytes} oltre il limite \const{MSGMNB} senza essere
     amministratore.
   \end{errlist}
@@ -1294,7 +1302,7 @@ eseguire; i valori possibili sono:
   effetto immediato. Tutti i processi che cercheranno di accedere alla coda
   riceveranno un errore di \errcode{EIDRM}, e tutti processi in attesa su
   funzioni di lettura o di scrittura sulla coda saranno svegliati ricevendo
-  il medesimo errore. Questo comando può essere eseguito solo da un processo
+  il medesimo errore. Questo comando può essere eseguito solo da un processo
   con user-ID effettivo corrispondente al creatore o al proprietario della
   coda, o all'amministratore.
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
@@ -1303,14 +1311,14 @@ eseguire; i valori possibili sono:
   struttura \struct{msqid\_ds} puntata da \param{buf}.  Per modificare i valori
   di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid} occorre
   essere il proprietario o il creatore della coda, oppure l'amministratore; lo
-  stesso vale per \var{msg\_qbytes}, ma l'amministratore ha la facoltà di
+  stesso vale per \var{msg\_qbytes}, ma l'amministratore ha la facoltà di
   incrementarne il valore a limiti superiori a \const{MSGMNB}.
 \end{basedescript}
 
 
 Una volta che si abbia a disposizione l'identificatore, per inviare un
 messaggio su una coda si utilizza la funzione \funcd{msgsnd}; il suo prototipo
-è:
+è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1321,53 +1329,51 @@ messaggio su una coda si utilizza la funzione \funcd{msgsnd}; il suo prototipo
 
   Invia un messaggio sulla coda \param{msqid}.
   
-  \bodydesc{La funzione restituisce 0, e -1 in caso di errore, nel qual caso
-    \var{errno} assumerà uno dei valori:
+  \bodydesc{La funzione restituisce 0, e $-1$ in caso di errore, nel qual caso
+    \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EACCES}] Non si hanno i privilegi di accesso sulla coda.
-  \item[\errcode{EIDRM}] La coda è stata cancellata.
-  \item[\errcode{EAGAIN}] Il messaggio non può essere inviato perché si è
+  \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
+  \item[\errcode{EIDRM}] la coda è stata cancellata.
+  \item[\errcode{EAGAIN}] il messaggio non può essere inviato perché si è
   superato il limite \var{msg\_qbytes} sul numero massimo di byte presenti
-  sulla coda, e si è richiesto \const{IPC\_NOWAIT} in \param{flag}.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-  \item[\errcode{EINVAL}] Si è specificato un \param{msgid} invalido, o un
+  sulla coda, e si è richiesto \const{IPC\_NOWAIT} in \param{flag}.
+  \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido, o un
     valore non positivo per \param{mtype}, o un valore di \param{msgsz}
     maggiore di \const{MSGMAX}.
   \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{ENOMEM}.
-}
+  ed inoltre \errval{EFAULT}, \errval{EINTR} ed \errval{ENOMEM}.  }
 \end{functions}
 
 La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il
-messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso il
+messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso il
 l'argomento \param{msgp}.  Quest'ultimo deve venire passato sempre come
 puntatore ad una struttura \struct{msgbuf} analoga a quella riportata in
-fig.~\ref{fig:ipc_msbuf} che è quella che deve contenere effettivamente il
-messaggio.  La dimensione massima per il testo di un messaggio non può
+fig.~\ref{fig:ipc_msbuf} che è quella che deve contenere effettivamente il
+messaggio.  La dimensione massima per il testo di un messaggio non può
 comunque superare il limite \const{MSGMAX}.
 
-La struttura di fig.~\ref{fig:ipc_msbuf} è comunque solo un modello, tanto che
+La struttura di fig.~\ref{fig:ipc_msbuf} è comunque solo un modello, tanto che
 la definizione contenuta in \file{sys/msg.h} usa esplicitamente per il secondo
-campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini pratici.
-La sola cosa che conta è che la struttura abbia come primo membro un campo
+campo il valore \code{mtext[1]}, che non è di nessuna utilità ai fini pratici.
+La sola cosa che conta è che la struttura abbia come primo membro un campo
 \var{mtype} come nell'esempio; esso infatti serve ad identificare il tipo di
 messaggio e deve essere sempre specificato come intero positivo di tipo
-\ctyp{long}.  Il campo \var{mtext} invece può essere di qualsiasi tipo e
+\ctyp{long}.  Il campo \var{mtext} invece può essere di qualsiasi tipo e
 dimensione, e serve a contenere il testo del messaggio.
 
 In generale pertanto per inviare un messaggio con \func{msgsnd} si usa
 ridefinire una struttura simile a quella di fig.~\ref{fig:ipc_msbuf}, adattando
 alle proprie esigenze il campo \var{mtype}, (o ridefinendo come si vuole il
-corpo del messaggio, anche con più campi o con strutture più complesse) avendo
-però la cura di mantenere nel primo campo un valore di tipo \ctyp{long} che ne
+corpo del messaggio, anche con più campi o con strutture più complesse) avendo
+però la cura di mantenere nel primo campo un valore di tipo \ctyp{long} che ne
 indica il tipo.
 
 Si tenga presente che la lunghezza che deve essere indicata in questo
-argomento è solo quella del messaggio, non quella di tutta la struttura, se
-cioè \var{message} è una propria struttura che si passa alla funzione,
-\param{msgsz} dovrà essere uguale a \code{sizeof(message)-sizeof(long)}, (se
+argomento è solo quella del messaggio, non quella di tutta la struttura, se
+cioè \var{message} è una propria struttura che si passa alla funzione,
+\param{msgsz} dovrà essere uguale a \code{sizeof(message)-sizeof(long)}, (se
 consideriamo il caso dell'esempio in fig.~\ref{fig:ipc_msbuf}, \param{msgsz}
-dovrà essere pari a \const{LENGTH}).
+dovrà essere pari a \const{LENGTH}).
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1383,11 +1389,11 @@ dovr
 Per capire meglio il funzionamento della funzione riprendiamo in
 considerazione la struttura della coda illustrata in
 fig.~\ref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
-sarà aggiunto in fondo alla lista inserendo una nuova struttura \struct{msg},
-il puntatore \var{msg\_last} di \struct{msqid\_ds} verrà aggiornato, come pure
+sarà aggiunto in fondo alla lista inserendo una nuova struttura \struct{msg},
+il puntatore \var{msg\_last} di \struct{msqid\_ds} verrà aggiornato, come pure
 il puntatore al messaggio successivo per quello che era il precedente ultimo
-messaggio; il valore di \var{mtype} verrà mantenuto in \var{msg\_type} ed il
-valore di \param{msgsz} in \var{msg\_ts}; il testo del messaggio sarà copiato
+messaggio; il valore di \var{mtype} verrà mantenuto in \var{msg\_type} ed il
+valore di \param{msgsz} in \var{msg\_ts}; il testo del messaggio sarà copiato
 all'indirizzo specificato da \var{msg\_spot}.
 
 Il valore dell'argomento \param{flag} permette di specificare il comportamento
@@ -1396,12 +1402,12 @@ ritorna immediatamente a meno che si sia ecceduto il valore di
 \var{msg\_qbytes}, o il limite di sistema sul numero di messaggi, nel qual
 caso si blocca mandando il processo in stato di \textit{sleep}.  Se si
 specifica per \param{flag} il valore \const{IPC\_NOWAIT} la funzione opera in
-modalità non bloccante, ed in questi casi ritorna immediatamente con un errore
+modalità non bloccante, ed in questi casi ritorna immediatamente con un errore
 di \errcode{EAGAIN}.
 
-Se non si specifica \const{IPC\_NOWAIT} la funzione resterà bloccata fintanto
+Se non si specifica \const{IPC\_NOWAIT} la funzione resterà bloccata fintanto
 che non si liberano risorse sufficienti per poter inserire nella coda il
-messaggio, nel qual caso ritornerà normalmente. La funzione può ritornare, con
+messaggio, nel qual caso ritornerà normalmente. La funzione può ritornare, con
 una condizione di errore anche in due altri casi: quando la coda viene rimossa
 (nel qual caso si ha un errore di \errcode{EIDRM}) o quando la funzione viene
 interrotta da un segnale (nel qual caso si ha un errore di \errcode{EINTR}).
@@ -1416,8 +1422,8 @@ vengono modificati:
 \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
 \end{itemize*}
 
-La funzione che viene utilizzata per estrarre un messaggio da una coda è
-\funcd{msgrcv}; il suo prototipo è:
+La funzione che viene utilizzata per estrarre un messaggio da una coda è
+\funcd{msgrcv}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1429,16 +1435,16 @@ La funzione che viene utilizzata per estrarre un messaggio da una coda 
   Legge un messaggio dalla coda \param{msqid}.
   
   \bodydesc{La funzione restituisce il numero di byte letti in caso di
-    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà uno
+    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà uno
     dei valori:
   \begin{errlist}
-  \item[\errcode{EACCES}] Non si hanno i privilegi di accesso sulla coda.
-  \item[\errcode{EIDRM}] La coda è stata cancellata.
-  \item[\errcode{E2BIG}] Il testo del messaggio è più lungo di \param{msgsz} e
-    non si è specificato \const{MSG\_NOERROR} in \param{msgflg}.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale mentre
+  \item[\errcode{EACCES}] non si hanno i privilegi di accesso sulla coda.
+  \item[\errcode{EIDRM}] la coda è stata cancellata.
+  \item[\errcode{E2BIG}] il testo del messaggio è più lungo di \param{msgsz} e
+    non si è specificato \const{MSG\_NOERROR} in \param{msgflg}.
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale mentre
     era in attesa di ricevere un messaggio.
-  \item[\errcode{EINVAL}] Si è specificato un \param{msgid} invalido o un
+  \item[\errcode{EINVAL}] si è specificato un \param{msgid} invalido o un
     valore di \param{msgsz} negativo.
   \end{errlist}
   ed inoltre \errval{EFAULT}.
@@ -1446,46 +1452,46 @@ La funzione che viene utilizzata per estrarre un messaggio da una coda 
 \end{functions}
 
 La funzione legge un messaggio dalla coda specificata, scrivendolo sulla
-struttura puntata da \param{msgp}, che dovrà avere un formato analogo a quello
-di fig.~\ref{fig:ipc_msbuf}.  Una volta estratto, il messaggio sarà rimosso
+struttura puntata da \param{msgp}, che dovrà avere un formato analogo a quello
+di fig.~\ref{fig:ipc_msbuf}.  Una volta estratto, il messaggio sarà rimosso
 dalla coda.  L'argomento \param{msgsz} indica la lunghezza massima del testo
 del messaggio (equivalente al valore del parametro \const{LENGTH} nell'esempio
 di fig.~\ref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
-rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
+rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
 \const{MSG\_NOERROR}, il messaggio viene troncato e la parte in eccesso viene
 perduta, altrimenti il messaggio non viene estratto e la funzione ritorna con
 un errore di \errcode{E2BIG}.
 
 L'argomento \param{msgtyp} permette di restringere la ricerca ad un
-sottoinsieme dei messaggi presenti sulla coda; la ricerca infatti è fatta con
+sottoinsieme dei messaggi presenti sulla coda; la ricerca infatti è fatta con
 una scansione della struttura mostrata in fig.~\ref{fig:ipc_mq_schema},
 restituendo il primo messaggio incontrato che corrisponde ai criteri
 specificati (che quindi, visto come i messaggi vengono sempre inseriti dalla
-coda, è quello meno recente); in particolare:
+coda, è quello meno recente); in particolare:
 \begin{itemize}
-\item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè
-  quello fra i presenti che è stato inserito per primo. 
-\item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui
+\item se \param{msgtyp} è 0 viene estratto il messaggio in cima alla coda, cioè
+  quello fra i presenti che è stato inserito per primo. 
+\item se \param{msgtyp} è positivo viene estratto il primo messaggio il cui
   tipo (il valore del campo \var{mtype}) corrisponde al valore di
   \param{msgtyp}.
-\item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con
-  il valore più basso del tipo, fra tutti quelli il cui tipo ha un valore
+\item se \param{msgtyp} è negativo viene estratto il primo fra i messaggi con
+  il valore più basso del tipo, fra tutti quelli il cui tipo ha un valore
   inferiore al valore assoluto di \param{msgtyp}.
 \end{itemize}
 
 Il valore di \param{msgflg} permette di controllare il comportamento della
-funzione, esso può essere nullo o una maschera binaria composta da uno o più
+funzione, esso può essere nullo o una maschera binaria composta da uno o più
 valori.  Oltre al precedente \const{MSG\_NOERROR}, sono possibili altri due
-valori: \const{MSG\_EXCEPT}, che permette, quando \param{msgtyp} è positivo,
+valori: \const{MSG\_EXCEPT}, che permette, quando \param{msgtyp} è positivo,
 di leggere il primo messaggio nella coda con tipo diverso da \param{msgtyp}, e
 \const{IPC\_NOWAIT} che causa il ritorno immediato della funzione quando non
 ci sono messaggi sulla coda.
 
 Il comportamento usuale della funzione infatti, se non ci sono messaggi
-disponibili per la lettura, è di bloccare il processo in stato di
-\textit{sleep}. Nel caso però si sia specificato \const{IPC\_NOWAIT} la
+disponibili per la lettura, è di bloccare il processo in stato di
+\textit{sleep}. Nel caso però si sia specificato \const{IPC\_NOWAIT} la
 funzione ritorna immediatamente con un errore \errcode{ENOMSG}. Altrimenti la
 funzione ritorna normalmente non appena viene inserito un messaggio del tipo
 desiderato, oppure ritorna con errore qualora la coda sia rimossa (con
@@ -1504,20 +1510,20 @@ vengono modificati:
 
 Le code di messaggi presentano il solito problema di tutti gli oggetti del
 SysV IPC; essendo questi permanenti restano nel sistema occupando risorse
-anche quando un processo è terminato, al contrario delle pipe per le quali
+anche quando un processo è terminato, al contrario delle pipe per le quali
 tutte le risorse occupate vengono rilasciate quanto l'ultimo processo che le
-utilizzava termina. Questo comporta che in caso di errori si può saturare il
+utilizzava termina. Questo comporta che in caso di errori si può saturare il
 sistema, e che devono comunque essere esplicitamente previste delle funzioni
 di rimozione in caso di interruzioni o uscite dal programma (come vedremo in
 fig.~\ref{fig:ipc_mq_fortune_server}).
 
-L'altro problema è non facendo uso di file descriptor le tecniche di
+L'altro problema è non facendo uso di file descriptor le tecniche di
 \textit{I/O multiplexing} descritte in sez.~\ref{sec:file_multiplexing} non
 possono essere utilizzate, e non si ha a disposizione niente di analogo alle
-funzioni \func{select} e \func{poll}. Questo rende molto scomodo usare più di
-una di queste strutture alla volta; ad esempio non si può scrivere un server
-che aspetti un messaggio su più di una coda senza fare ricorso ad una tecnica
-di \textit{polling}\itindex{polling} che esegua un ciclo di attesa su
+funzioni \func{select} e \func{poll}. Questo rende molto scomodo usare più di
+una di queste strutture alla volta; ad esempio non si può scrivere un server
+che aspetti un messaggio su più di una coda senza fare ricorso ad una tecnica
+di \itindex{polling} \textit{polling} che esegua un ciclo di attesa su
 ciascuna di esse.
 
 Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro
@@ -1536,13 +1542,13 @@ in maniera indipendente con client diversi.
   \label{fig:ipc_mq_fortune_server}
 \end{figure}
 
-In fig.~\ref{fig:ipc_mq_fortune_server} si è riportato un estratto delle parti
-principali del codice del nuovo server (il codice completo è nel file
-\file{MQFortuneServer.c} nei sorgenti allegati). Il programma è basato su un
+In fig.~\ref{fig:ipc_mq_fortune_server} si è riportato un estratto delle parti
+principali del codice del nuovo server (il codice completo è nel file
+\file{MQFortuneServer.c} nei sorgenti allegati). Il programma è basato su un
 uso accorto della caratteristica di poter associate un ``tipo'' ai messaggi
 per permettere una comunicazione indipendente fra il server ed i vari client,
-usando il \acr{pid} di questi ultimi come identificativo. Questo è possibile
-in quanto, al contrario di una fifo, la lettura di una coda di messaggi può
+usando il \acr{pid} di questi ultimi come identificativo. Questo è possibile
+in quanto, al contrario di una fifo, la lettura di una coda di messaggi può
 non essere sequenziale, proprio grazie alla classificazione dei messaggi sulla
 base del loro tipo.
 
@@ -1552,12 +1558,12 @@ definisce due strutture appositamente per la comunicazione; con
 \var{msgbuf\_read} (\texttt{\small 8--11}) vengono passate le richieste mentre
 con \var{msgbuf\_write} (\texttt{\small 12--15}) vengono restituite le frasi.
 
-La gestione delle opzioni si è al solito omessa, essa si curerà di impostare
+La gestione delle opzioni si è al solito omessa, essa si curerà di impostare
 in \var{n} il numero di frasi da leggere specificato a linea di comando ed in
 \var{fortunefilename} il file da cui leggerle; dopo aver installato
 (\texttt{\small 19--21}) i gestori dei segnali per trattare l'uscita dal
 server, viene prima controllato (\texttt{\small 22}) il numero di frasi
-richieste abbia senso (cioè sia maggiore di zero), le quali poi
+richieste abbia senso (cioè sia maggiore di zero), le quali poi
 (\texttt{\small 23}) vengono lette nel vettore in memoria con la stessa
 funzione \code{FortuneParse} usata anche per il server basato sulle fifo.
 
@@ -1574,13 +1580,13 @@ la funzione \func{daemon} per andare in background e poi esegue in permanenza
 il ciclo principale (\texttt{\small 33--40}). Questo inizia (\texttt{\small
   34}) con il porsi in attesa di un messaggio di richiesta da parte di un
 client; si noti infatti come \func{msgrcv} richieda un messaggio con
-\var{mtype} uguale a 1: questo è il valore usato per le richieste dato che
-corrisponde al \acr{pid} di \cmd{init}, che non può essere un client. L'uso
-del flag \const{MSG\_NOERROR} è solo per sicurezza, dato che i messaggi di
+\var{mtype} uguale a 1: questo è il valore usato per le richieste dato che
+corrisponde al \acr{pid} di \cmd{init}, che non può essere un client. L'uso
+del flag \const{MSG\_NOERROR} è solo per sicurezza, dato che i messaggi di
 richiesta sono di dimensione fissa (e contengono solo il \acr{pid} del
 client).
 
-Se non sono presenti messaggi di richiesta \func{msgrcv} si bloccherà,
+Se non sono presenti messaggi di richiesta \func{msgrcv} si bloccherà,
 ritornando soltanto in corrispondenza dell'arrivo sulla coda di un messaggio
 di richiesta da parte di un client, in tal caso il ciclo prosegue
 (\texttt{\small 35}) selezionando una frase a caso, copiandola (\texttt{\small
@@ -1590,12 +1596,12 @@ calcolandone (\texttt{\small 37}) la dimensione.
 Per poter permettere a ciascun client di ricevere solo la risposta indirizzata
 a lui il tipo del messaggio in uscita viene inizializzato (\texttt{\small 38})
 al valore del \acr{pid} del client ricevuto nel messaggio di richiesta.
-L'ultimo passo del ciclo (\texttt{\small 39}) è inviare sulla coda il
-messaggio di risposta. Si tenga conto che se la coda è piena anche questa
-funzione potrà bloccarsi fintanto che non venga liberato dello spazio.
+L'ultimo passo del ciclo (\texttt{\small 39}) è inviare sulla coda il
+messaggio di risposta. Si tenga conto che se la coda è piena anche questa
+funzione potrà bloccarsi fintanto che non venga liberato dello spazio.
 
-Si noti che il programma può terminare solo grazie ad una interruzione da
-parte di un segnale; in tal caso verrà eseguito (\texttt{\small 45--48}) il
+Si noti che il programma può terminare solo grazie ad una interruzione da
+parte di un segnale; in tal caso verrà eseguito (\texttt{\small 45--48}) il
 gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda
 (\texttt{\small 46}) ed ad uscire (\texttt{\small 47}).
 
@@ -1610,19 +1616,19 @@ gestore \code{HandSIGTERM}, che semplicemente si limita a cancellare la coda
   \label{fig:ipc_mq_fortune_client}
 \end{figure}
 
-In fig.~\ref{fig:ipc_mq_fortune_client} si è riportato un estratto il codice
-del programma client.  Al solito il codice completo è con i sorgenti allegati,
+In fig.~\ref{fig:ipc_mq_fortune_client} si è riportato un estratto il codice
+del programma client.  Al solito il codice completo è con i sorgenti allegati,
 nel file \file{MQFortuneClient.c}.  Come sempre si sono rimosse le parti
 relative alla gestione delle opzioni, ed in questo caso, anche la
 dichiarazione delle variabili, che, per la parte relative alle strutture usate
 per la comunicazione tramite le code, sono le stesse viste in
 fig.~\ref{fig:ipc_mq_fortune_server}.
 
-Il client in questo caso è molto semplice; la prima parte del programma
-(\texttt{\small 4--9}) si occupa di accedere alla coda di messaggi, ed è
+Il client in questo caso è molto semplice; la prima parte del programma
+(\texttt{\small 4--9}) si occupa di accedere alla coda di messaggi, ed è
 identica a quanto visto per il server, solo che in questo caso \func{msgget}
 non viene chiamata con il flag di creazione in quanto la coda deve essere
-preesistente. In caso di errore (ad esempio se il server non è stato avviato)
+preesistente. In caso di errore (ad esempio se il server non è stato avviato)
 il programma termina immediatamente. 
 
 Una volta acquisito l'identificatore della coda il client compone il
@@ -1634,19 +1640,19 @@ immettere la richiesta sulla coda.
 A questo punto non resta che (\texttt{\small 16}) rileggere dalla coda la
 risposta del server richiedendo a \func{msgrcv} di selezionare i messaggi di
 tipo corrispondente al valore del \acr{pid} inviato nella richiesta. L'ultimo
-passo (\texttt{\small 17}) prima di uscire è quello di stampare a video il
+passo (\texttt{\small 17}) prima di uscire è quello di stampare a video il
 messaggio ricevuto.
  
 Proviamo allora il nostro nuovo sistema, al solito occorre definire
-\code{LD\_LIBRAY\_PATH} per accedere alla libreria \file{libgapil.so}, dopo di
+\code{LD\_LIBRARY\_PATH} per accedere alla libreria \file{libgapil.so}, dopo di
 che, in maniera del tutto analoga a quanto fatto con il programma che usa le
 fifo, potremo far partire il server con:
 \begin{verbatim}
 [piccardi@gont sources]$ ./mqfortuned -n10
 \end{verbatim}%$
 come nel caso precedente, avendo eseguito il server in background, il comando
-ritornerà immediatamente; potremo però verificare con \cmd{ps} che il
-programma è effettivamente in esecuzione, e che ha creato una coda di
+ritornerà immediatamente; potremo però verificare con \cmd{ps} che il
+programma è effettivamente in esecuzione, e che ha creato una coda di
 messaggi:
 \begin{verbatim}
 [piccardi@gont sources]$ ipcs
@@ -1665,7 +1671,7 @@ a questo punto potremo usare il client per ottenere le nostre frasi:
 \begin{verbatim}
 [piccardi@gont sources]$ ./mqfortune
 Linux ext2fs has been stable for a long time, now it's time to break it
-        -- Linuxkongreß '95 in Berlin
+        -- Linuxkongreß '95 in Berlin
 [piccardi@gont sources]$ ./mqfortune
 Let's call it an accidental feature.
         --Larry Wall
@@ -1674,14 +1680,14 @@ con un risultato del tutto equivalente al precedente. Infine potremo chiudere
 il server inviando il segnale di terminazione con il comando \code{killall
   mqfortuned} verificando che effettivamente la coda di messaggi viene rimossa.
 
-Benché funzionante questa architettura risente dello stesso inconveniente
+Benché funzionante questa architettura risente dello stesso inconveniente
 visto anche nel caso del precedente server basato sulle fifo; se il client
 viene interrotto dopo l'invio del messaggio di richiesta e prima della lettura
-della risposta, quest'ultima resta nella coda (così come per le fifo si aveva
-il problema delle fifo che restavano nel filesystem). In questo caso però il
-problemi sono maggiori, sia perché è molto più facile esaurire la memoria
-dedicata ad una coda di messaggi che gli inode\index{inode} di un filesystem,
-sia perché, con il riutilizzo dei \acr{pid} da parte dei processi, un client
+della risposta, quest'ultima resta nella coda (così come per le fifo si aveva
+il problema delle fifo che restavano nel filesystem). In questo caso però il
+problemi sono maggiori, sia perché è molto più facile esaurire la memoria
+dedicata ad una coda di messaggi che gli \index{inode} inode di un filesystem,
+sia perché, con il riutilizzo dei \acr{pid} da parte dei processi, un client
 eseguito in un momento successivo potrebbe ricevere un messaggio non
 indirizzato a lui.
 
@@ -1693,46 +1699,46 @@ indirizzato a lui.
 I semafori non sono meccanismi di intercomunicazione diretta come quelli
 (pipe, fifo e code di messaggi) visti finora, e non consentono di scambiare
 dati fra processi, ma servono piuttosto come meccanismi di sincronizzazione o
-di protezione per le \textsl{sezioni critiche}\index{sezioni~critiche} del
-codice (si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}). 
+di protezione per le \index{sezione~critica} \textsl{sezioni critiche} del
+codice (si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}).
 
-Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
+Un semaforo è uno speciale contatore, mantenuto nel kernel, che permette, a
 seconda del suo valore, di consentire o meno la prosecuzione dell'esecuzione
-di un programma. In questo modo l'accesso ad una risorsa condivisa da più
-processi può essere controllato, associando ad essa un semaforo che consente
-di assicurare che non più di un processo alla volta possa usarla.
-
-Il concetto di semaforo è uno dei concetti base nella programmazione ed è
-assolutamente generico, così come del tutto generali sono modalità con cui lo
-si utilizza. Un processo che deve accedere ad una risorsa eseguirà un
-controllo del semaforo: se questo è positivo il suo valore sarà decrementato,
-indicando che si è consumato una unità della risorsa, ed il processo potrà
+di un programma. In questo modo l'accesso ad una risorsa condivisa da più
+processi può essere controllato, associando ad essa un semaforo che consente
+di assicurare che non più di un processo alla volta possa usarla.
+
+Il concetto di semaforo è uno dei concetti base nella programmazione ed è
+assolutamente generico, così come del tutto generali sono modalità con cui lo
+si utilizza. Un processo che deve accedere ad una risorsa eseguirà un
+controllo del semaforo: se questo è positivo il suo valore sarà decrementato,
+indicando che si è consumato una unità della risorsa, ed il processo potrà
 proseguire nell'utilizzo di quest'ultima, provvedendo a rilasciarla, una volta
 completate le operazioni volute, reincrementando il semaforo.
 
-Se al momento del controllo il valore del semaforo è nullo, siamo invece in
-una situazione in cui la risorsa non è disponibile, ed il processo si
-bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la
-rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna
-positivo, indicando che la risorsa è disponibile, il processo sarà svegliato,
-e si potrà operare come nel caso precedente (decremento del semaforo, accesso
+Se al momento del controllo il valore del semaforo è nullo, siamo invece in
+una situazione in cui la risorsa non è disponibile, ed il processo si
+bloccherà in stato di \textit{sleep} fin quando chi la sta utilizzando non la
+rilascerà, incrementando il valore del semaforo. Non appena il semaforo torna
+positivo, indicando che la risorsa è disponibile, il processo sarà svegliato,
+e si potrà operare come nel caso precedente (decremento del semaforo, accesso
 alla risorsa, incremento del semaforo).
 
 Per poter implementare questo tipo di logica le operazioni di controllo e
 decremento del contatore associato al semaforo devono essere atomiche,
-pertanto una realizzazione di un oggetto di questo tipo è necessariamente
-demandata al kernel. La forma più semplice di semaforo è quella del
+pertanto una realizzazione di un oggetto di questo tipo è necessariamente
+demandata al kernel. La forma più semplice di semaforo è quella del
 \textsl{semaforo binario}, o \textit{mutex}, in cui un valore diverso da zero
-(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione
-della risorsa; in generale però si possono usare semafori con valori interi,
+(normalmente 1) indica la libertà di accesso, e un valore nullo l'occupazione
+della risorsa. In generale però si possono usare semafori con valori interi,
 utilizzando il valore del contatore come indicatore del ``numero di risorse''
 ancora disponibili.
 
 Il sistema di comunicazione inter-processo di \textit{SysV IPC} prevede anche i
 semafori, ma gli oggetti utilizzati non sono semafori singoli, ma gruppi di
 semafori detti \textsl{insiemi} (o \textit{semaphore set}); la funzione che
-permette di creare o ottenere l'identificatore di un insieme di semafori è
-\funcd{semget}, ed il suo prototipo è:
+permette di creare o ottenere l'identificatore di un insieme di semafori è
+\funcd{semget}, ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1743,52 +1749,51 @@ permette di creare o ottenere l'identificatore di un insieme di semafori 
   Restituisce l'identificatore di un insieme di semafori.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà i valori:
+    in caso di errore, nel qual caso \var{errno} assumerà i valori:
     \begin{errlist}
-    \item[\errcode{ENOSPC}] Si è cercato di creare una insieme di semafori
-      quando è stato superato o il limite per il numero totale di semafori
+    \item[\errcode{ENOSPC}] si è cercato di creare una insieme di semafori
+      quando è stato superato o il limite per il numero totale di semafori
       (\const{SEMMNS}) o quello per il numero totale degli insiemi
       (\const{SEMMNI}) nel sistema.
-    \item[\errcode{EINVAL}] L'argomento \param{nsems} è minore di zero o
+    \item[\errcode{EINVAL}] l'argomento \param{nsems} è minore di zero o
       maggiore del limite sul numero di semafori per ciascun insieme
-      (\const{SEMMSL}), o se l'insieme già esiste, maggiore del numero di
+      (\const{SEMMSL}), o se l'insieme già esiste, maggiore del numero di
       semafori che contiene.
-    \item[\errcode{ENOMEM}] Il sistema non ha abbastanza memoria per poter
+    \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
       contenere le strutture per un nuovo insieme di semafori.
     \end{errlist}
     ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
     \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
 \end{functions}
 
-La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
-restituisce l'identificatore di un insieme di semafori, in particolare è
+La funzione è del tutto analoga a \func{msgget}, solo che in questo caso
+restituisce l'identificatore di un insieme di semafori, in particolare è
 identico l'uso degli argomenti \param{key} e \param{flag}, per cui non
 ripeteremo quanto detto al proposito in sez.~\ref{sec:ipc_sysv_mq}. L'argomento
 \param{nsems} permette di specificare quanti semafori deve contenere l'insieme
 quando se ne richieda la creazione, e deve essere nullo quando si effettua una
-richiesta dell'identificatore di un insieme già esistente.
+richiesta dell'identificatore di un insieme già esistente.
 
 Purtroppo questa implementazione complica inutilmente lo schema elementare che
-abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
-se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
-complicazione inutile, il problema è che i semafori del \textit{SysV IPC}
-soffrono di altri due, ben più gravi, difetti.
+abbiamo descritto, dato che non è possibile definire un singolo semaforo, ma
+se ne deve creare per forza un insieme.  Ma questa in definitiva è solo una
+complicazione inutile, il problema è che i semafori del \textit{SysV IPC}
+soffrono di altri due, ben più gravi, difetti.
 
-Il primo difetto è che non esiste una funzione che permetta di creare ed
+Il primo difetto è che non esiste una funzione che permetta di creare ed
 inizializzare un semaforo in un'unica chiamata; occorre prima creare l'insieme
 dei semafori con \func{semget} e poi inizializzarlo con \func{semctl}, si
-perde così ogni possibilità di eseguire l'operazione atomicamente.
+perde così ogni possibilità di eseguire l'operazione atomicamente.
 
 Il secondo difetto deriva dalla caratteristica generale degli oggetti del
 \textit{SysV IPC} di essere risorse globali di sistema, che non vengono
-cancellate quando nessuno le usa più; ci si così a trova a dover affrontare
+cancellate quando nessuno le usa più; ci si così a trova a dover affrontare
 esplicitamente il caso in cui un processo termina per un qualche errore,
-lasciando un semaforo occupato, che resterà tale fino al successivo riavvio
-del sistema. Come vedremo esistono delle modalità per evitare tutto ciò, ma
+lasciando un semaforo occupato, che resterà tale fino al successivo riavvio
+del sistema. Come vedremo esistono delle modalità per evitare tutto ciò, ma
 diventa necessario indicare esplicitamente che si vuole il ripristino del
 semaforo all'uscita del processo.
 
-
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
@@ -1800,7 +1805,7 @@ semaforo all'uscita del processo.
   \label{fig:ipc_semid_ds}
 \end{figure}
 
-A ciascun insieme di semafori è associata una struttura \struct{semid\_ds},
+A ciascun insieme di semafori è associata una struttura \struct{semid\_ds},
 riportata in fig.~\ref{fig:ipc_semid_ds}.\footnote{non si sono riportati i
   campi ad uso interno del kernel, che vedremo in
   fig.~\ref{fig:ipc_sem_schema}, che dipendono dall'implementazione.} Come nel
@@ -1808,7 +1813,7 @@ caso delle code di messaggi quando si crea un nuovo insieme di semafori con
 \func{semget} questa struttura viene inizializzata, in particolare il campo
 \var{sem\_perm} viene inizializzato come illustrato in
 sez.~\ref{sec:ipc_sysv_access_control} (si ricordi che in questo caso il
-permesso di scrittura è in realtà permesso di alterare il semaforo), per
+permesso di scrittura è in realtà permesso di alterare il semaforo), per
 quanto riguarda gli altri campi invece:
 \begin{itemize*}
 \item il campo \var{sem\_nsems}, che esprime il numero di semafori
@@ -1819,16 +1824,15 @@ quanto riguarda gli altri campi invece:
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
-
-Ciascun semaforo dell'insieme è realizzato come una struttura di tipo
+Ciascun semaforo dell'insieme è realizzato come una struttura di tipo
 \struct{sem} che ne contiene i dati essenziali, la sua definizione\footnote{si
-  è riportata la definizione originaria del kernel 1.0, che contiene la prima
-  realizzazione del \textit{SysV IPC} in Linux. In realtà questa struttura
-  ormai è ridotta ai soli due primi membri, e gli altri vengono calcolati
-  dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i
+  è riportata la definizione originaria del kernel 1.0, che contiene la prima
+  realizzazione del \textit{SysV IPC} in Linux. In realtà questa struttura
+  ormai è ridotta ai soli due primi membri, e gli altri vengono calcolati
+  dinamicamente. La si è utilizzata a scopo di esempio, perché indica tutti i
   valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
-  citati dalle pagine di manuale.} è riportata in fig.~\ref{fig:ipc_sem}.
-Questa struttura, non è accessibile in user space, ma i valori in essa
+  citati dalle pagine di manuale.} è riportata in fig.~\ref{fig:ipc_sem}.
+Questa struttura, non è accessibile in user space, ma i valori in essa
 specificati possono essere letti in maniera indiretta, attraverso l'uso delle
 funzioni di controllo.
 
@@ -1862,16 +1866,16 @@ indicano rispettivamente:
     \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \const{SEMMNI}&          128 & Numero massimo di insiemi di semafori. \\
+    \const{SEMMNI}&          128 & Numero massimo di insiemi di semafori.\\
     \const{SEMMSL}&          250 & Numero massimo di semafori per insieme.\\
     \const{SEMMNS}&\const{SEMMNI}*\const{SEMMSL}& Numero massimo di semafori
-                                   nel sistema .\\
+                                   nel sistema.\\
     \const{SEMVMX}&        32767 & Massimo valore per un semaforo.\\
     \const{SEMOPM}&           32 & Massimo numero di operazioni per chiamata a
                                    \func{semop}. \\
     \const{SEMMNU}&\const{SEMMNS}& Massimo numero di strutture di ripristino.\\
     \const{SEMUME}&\const{SEMOPM}& Massimo numero di voci di ripristino.\\
-    \const{SEMAEM}&\const{SEMVMX}& valore massimo per l'aggiustamento
+    \const{SEMAEM}&\const{SEMVMX}& Valore massimo per l'aggiustamento
                                    all'uscita. \\
     \hline
   \end{tabular}
@@ -1884,11 +1888,11 @@ Come per le code di messaggi anche per gli insiemi di semafori esistono una
 serie di limiti, i cui valori sono associati ad altrettante costanti, che si
 sono riportate in tab.~\ref{tab:ipc_sem_limits}. Alcuni di questi limiti sono
 al solito accessibili e modificabili attraverso \func{sysctl} o scrivendo
-direttamente nel file \file{/proc/sys/kernel/sem}.
+direttamente nel file \procfile{/proc/sys/kernel/sem}.
 
 La funzione che permette di effettuare le varie operazioni di controllo sui
-semafori (fra le quali, come accennato, è impropriamente compresa anche la
-loro inizializzazione) è \funcd{semctl}; il suo prototipo è:
+semafori (fra le quali, come accennato, è impropriamente compresa anche la
+loro inizializzazione) è \funcd{semctl}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -1901,23 +1905,23 @@ loro inizializzazione) 
   
   \bodydesc{La funzione restituisce in caso di successo un valore positivo
     quanto usata con tre argomenti ed un valore nullo quando usata con
-    quattro. In caso di errore restituisce -1, ed \var{errno} assumerà uno dei
+    quattro. In caso di errore restituisce -1, ed \var{errno} assumerà uno dei
     valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] Il processo non ha i privilegi per eseguire
+    \item[\errcode{EACCES}] il processo non ha i privilegi per eseguire
       l'operazione richiesta.
-    \item[\errcode{EIDRM}] L'insieme di semafori è stato cancellato.
-    \item[\errcode{EPERM}] Si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
+    \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
+    \item[\errcode{EPERM}] si è richiesto \const{IPC\_SET} o \const{IPC\_RMID}
       ma il processo non ha privilegi sufficienti ad eseguire l'operazione.
-    \item[\errcode{ERANGE}] Si è richiesto \const{SETALL} \const{SETVAL} ma il
-      valore a cui si vuole impostare il semaforo è minore di zero o maggiore
+    \item[\errcode{ERANGE}] si è richiesto \const{SETALL} \const{SETVAL} ma il
+      valore a cui si vuole impostare il semaforo è minore di zero o maggiore
       di \const{SEMVMX}.
   \end{errlist}
   ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
 }
 \end{functions}
 
-La funzione può avere tre o quattro argomenti, a seconda dell'operazione
+La funzione può avere tre o quattro argomenti, a seconda dell'operazione
 specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \param{semid} o sul singolo semaforo di un insieme, specificato da
 \param{semnum}. 
@@ -1934,16 +1938,16 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
   \label{fig:ipc_semun}
 \end{figure}
 
-Qualora la funzione operi con quattro argomenti \param{arg} è un argomento
-generico, che conterrà un dato diverso a seconda dell'azione richiesta; per
+Qualora la funzione operi con quattro argomenti \param{arg} è un argomento
+generico, che conterrà un dato diverso a seconda dell'azione richiesta; per
 unificare l'argomento esso deve essere passato come una \struct{semun}, la cui
-definizione, con i possibili valori che può assumere, è riportata in
+definizione, con i possibili valori che può assumere, è riportata in
 fig.~\ref{fig:ipc_semun}.
 
-Come già accennato sia il comportamento della funzione che il numero di
+Come già accennato sia il comportamento della funzione che il numero di
 argomenti con cui deve essere invocata dipendono dal valore dell'argomento
 \param{cmd}, che specifica l'azione da intraprendere; i valori validi (che
-cioè non causano un errore di \errcode{EINVAL}) per questo argomento sono i
+cioè non causano un errore di \errcode{EINVAL}) per questo argomento sono i
 seguenti:
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il
@@ -2010,10 +2014,10 @@ tutti i semafori il cui valore viene modificato.
     \textbf{Operazione}  & \textbf{Valore restituito} \\
     \hline
     \hline
-    \const{GETNCNT}& valore di \var{semncnt}.\\
-    \const{GETPID} & valore di \var{sempid}.\\
-    \const{GETVAL} & valore di \var{semval}.\\
-    \const{GETZCNT}& valore di \var{semzcnt}.\\
+    \const{GETNCNT}& Valore di \var{semncnt}.\\
+    \const{GETPID} & Valore di \var{sempid}.\\
+    \const{GETVAL} & Valore di \var{semval}.\\
+    \const{GETZCNT}& Valore di \var{semzcnt}.\\
     \hline
   \end{tabular}
   \caption{Valori di ritorno della funzione \func{semctl}.} 
@@ -2022,14 +2026,14 @@ tutti i semafori il cui valore viene modificato.
 
 Il valore di ritorno della funzione in caso di successo dipende
 dall'operazione richiesta; per tutte le operazioni che richiedono quattro
-argomenti esso è sempre nullo, per le altre operazioni, elencate in
+argomenti esso è sempre nullo, per le altre operazioni, elencate in
 tab.~\ref{tab:ipc_semctl_returns} viene invece restituito il valore richiesto,
 corrispondente al campo della struttura \struct{sem} indicato nella seconda
 colonna della tabella.
 
 Le operazioni ordinarie sui semafori, come l'acquisizione o il rilascio degli
 stessi (in sostanza tutte quelle non comprese nell'uso di \func{semctl})
-vengono effettuate con la funzione \funcd{semop}, il cui prototipo è:
+vengono effettuate con la funzione \funcd{semop}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -2040,20 +2044,20 @@ vengono effettuate con la funzione \funcd{semop}, il cui prototipo 
   Esegue le operazioni ordinarie su un semaforo o un insieme di semafori.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] Il processo non ha i privilegi per eseguire
+    \item[\errcode{EACCES}] il processo non ha i privilegi per eseguire
       l'operazione richiesta.
-    \item[\errcode{EIDRM}] L'insieme di semafori è stato cancellato.
-    \item[\errcode{ENOMEM}] Si è richiesto un \const{SEM\_UNDO} ma il sistema
+    \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
+    \item[\errcode{ENOMEM}] si è richiesto un \const{SEM\_UNDO} ma il sistema
       non ha le risorse per allocare la struttura di ripristino.
-    \item[\errcode{EAGAIN}] Un'operazione comporterebbe il blocco del processo,
-      ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
-    \item[\errcode{EINTR}] La funzione, bloccata in attesa dell'esecuzione
+    \item[\errcode{EAGAIN}] un'operazione comporterebbe il blocco del processo,
+      ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
+    \item[\errcode{EINTR}] la funzione, bloccata in attesa dell'esecuzione
       dell'operazione, viene interrotta da un segnale.
-    \item[\errcode{E2BIG}] L'argomento \param{nsops} è maggiore del numero
+    \item[\errcode{E2BIG}] l'argomento \param{nsops} è maggiore del numero
       massimo di operazioni \const{SEMOPM}.
-    \item[\errcode{ERANGE}] Per alcune operazioni il valore risultante del
+    \item[\errcode{ERANGE}] per alcune operazioni il valore risultante del
       semaforo viene a superare il limite massimo \const{SEMVMX}.
   \end{errlist}
   ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
@@ -2066,7 +2070,7 @@ un insieme. La funzione richiede come primo argomento l'identificatore
 effettuare viene specificato con l'argomento \param{nsop}, mentre il loro
 contenuto viene passato con un puntatore ad un vettore di strutture
 \struct{sembuf} nell'argomento \param{sops}. Le operazioni richieste vengono
-effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
+effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -2080,7 +2084,7 @@ effettivamente eseguite se e soltanto se 
 \end{figure}
 
 Il contenuto di ciascuna operazione deve essere specificato attraverso una
-opportuna struttura \struct{sembuf} (la cui definizione è riportata in
+opportuna struttura \struct{sembuf} (la cui definizione è riportata in
 fig.~\ref{fig:ipc_sembuf}) che il programma chiamante deve avere cura di
 allocare in un opportuno vettore. La struttura permette di indicare il
 semaforo su cui operare, il tipo di operazione, ed un flag di controllo.
@@ -2089,7 +2093,7 @@ riferimento l'operazione; si ricordi che i semafori sono numerati come in un
 vettore, per cui il primo semaforo corrisponde ad un valore nullo di
 \var{sem\_num}.
 
-Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
+Il campo \var{sem\_flg} è un flag, mantenuto come maschera binaria, per il
 quale possono essere impostati i due valori \const{IPC\_NOWAIT} e
 \const{SEM\_UNDO}.  Impostando \const{IPC\_NOWAIT} si fa si che, invece di
 bloccarsi (in tutti quei casi in cui l'esecuzione di una operazione richiede
@@ -2098,7 +2102,7 @@ immediatamente con un errore di \errcode{EAGAIN}.  Impostando \const{SEM\_UNDO}
 si richiede invece che l'operazione venga registrata in modo che il valore del
 semaforo possa essere ripristinato all'uscita del processo.
 
-Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita
+Infine \var{sem\_op} è il campo che controlla l'operazione che viene eseguita
 e determina il comportamento della chiamata a \func{semop}; tre sono i casi
 possibili:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
@@ -2107,12 +2111,12 @@ possibili:
   immediatamente (con un errore di \errcode{ERANGE} qualora si sia superato il
   limite \const{SEMVMX}) ed il processo non viene bloccato in nessun caso.
   Specificando \const{SEM\_UNDO} si aggiorna il contatore per il ripristino
-  del valore del semaforo. Al processo chiamante è richiesto il privilegio di
+  del valore del semaforo. Al processo chiamante è richiesto il privilegio di
   alterazione (scrittura) sull'insieme di semafori.
   
 \item[\var{sem\_op}$=0$] Nel caso \var{semval} sia zero l'esecuzione procede
-  immediatamente. Se \var{semval} è diverso da zero il comportamento è
-  controllato da \var{sem\_flg}, se è stato impostato \const{IPC\_NOWAIT} la
+  immediatamente. Se \var{semval} è diverso da zero il comportamento è
+  controllato da \var{sem\_flg}, se è stato impostato \const{IPC\_NOWAIT} la
   funzione ritorna con un errore di \errcode{EAGAIN}, altrimenti viene
   incrementato \var{semzcnt} di uno ed il processo resta in stato di
   \textit{sleep} fintanto che non si ha una delle condizioni seguenti:
@@ -2125,16 +2129,16 @@ possibili:
     viene decrementato di uno e \func{semop} ritorna un errore di
     \errcode{EINTR}.
   \end{itemize*}
-  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
+  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
   semafori.
   
-\item[\var{sem\_op}$<0$] Nel caso in cui \var{semval} è maggiore o uguale del
-  valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
+\item[\var{sem\_op}$<0$] Nel caso in cui \var{semval} è maggiore o uguale del
+  valore assoluto di \var{sem\_op} (se cioè la somma dei due valori resta
   positiva o nulla) i valori vengono sommati e la funzione ritorna
   immediatamente; qualora si sia impostato \const{SEM\_UNDO} viene anche
   aggiornato il contatore per il ripristino del valore del semaforo. In caso
-  contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
-  negativo) se si è impostato \const{IPC\_NOWAIT} la funzione ritorna con un
+  contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
+  negativo) se si è impostato \const{IPC\_NOWAIT} la funzione ritorna con un
   errore di \errcode{EAGAIN}, altrimenti viene incrementato di uno
   \var{semncnt} ed il processo resta in stato di \textit{sleep} fintanto che
   non si ha una delle condizioni seguenti:
@@ -2150,7 +2154,7 @@ possibili:
     viene decrementato di uno e \func{semop} ritorna un errore di
     \errcode{EINTR}.
   \end{itemize*}    
-  Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
+  Al processo chiamante è richiesto il privilegio di alterazione (scrittura)
   sull'insieme di semafori.
 \end{basedescript}
 
@@ -2159,10 +2163,10 @@ ogni semaforo modificato al valore del \acr{pid} del processo chiamante;
 inoltre vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e
 \var{sem\_ctime}.
 
-Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
+Dato che, come già accennato in precedenza, in caso di uscita inaspettata i
 semafori possono restare occupati, abbiamo visto come \func{semop} permetta di
 attivare un meccanismo di ripristino attraverso l'uso del flag
-\const{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura
+\const{SEM\_UNDO}. Il meccanismo è implementato tramite una apposita struttura
 \struct{sem\_undo}, associata ad ogni processo per ciascun semaforo che esso
 ha modificato; all'uscita i semafori modificati vengono ripristinati, e le
 strutture disallocate.  Per mantenere coerente il comportamento queste
@@ -2170,13 +2174,13 @@ strutture non vengono ereditate attraverso una \func{fork} (altrimenti si
 avrebbe un doppio ripristino), mentre passano inalterate nell'esecuzione di
 una \func{exec} (altrimenti non si avrebbe ripristino).
 
-Tutto questo però ha un problema di fondo. Per capire di cosa si tratta
-occorre fare riferimento all'implementazione usata in Linux, che è riportata
-in maniera semplificata nello schema di fig.~\ref{fig:ipc_sem_schema}.  Si è
-presa come riferimento l'architettura usata fino al kernel 2.2.x che è più
+Tutto questo però ha un problema di fondo. Per capire di cosa si tratta
+occorre fare riferimento all'implementazione usata in Linux, che è riportata
+in maniera semplificata nello schema di fig.~\ref{fig:ipc_sem_schema}.  Si è
+presa come riferimento l'architettura usata fino al kernel 2.2.x che è più
 semplice (ed illustrata in dettaglio in \cite{tlk}); nel kernel 2.4.x la
-struttura del \textit{SysV IPC} è stata modificata, ma le definizioni relative
-a queste strutture restano per compatibilità.\footnote{in particolare con le
+struttura del \textit{SysV IPC} è stata modificata, ma le definizioni relative
+a queste strutture restano per compatibilità.\footnote{in particolare con le
   vecchie versioni delle librerie del C, come le libc5.}
 
 \begin{figure}[htb]
@@ -2195,20 +2199,20 @@ coda di attesa associata a ciascun insieme di semafori\footnote{che viene
   di \struct{semid\_ds}.}. 
 
 Nella struttura viene memorizzato il riferimento alle operazioni richieste
-(nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e
+(nel campo \var{sops}, che è un puntatore ad una struttura \struct{sembuf}) e
 al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo
-stato di attesa e viene invocato lo scheduler\itindex{scheduler} per passare
+stato di attesa e viene invocato lo \itindex{scheduler} scheduler per passare
 all'esecuzione di un altro processo.
 
 Se invece tutte le operazioni possono avere successo queste vengono eseguite
 immediatamente, dopo di che il kernel esegue una scansione della coda di
 attesa (a partire da \var{sem\_pending}) per verificare se qualcuna delle
-operazioni sospese in precedenza può essere eseguita, nel qual caso la
+operazioni sospese in precedenza può essere eseguita, nel qual caso la
 struttura \struct{sem\_queue} viene rimossa e lo stato del processo associato
 all'operazione (\var{sleeper}) viene riportato a \textit{running}; il tutto
-viene ripetuto fin quando non ci sono più operazioni eseguibili o si è
+viene ripetuto fin quando non ci sono più operazioni eseguibili o si è
 svuotata la coda.  Per gestire il meccanismo del ripristino tutte le volte che
-per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta
+per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta
 per ciascun insieme di semafori una apposita struttura \struct{sem\_undo} che
 contiene (nel vettore puntato dal campo \var{semadj}) un valore di
 aggiustamento per ogni semaforo cui viene sommato l'opposto del valore usato
@@ -2217,34 +2221,34 @@ per l'operazione.
 Queste strutture sono mantenute in due liste,\footnote{rispettivamente
   attraverso i due campi \var{id\_next} e \var{proc\_next}.} una associata
 all'insieme di cui fa parte il semaforo, che viene usata per invalidare le
-strutture se questo viene cancellato o per azzerarle se si è eseguita una
+strutture se questo viene cancellato o per azzerarle se si è eseguita una
 operazione con \func{semctl}; l'altra associata al processo che ha eseguito
 l'operazione;\footnote{attraverso il campo \var{semundo} di
   \struct{task\_struct}, come mostrato in \ref{fig:ipc_sem_schema}.} quando un
 processo termina, la lista ad esso associata viene scandita e le operazioni
-applicate al semaforo.  Siccome un processo può accumulare delle richieste di
+applicate al semaforo.  Siccome un processo può accumulare delle richieste di
 ripristino per semafori differenti chiamate attraverso diverse chiamate a
 \func{semop}, si pone il problema di come eseguire il ripristino dei semafori
-all'uscita del processo, ed in particolare se questo può essere fatto
+all'uscita del processo, ed in particolare se questo può essere fatto
 atomicamente.
 
-Il punto è cosa succede quando una delle operazioni previste per il ripristino
-non può essere eseguita immediatamente perché ad esempio il semaforo è
+Il punto è cosa succede quando una delle operazioni previste per il ripristino
+non può essere eseguita immediatamente perché ad esempio il semaforo è
 occupato; in tal caso infatti, se si pone il processo in stato di
-\textit{sleep} aspettando la disponibilità del semaforo (come faceva
-l'implementazione originaria) si perde l'atomicità dell'operazione. La scelta
-fatta dal kernel è pertanto quella di effettuare subito le operazioni che non
+\textit{sleep} aspettando la disponibilità del semaforo (come faceva
+l'implementazione originaria) si perde l'atomicità dell'operazione. La scelta
+fatta dal kernel è pertanto quella di effettuare subito le operazioni che non
 prevedono un blocco del processo e di ignorare silenziosamente le altre;
-questo però comporta il fatto che il ripristino non è comunque garantito in
+questo però comporta il fatto che il ripristino non è comunque garantito in
 tutte le occasioni.
 
 Come esempio di uso dell'interfaccia dei semafori vediamo come implementare
-con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice
-in questione, contenuto nel file \file{Mutex.c} allegato ai sorgenti, è
+con essa dei semplici \textit{mutex} (cioè semafori binari), tutto il codice
+in questione, contenuto nel file \file{Mutex.c} allegato ai sorgenti, è
 riportato in fig.~\ref{fig:ipc_mutex_create}. Utilizzeremo l'interfaccia per
 creare un insieme contenente un singolo semaforo, per il quale poi useremo un
-valore unitario per segnalare la disponibilità della risorsa, ed un valore
-nullo per segnalarne l'indisponibilità
+valore unitario per segnalare la disponibilità della risorsa, ed un valore
+nullo per segnalarne l'indisponibilità
 
 \begin{figure}[!bht]
   \footnotesize \centering
@@ -2257,33 +2261,33 @@ nullo per segnalarne l'indisponibilit
   \label{fig:ipc_mutex_create}
 \end{figure}
 
-La prima funzione (\texttt{\small 2--15}) è \func{MutexCreate} che data una
+La prima funzione (\texttt{\small 2--15}) è \func{MutexCreate} che data una
 chiave crea il semaforo usato per il mutex e lo inizializza, restituendone
-l'identificatore. Il primo passo (\texttt{\small 6}) è chiamare \func{semget}
+l'identificatore. Il primo passo (\texttt{\small 6}) è chiamare \func{semget}
 con \const{IPC\_CREATE} per creare il semaforo qualora non esista,
 assegnandogli i privilegi di lettura e scrittura per tutti. In caso di errore
 (\texttt{\small 7--9}) si ritorna subito il risultato di \func{semget},
 altrimenti (\texttt{\small 10}) si inizializza il semaforo chiamando
 \func{semctl} con il comando \const{SETVAL}, utilizzando l'unione
 \struct{semunion} dichiarata ed avvalorata in precedenza (\texttt{\small 4})
-ad 1 per significare che risorsa è libera. In caso di errore (\texttt{\small
+ad 1 per significare che risorsa è libera. In caso di errore (\texttt{\small
   11--13}) si restituisce il valore di ritorno di \func{semctl}, altrimenti
 (\texttt{\small 14}) si ritorna l'identificatore del semaforo.
 
-La seconda funzione (\texttt{\small 17--20}) è \func{MutexFind}, che, data una
+La seconda funzione (\texttt{\small 17--20}) è \func{MutexFind}, che, data una
 chiave, restituisce l'identificatore del semaforo ad essa associato. La
-comprensione del suo funzionamento è immediata in quanto essa è soltanto un
-\textit{wrapper}\footnote{si chiama così una funzione usata per fare da
+comprensione del suo funzionamento è immediata in quanto essa è soltanto un
+\textit{wrapper}\footnote{si chiama così una funzione usata per fare da
   \textsl{involucro} alla chiamata di un altra, usata in genere per
   semplificare un'interfaccia (come in questo caso) o per utilizzare con la
   stessa funzione diversi substrati (librerie, ecc.)  che possono fornire le
-  stesse funzionalità.} di una chiamata a \func{semget} per cercare
+  stesse funzionalità.} di una chiamata a \func{semget} per cercare
 l'identificatore associato alla chiave, il valore di ritorno di quest'ultima
 viene passato all'indietro al chiamante.
 
-La terza funzione (\texttt{\small 22--25}) è \func{MutexRead} che, dato un
+La terza funzione (\texttt{\small 22--25}) è \func{MutexRead} che, dato un
 identificatore, restituisce il valore del semaforo associato al mutex. Anche
-in questo caso la funzione è un \textit{wrapper} per una chiamata a
+in questo caso la funzione è un \textit{wrapper} per una chiamata a
 \func{semctl} con il comando \const{GETVAL}, che permette di restituire il
 valore del semaforo.
 
@@ -2295,35 +2299,35 @@ strutture \var{sem\_lock} e \var{sem\_unlock} definite in precedenza
 dell'opzione \const{SEM\_UNDO} per evitare che il semaforo resti bloccato in
 caso di terminazione imprevista del processo.
 
-L'ultima funzione (\texttt{\small 46--49}) della serie, è \func{MutexRemove},
+L'ultima funzione (\texttt{\small 46--49}) della serie, è \func{MutexRemove},
 che rimuove il mutex. Anche in questo caso si ha un wrapper per una chiamata a
 \func{semctl} con il comando \const{IPC\_RMID}, che permette di cancellare il
 semaforo; il valore di ritorno di quest'ultima viene passato all'indietro.
 
-Chiamare \func{MutexLock} decrementa il valore del semaforo: se questo è
-libero (ha già valore 1) sarà bloccato (valore nullo), se è bloccato la
-chiamata a \func{semop} si bloccherà fintanto che la risorsa non venga
-rilasciata. Chiamando \func{MutexUnlock} il valore del semaforo sarà
+Chiamare \func{MutexLock} decrementa il valore del semaforo: se questo è
+libero (ha già valore 1) sarà bloccato (valore nullo), se è bloccato la
+chiamata a \func{semop} si bloccherà fintanto che la risorsa non venga
+rilasciata. Chiamando \func{MutexUnlock} il valore del semaforo sarà
 incrementato di uno, sbloccandolo qualora fosse bloccato.  
 
 Si noti che occorre eseguire sempre prima \func{MutexLock} e poi
-\func{MutexUnlock}, perché se per un qualche errore si esegue più volte
+\func{MutexUnlock}, perché se per un qualche errore si esegue più volte
 quest'ultima il valore del semaforo crescerebbe oltre 1, e \func{MutexLock}
-non avrebbe più l'effetto aspettato (bloccare la risorsa quando questa è
+non avrebbe più l'effetto aspettato (bloccare la risorsa quando questa è
 considerata libera).  Infine si tenga presente che usare \func{MutexRead} per
 controllare il valore dei mutex prima di proseguire in una operazione di
 sblocco non servirebbe comunque, dato che l'operazione non sarebbe atomica.
 Vedremo in sez.~\ref{sec:ipc_lock_file} come sia possibile ottenere
 un'interfaccia analoga a quella appena illustrata, senza incorrere in questi
-problemi, usando il file locking\index{file!locking}.
+problemi, usando il \index{file!locking} \textit{file locking}.
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_sysv_shm}
 
-Il terzo oggetto introdotto dal \textit{SysV IPC} è quello dei segmenti di
-memoria condivisa. La funzione che permette di ottenerne uno è \funcd{shmget},
-ed il suo prototipo è:
+Il terzo oggetto introdotto dal \textit{SysV IPC} è quello dei segmenti di
+memoria condivisa. La funzione che permette di ottenerne uno è \funcd{shmget},
+ed il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/ipc.h} 
@@ -2334,37 +2338,37 @@ ed il suo prototipo 
   Restituisce l'identificatore di una memoria condivisa.
   
   \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1
-    in caso di errore, nel qual caso \var{errno} assumerà i valori:
+    in caso di errore, nel qual caso \var{errno} assumerà i valori:
     \begin{errlist}
-    \item[\errcode{ENOSPC}] Si è superato il limite (\const{SHMMNI}) sul numero
+    \item[\errcode{ENOSPC}] si è superato il limite (\const{SHMMNI}) sul numero
       di segmenti di memoria nel sistema, o cercato di allocare un segmento le
       cui dimensioni fanno superare il limite di sistema (\const{SHMALL}) per
       la memoria ad essi riservata.
-    \item[\errcode{EINVAL}] Si è richiesta una dimensione per un nuovo segmento
+    \item[\errcode{EINVAL}] si è richiesta una dimensione per un nuovo segmento
       maggiore di \const{SHMMAX} o minore di \const{SHMMIN}, o se il segmento
-      già esiste \param{size} è maggiore delle sue dimensioni.
-    \item[\errcode{ENOMEM}] Il sistema non ha abbastanza memoria per poter
+      già esiste \param{size} è maggiore delle sue dimensioni.
+    \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter
       contenere le strutture per un nuovo segmento di memoria condivisa.
     \end{errlist}
     ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
     \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
 \end{functions}
 
-La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
-identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
+La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed
+identico è l'uso degli argomenti \param{key} e \param{flag} per cui non
 ripeteremo quanto detto al proposito in sez.~\ref{sec:ipc_sysv_mq}. L'argomento
 \param{size} specifica invece la dimensione, in byte, del segmento, che viene
 comunque arrotondata al multiplo superiore di \const{PAGE\_SIZE}.
 
-La memoria condivisa è la forma più veloce di comunicazione fra due processi,
+La memoria condivisa è la forma più veloce di comunicazione fra due processi,
 in quanto permette agli stessi di vedere nel loro spazio di indirizzi una
-stessa sezione di memoria.  Pertanto non è necessaria nessuna operazione di
-copia per trasmettere i dati da un processo all'altro, in quanto ciascuno può
+stessa sezione di memoria.  Pertanto non è necessaria nessuna operazione di
+copia per trasmettere i dati da un processo all'altro, in quanto ciascuno può
 accedervi direttamente con le normali operazioni di lettura e scrittura dei
 dati in memoria.
 
 Ovviamente tutto questo ha un prezzo, ed il problema fondamentale della
-memoria condivisa è la sincronizzazione degli accessi. È evidente infatti che
+memoria condivisa è la sincronizzazione degli accessi. È evidente infatti che
 se un processo deve scambiare dei dati con un altro, si deve essere sicuri che
 quest'ultimo non acceda al segmento di memoria condivisa prima che il primo
 non abbia completato le operazioni di scrittura, inoltre nel corso di una
@@ -2385,7 +2389,7 @@ norma, significa insieme a dei semafori.
   \label{fig:ipc_shmid_ds}
 \end{figure}
 
-A ciascun segmento di memoria condivisa è associata una struttura
+A ciascun segmento di memoria condivisa è associata una struttura
 \struct{shmid\_ds}, riportata in fig.~\ref{fig:ipc_shmid_ds}.  Come nel caso
 delle code di messaggi quando si crea un nuovo segmento di memoria condivisa
 con \func{shmget} questa struttura viene inizializzata, in particolare il
@@ -2399,7 +2403,7 @@ invece:
 \item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
   segmento, viene inizializzato al tempo corrente.
 \item i campi \var{shm\_atime} e \var{shm\_dtime}, che esprimono
-  rispettivamente il tempo dell'ultima volta che il segmento è stato
+  rispettivamente il tempo dell'ultima volta che il segmento è stato
   agganciato o sganciato da un processo, vengono inizializzati a zero.
 \item il campo \var{shm\_lpid}, che esprime il \acr{pid} del processo che ha
   eseguito l'ultima operazione, viene inizializzato a zero.
@@ -2430,23 +2434,25 @@ che permettono di cambiarne il valore.
     & \textbf{Significato} \\
     \hline
     \hline
-    \const{SHMALL}& 0x200000&\file{shmall}& Numero massimo di pagine che 
-                                       possono essere usate per i segmenti di
-                                       memoria condivisa. \\
-    \const{SHMMAX}&0x2000000&\file{shmmax}& Dimensione massima di un segmento 
-                                            di memoria condivisa.\\
-    \const{SHMMNI}&     4096&\file{msgmni}& Numero massimo di segmenti di 
-                                            memoria condivisa presenti nel
-                                            kernel.\\ 
+    \const{SHMALL}& 0x200000&\procrelfile{/proc/sys/kernel}{shmall}
+                            & Numero massimo di pagine che 
+                              possono essere usate per i segmenti di
+                              memoria condivisa.\\
+    \const{SHMMAX}&0x2000000&\procrelfile{/proc/sys/kernel}{shmmax} 
+                            & Dimensione massima di un segmento di memoria
+                              condivisa.\\ 
+    \const{SHMMNI}&     4096&\procrelfile{/proc/sys/kernel}{msgmni}
+                            & Numero massimo di segmenti di memoria condivisa
+                              presenti nel kernel.\\ 
     \const{SHMMIN}&        1& ---         & Dimensione minima di un segmento di
-                                            memoria condivisa. \\
+                                            memoria condivisa.\\
     \const{SHMLBA}&\const{PAGE\_SIZE}&--- & Limite inferiore per le dimensioni
                                             minime di un segmento (deve essere
                                             allineato alle dimensioni di una
-                                            pagina di memoria). \\
+                                            pagina di memoria).\\
     \const{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
-                                            memoria condivisa 
-                                            per ciascun processo.\\
+                                            memoria condivisa per ciascun
+                                            processo.\\
 
 
     \hline
@@ -2458,7 +2464,7 @@ che permettono di cambiarne il valore.
 \end{table}
 
 Al solito la funzione che permette di effettuare le operazioni di controllo su
-un segmento di memoria condivisa è \funcd{shmctl}; il suo prototipo è:
+un segmento di memoria condivisa è \funcd{shmctl}; il suo prototipo è:
 \begin{functions}
   \headdecl{sys/ipc.h} 
   \headdecl{sys/shm.h}
@@ -2468,27 +2474,27 @@ un segmento di memoria condivisa 
   Esegue le operazioni di controllo su un segmento di memoria condivisa.
   
   \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-    errore, nel qual caso \var{errno} assumerà i valori:
+    errore, nel qual caso \var{errno} assumerà i valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] Si è richiesto \const{IPC\_STAT} ma i permessi non
+    \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma i permessi non
       consentono l'accesso in lettura al segmento.
-    \item[\errcode{EINVAL}] O \param{shmid} non è un identificatore valido o
-      \param{cmd} non è un comando valido.
-    \item[\errcode{EIDRM}] L'argomento \param{shmid} fa riferimento ad un
-      segmento che è stato cancellato.
-    \item[\errcode{EPERM}] Si è specificato un comando con \const{IPC\_SET} o
+    \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o
+      \param{cmd} non è un comando valido.
+    \item[\errcode{EIDRM}] l'argomento \param{shmid} fa riferimento ad un
+      segmento che è stato cancellato.
+    \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o
       \const{IPC\_RMID} senza i permessi necessari.
-    \item[\errcode{EOVERFLOW}] Si è tentato il comando \const{IPC\_STAT} ma il
-      valore del group-ID o dell'user-ID è troppo grande per essere
+    \item[\errcode{EOVERFLOW}] si è tentato il comando \const{IPC\_STAT} ma il
+      valore del group-ID o dell'user-ID è troppo grande per essere
       memorizzato nella struttura puntata da \param{buf}.
-    \item[\errcode{EFAULT}] L'indirizzo specificato con \param{buf} non è
+    \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è
       valido.
     \end{errlist}
 }
 \end{functions}
 
 Il comando specificato attraverso l'argomento \param{cmd} determina i diversi
-effetti della funzione; i possibili valori che esso può assumere, ed il
+effetti della funzione; i possibili valori che esso può assumere, ed il
 corrispondente comportamento della funzione, sono i seguenti:
 
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
@@ -2496,8 +2502,8 @@ corrispondente comportamento della funzione, sono i seguenti:
   condivisa nella struttura \struct{shmid\_ds} puntata da \param{buf}. Occorre
   che il processo chiamante abbia il permesso di lettura sulla segmento.
 \item[\const{IPC\_RMID}] Marca il segmento di memoria condivisa per la
-  rimozione, questo verrà cancellato effettivamente solo quando l'ultimo
-  processo ad esso agganciato si sarà staccato. Questo comando può essere
+  rimozione, questo verrà cancellato effettivamente solo quando l'ultimo
+  processo ad esso agganciato si sarà staccato. Questo comando può essere
   eseguito solo da un processo con user-ID effettivo corrispondente o al
   creatore del segmento, o al proprietario del segmento, o all'amministratore.
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
@@ -2505,32 +2511,32 @@ corrispondente comportamento della funzione, sono i seguenti:
   \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o
   il creatore del segmento, oppure l'amministratore. Compiuta l'operazione
   aggiorna anche il valore del campo \var{shm\_ctime}.
-\item[\const{SHM\_LOCK}] Abilita il \textit{memory
-    locking}\itindex{memory~locking}\footnote{impedisce cioè che la memoria
-    usata per il segmento venga salvata su disco dal meccanismo della memoria
-    virtuale\index{memoria~virtuale}; si ricordi quanto trattato in
+\item[\const{SHM\_LOCK}] Abilita il \itindex{memory~locking} \textit{memory
+    locking}\footnote{impedisce cioè che la memoria usata per il segmento
+    venga salvata su disco dal meccanismo della \index{memoria~virtuale}
+    memoria virtuale; si ricordi quanto trattato in
     sez.~\ref{sec:proc_mem_lock}.} sul segmento di memoria condivisa. Solo
-  l'amministratore può utilizzare questo comando.
-\item[\const{SHM\_UNLOCK}] Disabilita il \textit{memory
-    locking}\itindex{memory~locking} sul segmento di memoria condivisa.  Solo
-  l'amministratore può utilizzare questo comando.
+  l'amministratore può utilizzare questo comando.
+\item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
+  \textit{memory locking} sul segmento di memoria condivisa.  Solo
+  l'amministratore può utilizzare questo comando.
 \end{basedescript}
-i primi tre comandi sono gli stessi già visti anche per le code di messaggi e
+i primi tre comandi sono gli stessi già visti anche per le code di messaggi e
 gli insiemi di semafori, gli ultimi due sono delle estensioni specifiche
 previste da Linux, che permettono di abilitare e disabilitare il meccanismo
-della memoria virtuale\index{memoria~virtuale} per il segmento.
+della \index{memoria~virtuale} memoria virtuale per il segmento.
 
 L'argomento \param{buf} viene utilizzato solo con i comandi \const{IPC\_STAT}
-e \const{IPC\_SET} nel qual caso esso dovrà puntare ad una struttura
+e \const{IPC\_SET} nel qual caso esso dovrà puntare ad una struttura
 \struct{shmid\_ds} precedentemente allocata, in cui nel primo caso saranno
 scritti i dati del segmento di memoria restituiti dalla funzione e da cui, nel
 secondo caso, verranno letti i dati da impostare sul segmento.
 
-Una volta che lo si è creato, per utilizzare un segmento di memoria condivisa
+Una volta che lo si è creato, per utilizzare un segmento di memoria condivisa
 l'interfaccia prevede due funzioni, \funcd{shmat} e \func{shmdt}. La prima di
 queste serve ad agganciare un segmento al processo chiamante, in modo che
 quest'ultimo possa inserirlo nel suo spazio di indirizzi per potervi accedere;
-il suo prototipo è:
+il suo prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/shm.h}
@@ -2539,12 +2545,12 @@ il suo prototipo 
   Aggancia al processo un segmento di memoria condivisa.
   
   \bodydesc{La funzione restituisce l'indirizzo del segmento in caso di
-    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
+    successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i
     valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] Il processo non ha i privilegi per accedere al
-      segmento nella modalità richiesta.
-    \item[\errcode{EINVAL}] Si è specificato un identificatore invalido per
+    \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
+      segmento nella modalità richiesta.
+    \item[\errcode{EINVAL}] si è specificato un identificatore invalido per
       \param{shmid}, o un indirizzo non allineato sul confine di una pagina
       per \param{shmaddr}.
     \end{errlist}
@@ -2553,37 +2559,37 @@ il suo prototipo 
 
 La funzione inserisce un segmento di memoria condivisa all'interno dello
 spazio di indirizzi del processo, in modo che questo possa accedervi
-direttamente, la situazione dopo l'esecuzione di \func{shmat} è illustrata in
+direttamente, la situazione dopo l'esecuzione di \func{shmat} è illustrata in
 fig.~\ref{fig:ipc_shmem_layout} (per la comprensione del resto dello schema si
 ricordi quanto illustrato al proposito in sez.~\ref{sec:proc_mem_layout}). In
 particolare l'indirizzo finale del segmento dati (quello impostato da
-\func{brk}, vedi sez.~\ref{sec:proc_mem_sbrk_alloca}) non viene influenzato.
-Si tenga presente infine che la funzione ha successo anche se il segmento è
+\func{brk}, vedi sez.~\ref{sec:proc_mem_alloc}) non viene influenzato.
+Si tenga presente infine che la funzione ha successo anche se il segmento è
 stato marcato per la cancellazione.
 
 \begin{figure}[htb]
   \centering
   \includegraphics[height=10cm]{img/sh_memory_layout}
-  \caption{Disposizione dei segmenti di memoria di un processo quando si è
+  \caption{Disposizione dei segmenti di memoria di un processo quando si è
     agganciato un segmento di memoria condivisa.}
   \label{fig:ipc_shmem_layout}
 \end{figure}
 
-L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{Lo standard
-  SVID prevede che l'argomento \param{shmaddr} sia di tipo \ctyp{char *}, così
-  come il valore di ritorno della funzione. In Linux è stato così con le
+L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{lo standard
+  SVID prevede che l'argomento \param{shmaddr} sia di tipo \ctyp{char *}, così
+  come il valore di ritorno della funzione; in Linux è stato così con le
   \acr{libc4} e le \acr{libc5}, con il passaggio alle \acr{glibc} il tipo di
-  \param{shmaddr} è divenuto un \ctyp{const void *} e quello del valore di
+  \param{shmaddr} è divenuto un \ctyp{const void *} e quello del valore di
   ritorno un \ctyp{void *}.} deve essere associato il segmento, se il valore
-specificato è \val{NULL} è il sistema a scegliere opportunamente un'area di
-memoria libera (questo è il modo più portabile e sicuro di usare la funzione).
+specificato è \val{NULL} è il sistema a scegliere opportunamente un'area di
+memoria libera (questo è il modo più portabile e sicuro di usare la funzione).
 Altrimenti il kernel aggancia il segmento all'indirizzo specificato da
-\param{shmaddr}; questo però può avvenire solo se l'indirizzo coincide con il
-limite di una pagina, cioè se è un multiplo esatto del parametro di sistema
-\const{SHMLBA}, che in Linux è sempre uguale \const{PAGE\_SIZE}. 
+\param{shmaddr}; questo però può avvenire solo se l'indirizzo coincide con il
+limite di una pagina, cioè se è un multiplo esatto del parametro di sistema
+\const{SHMLBA}, che in Linux è sempre uguale \const{PAGE\_SIZE}. 
 
-Si tenga presente però che quando si usa \val{NULL} come valore di
-\param{shmaddr}, l'indirizzo restituito da \func{shmat} può cambiare da
+Si tenga presente però che quando si usa \val{NULL} come valore di
+\param{shmaddr}, l'indirizzo restituito da \func{shmat} può cambiare da
 processo a processo; pertanto se nell'area di memoria condivisa si salvano
 anche degli indirizzi, si deve avere cura di usare valori relativi (in genere
 riferiti all'indirizzo di partenza del segmento).
@@ -2593,20 +2599,20 @@ funzione; esso va specificato come maschera binaria, i bit utilizzati sono
 solo due e sono identificati dalle costanti \const{SHM\_RND} e
 \const{SHM\_RDONLY}, che vanno combinate con un OR aritmetico.  Specificando
 \const{SHM\_RND} si evita che \func{shmat} ritorni un errore quando
-\param{shmaddr} non è allineato ai confini di una pagina. Si può quindi usare
-un valore qualunque per \param{shmaddr}, e il segmento verrà comunque
-agganciato, ma al più vicino multiplo di \const{SHMLBA} (il nome della
+\param{shmaddr} non è allineato ai confini di una pagina. Si può quindi usare
+un valore qualunque per \param{shmaddr}, e il segmento verrà comunque
+agganciato, ma al più vicino multiplo di \const{SHMLBA} (il nome della
 costante sta infatti per \textit{rounded}, e serve per specificare un
-indirizzo come arrotondamento, in Linux è equivalente a \const{PAGE\_SIZE}).
+indirizzo come arrotondamento, in Linux è equivalente a \const{PAGE\_SIZE}).
 
 L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola
 lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal
-caso un tentativo di scrivere sul segmento comporterà una violazione di
-accesso con l'emissione di un segnale di \const{SIGSEGV}. Il comportamento
-usuale di \func{shmat} è quello di agganciare il segmento con l'accesso in
-lettura e scrittura (ed il processo deve aver questi permessi in
-\var{shm\_perm}), non è prevista la possibilità di agganciare un segmento in
-sola scrittura.
+caso un tentativo di scrivere sul segmento comporterà una
+\itindex{segment~violation} violazione di accesso con l'emissione di un
+segnale di \const{SIGSEGV}. Il comportamento usuale di \func{shmat} è quello
+di agganciare il segmento con l'accesso in lettura e scrittura (ed il processo
+deve aver questi permessi in \var{shm\_perm}), non è prevista la possibilità
+di agganciare un segmento in sola scrittura.
 
 In caso di successo la funzione aggiorna anche i seguenti campi di
 \struct{shmid\_ds}:
@@ -2628,9 +2634,9 @@ diverso, tutti i segmenti agganciati al processo originario vengono
 automaticamente sganciati. Lo stesso avviene all'uscita del processo
 attraverso una \func{exit}.
 
-Una volta che un segmento di memoria condivisa non serve più, si può
+Una volta che un segmento di memoria condivisa non serve più, si può
 sganciarlo esplicitamente dal processo usando l'altra funzione
-dell'interfaccia, \funcd{shmdt}, il cui prototipo è:
+dell'interfaccia, \funcd{shmdt}, il cui prototipo è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{sys/shm.h}
@@ -2639,7 +2645,7 @@ dell'interfaccia, \funcd{shmdt}, il cui prototipo 
   Sgancia dal processo un segmento di memoria condivisa.
   
   \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
-    errore, la funzione fallisce solo quando non c'è un segmento agganciato
+    errore, la funzione fallisce solo quando non c'è un segmento agganciato
     all'indirizzo \param{shmaddr}, con \var{errno} che assume il valore
     \errval{EINVAL}.}
 \end{functions}
@@ -2675,10 +2681,10 @@ viene tolta dallo spazio di indirizzi del processo.
 
 Come esempio di uso di queste funzioni vediamo come implementare una serie di
 funzioni di libreria che ne semplifichino l'uso, automatizzando le operazioni
-più comuni; il codice, contenuto nel file \file{SharedMem.c}, è riportato in
+più comuni; il codice, contenuto nel file \file{SharedMem.c}, è riportato in
 fig.~\ref{fig:ipc_sysv_shm_func}.
 
-La prima funzione (\texttt{\small 3--16}) è \func{ShmCreate} che, data una
+La prima funzione (\texttt{\small 3--16}) è \func{ShmCreate} che, data una
 chiave, crea il segmento di memoria condivisa restituendo il puntatore allo
 stesso. La funzione comincia (\texttt{\small 6}) con il chiamare
 \func{shmget}, usando il flag \const{IPC\_CREATE} per creare il segmento
@@ -2692,7 +2698,7 @@ memoria condivisa al processo con \func{shmat}. In caso di errore
 segmento al valore costante specificato dall'argomento \var{fill}, e poi si
 ritorna il puntatore al segmento stesso.
 
-La seconda funzione (\texttt{\small 17--31}) è \func{ShmFind}, che, data una
+La seconda funzione (\texttt{\small 17--31}) è \func{ShmFind}, che, data una
 chiave, restituisce l'indirizzo del segmento ad essa associato. Anzitutto
 (\texttt{\small 22}) si richiede l'identificatore del segmento con
 \func{shmget}, ritornando (\texttt{\small 23--25}) un puntatore nullo in caso
@@ -2701,33 +2707,33 @@ processo con \func{shmat}, restituendo (\texttt{\small 27--29}) di nuovo un
 puntatore nullo in caso di errore, se invece non ci sono errori si restituisce
 il puntatore ottenuto da \func{shmat}.
 
-La terza funzione (\texttt{\small 32--51}) è \func{ShmRemove} che, data la
+La terza funzione (\texttt{\small 32--51}) è \func{ShmRemove} che, data la
 chiave ed il puntatore associati al segmento di memoria condivisa, prima lo
-sgancia dal processo e poi lo rimuove. Il primo passo (\texttt{\small 37}) è
+sgancia dal processo e poi lo rimuove. Il primo passo (\texttt{\small 37}) è
 la chiamata a \func{shmdt} per sganciare il segmento, restituendo
 (\texttt{\small 38--39}) un valore -1 in caso di errore. Il passo successivo
-(\texttt{\small 41}) è utilizzare \func{shmget} per ottenre l'identificatore
+(\texttt{\small 41}) è utilizzare \func{shmget} per ottenere l'identificatore
 associato al segmento data la chiave \var{key}. Al solito si restituisce un
 valore di -1 (\texttt{\small 42--45}) in caso di errore, mentre se tutto va
 bene si conclude restituendo un valore nullo.
 
-Benché la memoria condivisa costituisca il meccanismo di intercomunicazione
-fra processi più veloce, essa non è sempre il più appropriato, dato che, come
-abbiamo visto, si avrà comunque la necessità di una sincronizzazione degli
-accessi.  Per questo motivo, quando la comunicazione fra processi è
+Benché la memoria condivisa costituisca il meccanismo di intercomunicazione
+fra processi più veloce, essa non è sempre il più appropriato, dato che, come
+abbiamo visto, si avrà comunque la necessità di una sincronizzazione degli
+accessi.  Per questo motivo, quando la comunicazione fra processi è
 sequenziale, altri meccanismi come le pipe, le fifo o i socket, che non
 necessitano di sincronizzazione esplicita, sono da preferire. Essa diventa
-l'unico meccanismo possibile quando la comunicazione non è
+l'unico meccanismo possibile quando la comunicazione non è
 sequenziale\footnote{come accennato in sez.~\ref{sec:ipc_sysv_mq} per la
   comunicazione non sequenziale si possono usare le code di messaggi,
-  attraverso l'uso del campo \var{mtype}, ma solo se quest'ultima può essere
-  effettuata in forma di messaggio.} o quando non può avvenire secondo una
-modalità predefinita.
+  attraverso l'uso del campo \var{mtype}, ma solo se quest'ultima può essere
+  effettuata in forma di messaggio.} o quando non può avvenire secondo una
+modalità predefinita.
 
-Un esempio classico di uso della memoria condivisa è quello del
+Un esempio classico di uso della memoria condivisa è quello del
 ``\textit{monitor}'', in cui viene per scambiare informazioni fra un processo
 server, che vi scrive dei dati di interesse generale che ha ottenuto, e i
-processi client interessati agli stessi dati che così possono leggerli in
+processi client interessati agli stessi dati che così possono leggerli in
 maniera completamente asincrona.  Con questo schema di funzionamento da una
 parte si evita che ciascun processo client debba compiere l'operazione,
 potenzialmente onerosa, di ricavare e trattare i dati, e dall'altra si evita
@@ -2736,13 +2742,13 @@ al processo server di dover gestire l'invio a tutti i client di tutti i dati
 client).
 
 Nel nostro caso implementeremo un ``\textsl{monitor}'' di una directory: un
-processo si incaricherà di tenere sotto controllo alcuni parametri relativi ad
+processo si incaricherà di tenere sotto controllo alcuni parametri relativi ad
 una directory (il numero dei file contenuti, la dimensione totale, quante
 directory, link simbolici, file normali, ecc.) che saranno salvati in un
 segmento di memoria condivisa cui altri processi potranno accedere per
 ricavare la parte di informazione che interessa.
 
-In fig.~\ref{fig:ipc_dirmonitor_main} si è riportata la sezione principale del
+In fig.~\ref{fig:ipc_dirmonitor_main} si è riportata la sezione principale del
 corpo del programma server, insieme alle definizioni delle altre funzioni
 usate nel programma e delle variabili globali, omettendo tutto quello che
 riguarda la gestione delle opzioni e la stampa delle istruzioni di uso a
@@ -2760,16 +2766,16 @@ video; al solito il codice completo si trova con i sorgenti allegati nel file
 \end{figure}
 
 Il programma usa delle variabili globali (\texttt{\small 2--14}) per mantenere
-i valori relativi agli oggetti usati per la comunicazione inter-processo; si è
+i valori relativi agli oggetti usati per la comunicazione inter-processo; si è
 definita inoltre una apposita struttura \struct{DirProp} che contiene i dati
-relativi alle proprietà che si vogliono mantenere nella memoria condivisa, per
+relativi alle proprietà che si vogliono mantenere nella memoria condivisa, per
 l'accesso da parte dei client.
 
 Il programma, dopo la sezione, omessa, relativa alla gestione delle opzioni da
 riga di comando (che si limitano alla eventuale stampa di un messaggio di
 aiuto a video ed all'impostazione della durata dell'intervallo con cui viene
-ripetuto il calcolo delle proprietà della directory) controlla (\texttt{\small
-  20--23}) che sia stato specificato l'argoemnto necessario contenente il nome
+ripetuto il calcolo delle proprietà della directory) controlla (\texttt{\small
+  20--23}) che sia stato specificato l'argomento necessario contenente il nome
 della directory da tenere sotto controllo, senza il quale esce immediatamente
 con un messaggio di errore.
 
@@ -2778,7 +2784,7 @@ si esegue (\texttt{\small 24--26}) su di esso una \func{chdir}, uscendo
 immediatamente in caso di errore.  Questa funzione serve anche per impostare
 la directory di lavoro del programma nella directory da tenere sotto
 controllo, in vista del successivo uso della funzione
-\func{daemon}.\footnote{si noti come si è potuta fare questa scelta,
+\func{daemon}.\footnote{si noti come si è potuta fare questa scelta,
   nonostante le indicazioni illustrate in sez.~\ref{sec:sess_daemon}, per il
   particolare scopo del programma, che necessita comunque di restare
   all'interno di una directory.} Infine (\texttt{\small 27--29}) si installano
@@ -2786,21 +2792,21 @@ i gestori per i vari segnali di terminazione che, avendo a che fare con un
 programma che deve essere eseguito come server, sono il solo strumento
 disponibile per concluderne l'esecuzione.
 
-Il passo successivo (\texttt{\small 30--39}) è quello di creare gli oggetti di
+Il passo successivo (\texttt{\small 30--39}) è quello di creare gli oggetti di
 intercomunicazione necessari. Si inizia costruendo (\texttt{\small 30}) la
-chiave da usare come riferimento con il nome del programma,\footnote{si è
+chiave da usare come riferimento con il nome del programma,\footnote{si è
   usato un riferimento relativo alla home dell'utente, supposto che i sorgenti
   di GaPiL siano stati installati direttamente in essa. Qualora si effettui
-  una installazione diversa si dovrà correggere il programma.} dopo di che si
+  una installazione diversa si dovrà correggere il programma.} dopo di che si
 richiede (\texttt{\small 31}) la creazione di un segmento di memoria condivisa
 con usando la funzione \func{ShmCreate} illustrata in precedenza (una pagina
-di memoria è sufficiente per i dati che useremo), uscendo (\texttt{\small
+di memoria è sufficiente per i dati che useremo), uscendo (\texttt{\small
   32--35}) qualora la creazione ed il successivo agganciamento al processo non
-abbia successo. Con l'indirizzo \var{shmptr} così ottenuto potremo poi
+abbia successo. Con l'indirizzo \var{shmptr} così ottenuto potremo poi
 accedere alla memoria condivisa, che, per come abbiamo lo abbiamo definito,
-sarà vista nella forma data da \struct{DirProp}. Infine (\texttt{\small
+sarà vista nella forma data da \struct{DirProp}. Infine (\texttt{\small
   36--39}) utilizzando sempre la stessa chiave, si crea, tramite le funzioni
-di interfaccia già descritte in sez.~\ref{sec:ipc_sysv_sem}, anche un mutex,
+di interfaccia già descritte in sez.~\ref{sec:ipc_sysv_sem}, anche un mutex,
 che utilizzeremo per regolare l'accesso alla memoria condivisa.
 
 \begin{figure}[!htb]
@@ -2815,15 +2821,15 @@ che utilizzeremo per regolare l'accesso alla memoria condivisa.
 
 Completata l'inizializzazione e la creazione degli oggetti di
 intercomunicazione il programma entra nel ciclo principale (\texttt{\small
-  40--49}) dove vengono eseguite indefinitamente le attività di monitoraggio.
-Il primo passo (\texttt{\small 41}) è eseguire \func{daemon} per proseguire
+  40--49}) dove vengono eseguite indefinitamente le attività di monitoraggio.
+Il primo passo (\texttt{\small 41}) è eseguire \func{daemon} per proseguire
 con l'esecuzione in background come si conviene ad un programma demone; si
-noti che si è mantenuta, usando un valore non nullo del primo argomento, la
-directory di lavoro corrente.  Una volta che il programma è andato in
+noti che si è mantenuta, usando un valore non nullo del primo argomento, la
+directory di lavoro corrente.  Una volta che il programma è andato in
 background l'esecuzione prosegue (\texttt{\small 42--48}) all'interno di un
 ciclo infinito: si inizia (\texttt{\small 43}) bloccando il mutex con
 \func{MutexLock} per poter accedere alla memoria condivisa (la funzione si
-bloccherà automaticamente se qualche client sta leggendo), poi (\texttt{\small
+bloccherà automaticamente se qualche client sta leggendo), poi (\texttt{\small
   44}) si cancellano i valori precedentemente immagazzinati nella memoria
 condivisa con \func{memset}, e si esegue (\texttt{\small 45}) un nuovo calcolo
 degli stessi utilizzando la funzione \func{DirScan}; infine (\texttt{\small
@@ -2832,31 +2838,31 @@ degli stessi utilizzando la funzione \func{DirScan}; infine (\texttt{\small
 l'opzione \code{-p} con una \func{sleep}.
 
 Si noti come per il calcolo dei valori da mantenere nella memoria condivisa si
-sia usata ancora una volta la funzione \func{DirScan}, già utilizzata (e
+sia usata ancora una volta la funzione \func{DirScan}, già utilizzata (e
 descritta in dettaglio) in sez.~\ref{sec:file_dir_read}, che ci permette di
 effettuare la scansione delle voci della directory, chiamando per ciascuna di
 esse la funzione \func{ComputeValues}, che esegue tutti i calcoli necessari.
 
-Il codice di quest'ultima è riportato in fig.~\ref{fig:ipc_dirmonitor_sub}.
-Come si vede la funzione (\texttt{\small 2--16}) è molto semplice e si limita
+Il codice di quest'ultima è riportato in fig.~\ref{fig:ipc_dirmonitor_sub}.
+Come si vede la funzione (\texttt{\small 2--16}) è molto semplice e si limita
 a chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da
 ciascuna voce, per ottenerne i dati, che poi utilizza per incrementare i vari
 contatori nella memoria condivisa, cui accede grazie alla variabile globale
 \var{shmptr}.
 
-Dato che la funzione è chiamata da \func{DirScan}, si è all'interno del ciclo
-principale del programma, con un mutex acquisito, perciò non è necessario
-effettuare nessun controllo e si può accedere direttamente alla memoria
+Dato che la funzione è chiamata da \func{DirScan}, si è all'interno del ciclo
+principale del programma, con un mutex acquisito, perciò non è necessario
+effettuare nessun controllo e si può accedere direttamente alla memoria
 condivisa usando \var{shmptr} per riempire i campi della struttura
-\struct{DirProp}; così prima (\texttt{\small 6--7}) si sommano le dimensioni
+\struct{DirProp}; così prima (\texttt{\small 6--7}) si sommano le dimensioni
 dei file ed il loro numero, poi, utilizzando le macro di
 tab.~\ref{tab:file_type_macro}, si contano (\texttt{\small 8--14}) quanti ce
 ne sono per ciascun tipo.
 
-In fig.~\ref{fig:ipc_dirmonitor_sub} è riportato anche il codice
+In fig.~\ref{fig:ipc_dirmonitor_sub} è riportato anche il codice
 (\texttt{\small 17--23}) del gestore dei segnali di terminazione, usato per
 chiudere il programma. Esso, oltre a provocare l'uscita del programma, si
-incarica anche di cancellare tutti gli oggetti di intercomunicazione non più
+incarica anche di cancellare tutti gli oggetti di intercomunicazione non più
 necessari.  Per questo anzitutto (\texttt{\small 19}) acquisisce il mutex con
 \func{MutexLock}, per evitare di operare mentre un client sta ancora leggendo
 i dati, dopo di che (\texttt{\small 20}) distacca e rimuove il segmento di
@@ -2869,15 +2875,15 @@ rimuove il mutex con \func{MutexRemove} ed esce (\texttt{\small 22}).
     \includecodesample{listati/ReadMonitor.c}
   \end{minipage} 
   \normalsize 
-  \caption{Codice del programma client del monitor delle proprietà di una
+  \caption{Codice del programma client del monitor delle proprietà di una
     directory, \file{ReadMonitor.c}.}
   \label{fig:ipc_dirmonitor_client}
 \end{figure}
 
 Il codice del client usato per leggere le informazioni mantenute nella memoria
-condivisa è riportato in fig.~\ref{fig:ipc_dirmonitor_client}. Al solito si è
+condivisa è riportato in fig.~\ref{fig:ipc_dirmonitor_client}. Al solito si è
 omessa la sezione di gestione delle opzioni e la funzione che stampa a video
-le istruzioni; il codice completo è nei sorgenti allegati, nel file
+le istruzioni; il codice completo è nei sorgenti allegati, nel file
 \file{ReadMonitor.c}.
 
 Una volta conclusa la gestione delle opzioni a riga di comando il programma
@@ -2890,21 +2896,22 @@ mutex.  Completata l'inizializzazione ed ottenuti i riferimenti agli oggetti
 di intercomunicazione necessari viene eseguito il corpo principale del
 programma (\texttt{\small 21--33}); si comincia (\texttt{\small 22})
 acquisendo il mutex con \func{MutexLock}; qui avviene il blocco del processo
-se la memoria condivisa non è disponibile.  Poi (\texttt{\small 23--31}) si
+se la memoria condivisa non è disponibile.  Poi (\texttt{\small 23--31}) si
 stampano i vari valori mantenuti nella memoria condivisa attraverso l'uso di
 \var{shmptr}.  Infine (\texttt{\small 41}) con \func{MutexUnlock} si rilascia
 il mutex, prima di uscire.
 
 Verifichiamo allora il funzionamento dei nostri programmi; al solito, usando
 le funzioni di libreria occorre definire opportunamente
-\code{LD\_LIBRARY\_PATH}; poi si potrà lanciare il server con:
-\begin{verbatim}
+\code{LD\_LIBRARY\_PATH}; poi si potrà lanciare il server con:
+\begin{Verbatim}
 [piccardi@gont sources]$ ./dirmonitor ./
-\end{verbatim}%$
-ed avendo usato \func{daemon} il comando ritornerà immediatamente. Una volta
-che il server è in esecuzione, possiamo passare ad invocare il client per
+\end{Verbatim}
+%$
+ed avendo usato \func{daemon} il comando ritornerà immediatamente. Una volta
+che il server è in esecuzione, possiamo passare ad invocare il client per
 verificarne i risultati, in tal caso otterremo:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ./readmon 
 Ci sono 68 file dati
 Ci sono 3 directory
@@ -2914,12 +2921,13 @@ Ci sono 0 socket
 Ci sono 0 device a caratteri
 Ci sono 0 device a blocchi
 Totale  71 file, per 489831 byte
-\end{verbatim}%$
+\end{Verbatim}
+%$
 ed un rapido calcolo (ad esempio con \code{ls -a | wc} per contare i file) ci
-permette di verificare che il totale dei file è giusto. Un controllo con
+permette di verificare che il totale dei file è giusto. Un controllo con
 \cmd{ipcs} ci permette inoltre di verificare la presenza di un segmento di
 memoria condivisa e di un semaforo:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ipcs
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
@@ -2931,12 +2939,13 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{verbatim}%$
+\end{Verbatim}
+%$
 
 Se a questo punto aggiungiamo un file, ad esempio con \code{touch prova},
 potremo verificare che, passati nel peggiore dei casi almeno 10 secondi (o
 l'eventuale altro intervallo impostato per la rilettura dei dati) avremo:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ./readmon 
 Ci sono 69 file dati
 Ci sono 3 directory
@@ -2946,18 +2955,20 @@ Ci sono 0 socket
 Ci sono 0 device a caratteri
 Ci sono 0 device a blocchi
 Totale  72 file, per 489887 byte
-\end{verbatim}%$
+\end{Verbatim}
+%$
 
 A questo punto possiamo far uscire il server inviandogli un segnale di
 \const{SIGTERM} con il comando \code{killall dirmonitor}, a questo punto
 ripetendo la lettura, otterremo un errore:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ./readmon 
 Cannot find shared memory: No such file or directory
-\end{verbatim}%$
+\end{Verbatim}
+%$
 e inoltre potremo anche verificare che anche gli oggetti di intercomunicazione
 visti in precedenza sono stati regolarmente  cancellati:
-\begin{verbatim}
+\begin{Verbatim}
 [piccardi@gont sources]$ ipcs
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
@@ -2967,13 +2978,13 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{verbatim}%$
-
+\end{Verbatim}
+%$
 
 
 %% Per capire meglio il funzionamento delle funzioni facciamo ancora una volta
 %% riferimento alle strutture con cui il kernel implementa i segmenti di memoria
-%% condivisa; uno schema semplificato della struttura è illustrato in
+%% condivisa; uno schema semplificato della struttura è illustrato in
 %% fig.~\ref{fig:ipc_shm_struct}. 
 
 %% \begin{figure}[htb]
@@ -2994,7 +3005,7 @@ Come abbiamo detto in sez.~\ref{sec:ipc_sysv_generic}, e ripreso nella
 descrizione dei singoli oggetti che ne fan parte, il \textit{SysV IPC}
 presenta numerosi problemi; in \cite{APUE}\footnote{in particolare nel
   capitolo 14.}  Stevens ne effettua una accurata analisi (alcuni dei concetti
-sono già stati accennati in precedenza) ed elenca alcune possibili tecniche
+sono già stati accennati in precedenza) ed elenca alcune possibili tecniche
 alternative, che vogliamo riprendere in questa sezione.
 
 
@@ -3004,53 +3015,54 @@ alternative, che vogliamo riprendere in questa sezione.
 Le code di messaggi sono probabilmente il meno usato degli oggetti del
 \textit{SysV IPC}; esse infatti nacquero principalmente come meccanismo di
 comunicazione bidirezionale quando ancora le pipe erano unidirezionali; con la
-disponibilità di \func{socketpair} (vedi sez.~\ref{sec:ipc_socketpair}) o
-utilizzando una coppia di pipe, si può ottenere questo risultato senza
+disponibilità di \func{socketpair} (vedi sez.~\ref{sec:ipc_socketpair}) o
+utilizzando una coppia di pipe, si può ottenere questo risultato senza
 incorrere nelle complicazioni introdotte dal \textit{SysV IPC}.
 
-In realtà, grazie alla presenza del campo \var{mtype}, le code di messaggi
+In realtà, grazie alla presenza del campo \var{mtype}, le code di messaggi
 hanno delle caratteristiche ulteriori, consentendo una classificazione dei
 messaggi ed un accesso non rigidamente sequenziale; due caratteristiche che
-sono impossibili da ottenere con le pipe e i socket\index{socket} di
-\func{socketpair}.  A queste esigenze però si può comunque ovviare in maniera
-diversa con un uso combinato della memoria condivisa e dei meccanismi di
-sincronizzazione, per cui alla fine l'uso delle code di messaggi classiche è
-relativamente poco diffuso.
+sono impossibili da ottenere con le pipe e i socket di \func{socketpair}.  A
+queste esigenze però si può comunque ovviare in maniera diversa con un uso
+combinato della memoria condivisa e dei meccanismi di sincronizzazione, per
+cui alla fine l'uso delle code di messaggi classiche è relativamente poco
+diffuso.
 
 \subsection{I \textsl{file di lock}}
 \label{sec:ipc_file_lock}
 
 \index{file!di lock|(}
+
 Come illustrato in sez.~\ref{sec:ipc_sysv_sem} i semafori del \textit{SysV IPC}
 presentano una interfaccia inutilmente complessa e con alcuni difetti
 strutturali, per questo quando si ha una semplice esigenza di sincronizzazione
 per la quale basterebbe un semaforo binario (quello che abbiamo definito come
-\textit{mutex}), per indicare la disponibilità o meno di una risorsa, senza la
-necessità di un contatore come i semafori, si possono utilizzare metodi
+\textit{mutex}), per indicare la disponibilità o meno di una risorsa, senza la
+necessità di un contatore come i semafori, si possono utilizzare metodi
 alternativi.
 
-La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
+La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
 dei \textsl{file di lock} (per i quali esiste anche una opportuna directory,
 \file{/var/lock}, nel filesystem standard). Per questo si usa la
 caratteristica della funzione \func{open} (illustrata in
-sez.~\ref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo
-  standard POSIX.1, ciò non toglie che in alcune implementazioni questa
+sez.~\ref{sec:file_open}) che prevede\footnote{questo è quanto dettato dallo
+  standard POSIX.1, ciò non toglie che in alcune implementazioni questa
   tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si
-  è comunque soggetti alla possibilità di una \textit{race
-    condition}\itindex{race~condition}.} che essa ritorni un errore quando
-usata con i flag di \const{O\_CREAT} e \const{O\_EXCL}. In tal modo la
-creazione di un \textsl{file di lock} può essere eseguita atomicamente, il
-processo che crea il file con successo si può considerare come titolare del
-lock (e della risorsa ad esso associata) mentre il rilascio si può eseguire
-con una chiamata ad \func{unlink}.
-
-Un esempio dell'uso di questa funzione è mostrato dalle funzioni
+  è comunque soggetti alla possibilità di una \itindex{race~condition}
+  \textit{race condition}.} che essa ritorni un errore quando usata con i
+flag di \const{O\_CREAT} e \const{O\_EXCL}. In tal modo la creazione di un
+\textsl{file di lock} può essere eseguita atomicamente, il processo che crea
+il file con successo si può considerare come titolare del lock (e della
+risorsa ad esso associata) mentre il rilascio si può eseguire con una chiamata
+ad \func{unlink}.
+
+Un esempio dell'uso di questa funzione è mostrato dalle funzioni
 \func{LockFile} ed \func{UnlockFile} riportate in fig.~\ref{fig:ipc_file_lock}
-(sono contenute in \file{LockFile.c}, un'altro dei sorgenti allegati alla
+(sono contenute in \file{LockFile.c}, un altro dei sorgenti allegati alla
 guida) che permettono rispettivamente di creare e rimuovere un \textsl{file di
-  lock}. Come si può notare entrambe le funzioni sono elementari; la prima
+  lock}. Come si può notare entrambe le funzioni sono elementari; la prima
 (\texttt{\small 4--10}) si limita ad aprire il file di lock (\texttt{\small
-  9}) nella modalità descritta, mentre la seconda (\texttt{\small 11--17}) lo
+  9}) nella modalità descritta, mentre la seconda (\texttt{\small 11--17}) lo
 cancella con \func{unlink}.
 
 \begin{figure}[!htb]
@@ -3064,57 +3076,58 @@ cancella con \func{unlink}.
   \label{fig:ipc_file_lock}
 \end{figure}
 
-Uno dei limiti di questa tecnica è che, come abbiamo già accennato in
-sez.~\ref{sec:file_open}, questo comportamento di \func{open} può non
-funzionare (la funzione viene eseguita, ma non è garantita l'atomicità
-dell'operazione) se il filesystem su cui si va ad operare è su NFS; in tal
-caso si può adottare una tecnica alternativa che prevede l'uso della
+Uno dei limiti di questa tecnica è che, come abbiamo già accennato in
+sez.~\ref{sec:file_open}, questo comportamento di \func{open} può non
+funzionare (la funzione viene eseguita, ma non è garantita l'atomicità
+dell'operazione) se il filesystem su cui si va ad operare è su NFS; in tal
+caso si può adottare una tecnica alternativa che prevede l'uso della
 \func{link} per creare come \textsl{file di lock} un hard link ad un file
-esistente; se il link esiste già e la funzione fallisce, significa che la
-risorsa è bloccata e potrà essere sbloccata solo con un \func{unlink},
-altrimenti il link è creato ed il lock acquisito; il controllo e l'eventuale
-acquisizione sono atomici; la soluzione funziona anche su NFS, ma ha un'altro
-difetto è che è quello di poterla usare solo se si opera all'interno di uno
+esistente; se il link esiste già e la funzione fallisce, significa che la
+risorsa è bloccata e potrà essere sbloccata solo con un \func{unlink},
+altrimenti il link è creato ed il lock acquisito; il controllo e l'eventuale
+acquisizione sono atomici; la soluzione funziona anche su NFS, ma ha un altro
+difetto è che è quello di poterla usare solo se si opera all'interno di uno
 stesso filesystem.
 
-Un generale comunque l'uso di un \textsl{file di lock} presenta parecchi
-problemi, che non lo rendono una alternativa praticabile per la
+In generale comunque l'uso di un \textsl{file di lock} presenta parecchi
+problemi che non lo rendono una alternativa praticabile per la
 sincronizzazione: anzitutto in caso di terminazione imprevista del processo,
 si lascia allocata la risorsa (il \textsl{file di lock}) e questa deve essere
-sempre cancellata esplicitamente.  Inoltre il controllo della disponibilità
-può essere eseguito solo con una tecnica di \textit{polling}\itindex{polling},
-ed è quindi molto inefficiente.
+sempre cancellata esplicitamente.  Inoltre il controllo della disponibilità
+può essere eseguito solo con una tecnica di \itindex{polling}
+\textit{polling}, ed è quindi molto inefficiente.
 
-La tecnica dei file di lock ha comunque una sua utilità, e può essere usata
-con successo quando l'esigenza è solo quella di segnalare l'occupazione di una
-risorsa, senza necessità di attendere che questa si liberi; ad esempio la si
+La tecnica dei file di lock ha comunque una sua utilità, e può essere usata
+con successo quando l'esigenza è solo quella di segnalare l'occupazione di una
+risorsa, senza necessità di attendere che questa si liberi; ad esempio la si
 usa spesso per evitare interferenze sull'uso delle porte seriali da parte di
-più programmi: qualora si trovi un file di lock il programma che cerca di
-accedere alla seriale si limita a segnalare che la risorsa non è
-disponibile.\index{file!di lock|)}
+più programmi: qualora si trovi un file di lock il programma che cerca di
+accedere alla seriale si limita a segnalare che la risorsa non è disponibile.
+
+\index{file!di lock|)}
 
 
 \subsection{La sincronizzazione con il \textit{file locking}}
 \label{sec:ipc_lock_file}
 
-Dato che i file di lock\index{file!di lock} presentano gli inconvenienti
-illustrati in precedenza, la tecnica alternativa di sincronizzazione più
-comune è quella di fare ricorso al \textit{file locking}\index{file!locking}
+Dato che i \index{file!di lock} file di lock presentano gli inconvenienti
+illustrati in precedenza, la tecnica alternativa di sincronizzazione più
+comune è quella di fare ricorso al \index{file!locking} \textit{file locking}
 (trattato in sez.~\ref{sec:file_locking}) usando \func{fcntl} su un file
 creato per l'occasione per ottenere un write lock. In questo modo potremo
-usare il lock come un \textit{mutex}: per bloccare la risorsa basterà
-acquisire il lock, per sbloccarla basterà rilasciare il lock. Una richiesta
-fatta con un write lock metterà automaticamente il processo in stato di
-attesa, senza necessità di ricorrere al \textit{polling}\itindex{polling} per
-determinare la disponibilità della risorsa, e al rilascio della stessa da
-parte del processo che la occupava si otterrà il nuovo lock atomicamente.
+usare il lock come un \textit{mutex}: per bloccare la risorsa basterà
+acquisire il lock, per sbloccarla basterà rilasciare il lock. Una richiesta
+fatta con un write lock metterà automaticamente il processo in stato di
+attesa, senza necessità di ricorrere al \itindex{polling} \textit{polling} per
+determinare la disponibilità della risorsa, e al rilascio della stessa da
+parte del processo che la occupava si otterrà il nuovo lock atomicamente.
 
 Questo approccio presenta il notevole vantaggio che alla terminazione di un
 processo tutti i lock acquisiti vengono rilasciati automaticamente (alla
 chiusura dei relativi file) e non ci si deve preoccupare di niente; inoltre
-non consuma risorse permanentemente allocate nel sistema. Lo svantaggio è che,
-dovendo fare ricorso a delle operazioni sul filesystem, esso è in genere
-leggermente più lento.
+non consuma risorse permanentemente allocate nel sistema. Lo svantaggio è che,
+dovendo fare ricorso a delle operazioni sul filesystem, esso è in genere
+leggermente più lento.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -3123,78 +3136,80 @@ leggermente pi
   \end{minipage} 
   \normalsize 
   \caption{Il codice delle funzioni che permettono per la gestione dei 
-    \textit{mutex} con il file locking\index{file!locking}.}
+    \textit{mutex} con il \index{file!locking} \textit{file locking}.}
   \label{fig:ipc_flock_mutex}
 \end{figure}
 
 Il codice delle varie funzioni usate per implementare un mutex utilizzando il
-file locking\index{file!locking} è riportato in fig.~\ref{fig:ipc_flock_mutex};
-si è mantenuta volutamente una struttura analoga alle precedenti funzioni che
-usano i semafori, anche se le due interfacce non possono essere completamente
-equivalenti, specie per quanto riguarda la rimozione del mutex.
-
-La prima funzione (\texttt{\small 1--5}) è \func{CreateMutex}, e serve a
-creare il mutex; la funzione è estremamente semplice, e si limita
+\textit{file locking} \index{file!locking} è riportato in
+fig.~\ref{fig:ipc_flock_mutex}; si è mantenuta volutamente una struttura
+analoga alle precedenti funzioni che usano i semafori, anche se le due
+interfacce non possono essere completamente equivalenti, specie per quanto
+riguarda la rimozione del mutex.
+
+La prima funzione (\texttt{\small 1--5}) è \func{CreateMutex}, e serve a
+creare il mutex; la funzione è estremamente semplice, e si limita
 (\texttt{\small 4}) a creare, con una opportuna chiamata ad \func{open}, il
-file che sarà usato per il successivo file locking, assicurandosi che non
-esista già (nel qual caso segnala un errore); poi restituisce il file
-descriptor che sarà usato dalle altre funzioni per acquisire e rilasciare il
+file che sarà usato per il successivo \textit{file locking}, assicurandosi che
+non esista già (nel qual caso segnala un errore); poi restituisce il file
+descriptor che sarà usato dalle altre funzioni per acquisire e rilasciare il
 mutex.
 
-La seconda funzione (\texttt{\small 6--10}) è \func{FindMutex}, che, come la
-precedente, è stata definita per mantenere una analogia con la corrispondente
+La seconda funzione (\texttt{\small 6--10}) è \func{FindMutex}, che, come la
+precedente, è stata definita per mantenere una analogia con la corrispondente
 funzione basata sui semafori. Anch'essa si limita (\texttt{\small 9}) ad
-aprire il file da usare per il file locking, solo che in questo caso le
-opzioni di \func{open} sono tali che il file in questione deve esistere di
-già.
+aprire il file da usare per il \index{file!locking} \textit{file locking},
+solo che in questo caso le opzioni di \func{open} sono tali che il file in
+questione deve esistere di già.
 
-La terza funzione (\texttt{\small 11--22}) è \func{LockMutex} e serve per
+La terza funzione (\texttt{\small 11--22}) è \func{LockMutex} e serve per
 acquisire il mutex. La funzione definisce (\texttt{\small 14}) e inizializza
 (\texttt{\small 16--19}) la struttura \var{lock} da usare per acquisire un
 write lock sul file, che poi (\texttt{\small 21}) viene richiesto con
-\func{fcntl}, restituendo il valore di ritorno di quest'ultima. Se il file è
+\func{fcntl}, restituendo il valore di ritorno di quest'ultima. Se il file è
 libero il lock viene acquisito e la funzione ritorna immediatamente;
-altrimenti \func{fcntl} si bloccherà (si noti che la si è chiamata con
-\func{F\_SETLKW}) fino al rilascio del lock.
+altrimenti \func{fcntl} si bloccherà (si noti che la si è chiamata con
+\const{F\_SETLKW}) fino al rilascio del lock.
 
-La quarta funzione (\texttt{\small 24--34}) è \func{UnlockMutex} e serve a
-rilasciare il mutex. La funzione è analoga alla precedente, solo che in questo
+La quarta funzione (\texttt{\small 24--34}) è \func{UnlockMutex} e serve a
+rilasciare il mutex. La funzione è analoga alla precedente, solo che in questo
 caso si inizializza (\texttt{\small 28--31}) la struttura \var{lock} per il
 rilascio del lock, che viene effettuato (\texttt{\small 33}) con la opportuna
-chiamata a \func{fcntl}. Avendo usato il file locking in semantica POSIX (si
-riveda quanto detto sez.~\ref{sec:file_posix_lock}) solo il processo che ha
-precedentemente eseguito il lock può sbloccare il mutex.
+chiamata a \func{fcntl}. Avendo usato il \index{file!locking} \textit{file
+  locking} in semantica POSIX (si riveda quanto detto
+sez.~\ref{sec:file_posix_lock}) solo il processo che ha precedentemente
+eseguito il lock può sbloccare il mutex.
 
-La quinta funzione (\texttt{\small 36--39}) è \func{RemoveMutex} e serve a
-cancellare il mutex. Anche questa funzione è stata definita per mantenere una
+La quinta funzione (\texttt{\small 36--39}) è \func{RemoveMutex} e serve a
+cancellare il mutex. Anche questa funzione è stata definita per mantenere una
 analogia con le funzioni basate sui semafori, e si limita a cancellare
 (\texttt{\small 38}) il file con una chiamata ad \func{unlink}. Si noti che in
-questo caso la funzione non ha effetto sui mutex già ottenuti con precedenti
+questo caso la funzione non ha effetto sui mutex già ottenuti con precedenti
 chiamate a \func{FindMutex} o \func{CreateMutex}, che continueranno ad essere
 disponibili fintanto che i relativi file descriptor restano aperti. Pertanto
-per rilasciare un mutex occorrerà prima chiamare \func{UnlockMutex} oppure
+per rilasciare un mutex occorrerà prima chiamare \func{UnlockMutex} oppure
 chiudere il file usato per il lock.
 
-La sesta funzione (\texttt{\small 41--55}) è \func{ReadMutex} e serve a
+La sesta funzione (\texttt{\small 41--55}) è \func{ReadMutex} e serve a
 leggere lo stato del mutex. In questo caso si prepara (\texttt{\small 46--49})
 la solita struttura \var{lock} come l'acquisizione del lock, ma si effettua
 (\texttt{\small 51}) la chiamata a \func{fcntl} usando il comando
 \const{F\_GETLK} per ottenere lo stato del lock, e si restituisce
 (\texttt{\small 52}) il valore di ritorno in caso di errore, ed il valore del
 campo \var{l\_type} (che descrive lo stato del lock) altrimenti
-(\texttt{\small 54}). Per questo motivo la funzione restituirà -1 in caso di
+(\texttt{\small 54}). Per questo motivo la funzione restituirà -1 in caso di
 errore e uno dei due valori \const{F\_UNLCK} o \const{F\_WRLCK}\footnote{non
   si dovrebbe mai avere il terzo valore possibile, \const{F\_RDLCK}, dato che
-  la nostra interfaccia usa solo i write lock. Però è sempre possibile che
+  la nostra interfaccia usa solo i write lock. Però è sempre possibile che
   siano richiesti altri lock sul file al di fuori dell'interfaccia, nel qual
   caso si potranno avere, ovviamente, interferenze indesiderate.} in caso di
-successo, ad indicare che il mutex è, rispettivamente, libero o occupato.
+successo, ad indicare che il mutex è, rispettivamente, libero o occupato.
 
 Basandosi sulla semantica dei file lock POSIX valgono tutte le considerazioni
 relative al comportamento di questi ultimi fatte in
 sez.~\ref{sec:file_posix_lock}; questo significa ad esempio che, al contrario
 di quanto avveniva con l'interfaccia basata sui semafori, chiamate multiple a
-\func{UnlockMutex} o \func{LockMutex} non si cumulano e non danno perciò
+\func{UnlockMutex} o \func{LockMutex} non si cumulano e non danno perciò
 nessun inconveniente.
 
 
@@ -3202,9 +3217,9 @@ nessun inconveniente.
 \label{sec:ipc_mmap_anonymous}
 
 \itindbeg{memory~mapping}
-Abbiamo già visto che quando i processi sono \textsl{correlati}\footnote{se
-  cioè hanno almeno un progenitore comune.} l'uso delle pipe può costituire
-una valida alternativa alle code di messaggi; nella stessa situazione si può
+Abbiamo già visto che quando i processi sono \textsl{correlati}\footnote{se
+  cioè hanno almeno un progenitore comune.} l'uso delle pipe può costituire
+una valida alternativa alle code di messaggi; nella stessa situazione si può
 evitare l'uso di una memoria condivisa facendo ricorso al cosiddetto
 \textit{memory mapping} anonimo.
 
@@ -3212,26 +3227,27 @@ In sez.~\ref{sec:file_memory_map} abbiamo visto come sia possibile mappare il
 contenuto di un file nella memoria di un processo, e che, quando viene usato
 il flag \const{MAP\_SHARED}, le modifiche effettuate al contenuto del file
 vengono viste da tutti i processi che lo hanno mappato. Utilizzare questa
-tecnica per creare una memoria condivisa fra processi diversi è estremamente
-inefficiente, in quanto occorre passare attraverso il disco. Però abbiamo
+tecnica per creare una memoria condivisa fra processi diversi è estremamente
+inefficiente, in quanto occorre passare attraverso il disco. Però abbiamo
 visto anche che se si esegue la mappatura con il flag \const{MAP\_ANONYMOUS}
 la regione mappata non viene associata a nessun file, anche se quanto scritto
-rimane in memoria e può essere riletto; allora, dato che un processo figlio
-mantiene nel suo spazio degli indirizzi anche le regioni mappate, esso sarà
-anche in grado di accedere a quanto in esse è contenuto.
+rimane in memoria e può essere riletto; allora, dato che un processo figlio
+mantiene nel suo spazio degli indirizzi anche le regioni mappate, esso sarà
+anche in grado di accedere a quanto in esse è contenuto.
 
 In questo modo diventa possibile creare una memoria condivisa fra processi
-diversi, purché questi abbiano almeno un progenitore comune che ha effettuato
+diversi, purché questi abbiano almeno un progenitore comune che ha effettuato
 il \textit{memory mapping} anonimo.\footnote{nei sistemi derivati da SysV una
-  funzionalità simile a questa viene implementata mappando il file speciale
+  funzionalità simile a questa viene implementata mappando il file speciale
   \file{/dev/zero}. In tal caso i valori scritti nella regione mappata non
   vengono ignorati (come accade qualora si scriva direttamente sul file), ma
-  restano in memoria e possono essere riletti secondo le stesse modalità usate
+  restano in memoria e possono essere riletti secondo le stesse modalità usate
   nel \textit{memory mapping} anonimo.} Vedremo come utilizzare questa tecnica
-più avanti, quando realizzeremo una nuova versione del monitor visto in
+più avanti, quando realizzeremo una nuova versione del monitor visto in
 sez.~\ref{sec:ipc_sysv_shm} che possa restituisca i risultati via rete.
 \itindend{memory~mapping}
 
+% TODO fare esempio di mmap anonima
 
 \section{Il sistema di comunicazione fra processi di POSIX}
 \label{sec:ipc_posix}
@@ -3246,110 +3262,107 @@ una interfaccia completamente nuova, che tratteremo in questa sezione.
 \subsection{Considerazioni generali}
 \label{sec:ipc_posix_generic}
 
-In Linux non tutti gli oggetti del POSIX IPC sono pienamente supportati nel
-kernel ufficiale; solo la memoria condivisa è presente con l'interfaccia
-completa, ma solo a partire dal kernel 2.4.x, i semafori sono forniti dalle
-\acr{glibc} nella sezione che implementa i thread POSIX, le code di messaggi
-non hanno alcun tipo di supporto ufficiale.  Per queste ultime esistono
-tuttavia dei patch e una libreria aggiuntiva.
+Oggi Linux supporta tutti gli oggetti definito nello standard POSIX per l'IPC,
+ma a lungo non è stato così; la memoria condivisa è presente a partire dal
+kernel 2.4.x, i semafori sono forniti dalle \acr{glibc} nella sezione che
+implementa i \itindex{thread} \textit{thread} POSIX di nuova generazione che
+richiedono il kernel 2.6, le code di messaggi sono supportate a partire dal
+kernel 2.6.6.
 
-La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
+La caratteristica fondamentale dell'interfaccia POSIX è l'abbandono dell'uso
 degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
-\textit{Posix IPC names}\itindex{Posix~IPC~names}, che sono sostanzialmente
+\itindex{POSIX~IPC~names} \textit{POSIX IPC names}, che sono sostanzialmente
 equivalenti ai nomi dei file. Tutte le funzioni che creano un oggetto di IPC
-Posix prendono come primo argomento una stringa che indica uno di questi nomi;
-lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
-possono avere o meno una corrispondenza sul filesystem; tutto quello che è
-richiesto è che:
-\begin{itemize}
+POSIX prendono come primo argomento una stringa che indica uno di questi nomi;
+lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
+possono avere o meno una corrispondenza sul filesystem; tutto quello che è
+richiesto è che:
+\begin{itemize*}
 \item i nomi devono essere conformi alle regole che caratterizzano i
-  \itindex{pathname}\textit{pathname}, in particolare non essere più lunghi di
+  \itindex{pathname} \textit{pathname}, in particolare non essere più lunghi di
   \const{PATH\_MAX} byte e terminati da un carattere nullo.
 \item se il nome inizia per una \texttt{/} chiamate differenti allo stesso
   nome fanno riferimento allo stesso oggetto, altrimenti l'interpretazione del
   nome dipende dall'implementazione.
 \item l'interpretazione di ulteriori \texttt{/} presenti nel nome dipende
   dall'implementazione.
-\end{itemize}
+\end{itemize*}
 
-Data la assoluta genericità delle specifiche, il comportamento delle funzioni
-è pertanto subordinato in maniera quasi completa alla relativa
+Data la assoluta genericità delle specifiche, il comportamento delle funzioni
+è subordinato in maniera quasi completa alla relativa
 implementazione.\footnote{tanto che Stevens in \cite{UNP2} cita questo caso
   come un esempio della maniera standard usata dallo standard POSIX per
   consentire implementazioni non standardizzabili.} Nel caso di Linux, sia per
-quanto riguarda la memoria condivisa, che per quanto riguarda le code di
-messaggi, tutto viene creato usando come radici delle opportune directory
-(rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per i dettagli si
-faccia riferimento a sez.~\ref{sec:ipc_posix_shm} e
-sez.~\ref{sec:ipc_posix_mq}) ed i nomi specificati nelle relative funzioni
-sono considerati come un \itindsub{pathname}{assoluto}\textit{pathname}
-assoluto (comprendente eventuali sottodirectory) rispetto a queste radici.
-
-Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti
+quanto riguarda la memoria condivisa ed i semafori, che per quanto riguarda le
+code di messaggi, tutto viene creato usando come radici delle opportune
+directory (rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per i
+dettagli si faccia riferimento a sez.~\ref{sec:ipc_posix_shm},
+sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}) ed i nomi
+specificati nelle relative funzioni sono considerati come un
+\itindsub{pathname}{assoluto} \textit{pathname} assoluto (comprendente
+eventuali sottodirectory) rispetto a queste radici.
+
+Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti
 nell'albero dei file, e possono essere maneggiati con le usuali funzioni e
-comandi di accesso ai file,\footnote{questo è ancora più vero nel caso di
-  Linux, che usa una implementazione che lo consente, non è detto che
-  altrettanto valga per altri kernel. In particolare sia la memoria condivisa
-  che per le code di messaggi, come si può facilmente evincere con uno
-  \cmd{strace}, le system call utilizzate sono le stesse, in quanto esse sono
-  realizzate con dei file in speciali filesystem.}  che funzionano come su dei
-file normali.
+comandi di accesso ai file,\footnote{questo è vero nel caso di Linux, che usa
+  una implementazione che lo consente, non è detto che altrettanto valga per
+  altri kernel; in particolare, come si può facilmente verificare con uno
+  \cmd{strace}, sia per la memoria condivisa che per le code di messaggi le
+  system call utilizzate da Linux sono le stesse di quelle dei file, essendo
+  detti oggetti realizzati come tali in appositi filesystem.}  che funzionano
+come su dei file normali.
 
 In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai
-permessi dei file, e il controllo di accesso segue esattamente la stessa
-semantica (quella illustrata in sez.~\ref{sec:file_access_control}), invece di
+permessi dei file, ed il controllo di accesso segue esattamente la stessa
+semantica (quella illustrata in sez.~\ref{sec:file_access_control}), e non
 quella particolare (si ricordi quanto visto in
-sez.~\ref{sec:ipc_sysv_access_control}) usata per gli oggetti del SysV IPC. Per
-quanto riguarda l'attribuzione dell'utente e del gruppo proprietari
-dell'oggetto alla creazione di quest'ultimo essa viene effettuata secondo la
-semantica SysV (essi corrispondono cioè a userid e groupid effettivi del
-processo che esegue la creazione).
-
+sez.~\ref{sec:ipc_sysv_access_control}) che viene usata per gli oggetti del
+SysV IPC.  Per quanto riguarda l'attribuzione dell'utente e del gruppo
+proprietari dell'oggetto alla creazione di quest'ultimo essa viene effettuata
+secondo la semantica SysV: corrispondono cioè a user-ID e group-ID effettivi
+del processo che esegue la creazione.
 
 
 \subsection{Code di messaggi}
 \label{sec:ipc_posix_mq}
 
-Le code di messaggi non sono ancora supportate nel kernel ufficiale, esiste
-però una implementazione sperimentale di Michal Wronski e Krzysztof
-Benedyczak,\footnote{i patch al kernel e la relativa libreria possono essere
-trovati su \href{http://www.mat.uni.torun.pl/~wrona/posix_ipc}
-{\textsf{http://www.mat.uni.torun.pl/\tild{}wrona/posix\_ipc}}, questi sono
-stati inseriti nel kernel ufficiale a partire dalla versione 2.6.6-rc1.}.  In
+Le code di messaggi POSIX sono supportate da Linux a partire dalla versione
+2.6.6-rc1 del kernel,\footnote{l'implementazione è dovuta a Michal Wronski e
+  Krzysztof Benedyczak, e le relative informazioni si possono trovare su
+  \href{http://www.geocities.com/wronski12/posix_ipc/index.html}
+  {\textsf{http://www.geocities.com/wronski12/posix\_ipc/index.html}}.} In
 generale, come le corrispettive del SysV IPC, le code di messaggi sono poco
-usate, dato che i socket\index{socket}, nei casi in cui sono sufficienti, sono
-più comodi, e che in casi più complessi la comunicazione può essere gestita
-direttamente con mutex e memoria condivisa con tutta la flessibilità che
-occorre.
-
-Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel cui
-siano stati opportunamente applicati i relativi patch, occorre utilizzare la
-libreria \file{mqueue}\footnote{i programmi che usano le code di messaggi cioè
-  devono essere compilati aggiungendo l'opzione \code{-lmqueue} al comando
-  \cmd{gcc}, dato che le funzioni non fanno parte della libreria standard, in
-  corrispondenza all'inclusione del supporto nel kernel ufficiale, anche le
-  relative funzioni sono state inserite nelle \acr{glibc} a partire dalla
-  versione 2.3.4.}  che contiene le funzioni dell'interfaccia
-POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle
-  speciali chiamate ad \func{ioctl} sui file del filesystem speciale su cui
+usate, dato che i socket, nei casi in cui sono sufficienti, sono più comodi, e
+che in casi più complessi la comunicazione può essere gestita direttamente con
+mutex (o semafori) e memoria condivisa con tutta la flessibilità che occorre.
+
+Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel
+superiore al 2.6.6 (o precedente, se sono stati opportunamente applicati i
+relativi patch) occorre utilizzare la libreria \file{libmqueue}\footnote{i
+  programmi che usano le code di messaggi cioè devono essere compilati
+  aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}; in
+  corrispondenza all'inclusione del supporto nel kernel ufficiale anche
+  \file{libmqueue} è stata inserita nelle \acr{glibc}, a partire dalla
+  versione 2.3.4 delle medesime.} che contiene le funzioni dell'interfaccia
+POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle
+  opportune chiamate ad \func{ioctl} sui file del filesystem speciale su cui
   vengono mantenuti questi oggetti di IPC.}
 
-
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
-\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
-aggiungendo ad \file{/etc/fstab} una riga come:
+\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
+aggiungendo ad \conffile{/etc/fstab} una riga come:
 \begin{verbatim}
 mqueue   /dev/mqueue       mqueue    defaults        0      0
 \end{verbatim}
-ed esso sarà utilizzato come radice sulla quale vengono risolti i nomi delle
-code di messaggi che iniziano con una \texttt{/}. Le opzioni di mount
+ed esso sarà utilizzato come radice sulla quale vengono risolti i nomi delle
+code di messaggi che iniziano con una ``\texttt{/}''. Le opzioni di mount
 accettate sono \texttt{uid}, \texttt{gid} e \texttt{mode} che permettono
 rispettivamente di impostare l'utente, il gruppo ed i permessi associati al
 filesystem.
 
 
 La funzione che permette di aprire (e crearla se non esiste ancora) una coda
-di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
+di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
 \begin{functions}
   \headdecl{mqueue.h} 
   
@@ -3361,42 +3374,47 @@ di messaggi POSIX 
   Apre una coda di messaggi POSIX impostandone le caratteristiche.
   
   \bodydesc{La funzione restituisce il descrittore associato alla coda in caso
-    di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
+    di successo e -1 per un errore; nel quel caso \var{errno} assumerà i
     valori:
     \begin{errlist}
-    \item[\errcode{EACCES}] Il processo non ha i privilegi per accedere al
+    \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
       alla memoria secondo quanto specificato da \param{oflag}.
-    \item[\errcode{EEXIST}] Si è specificato \const{O\_CREAT} e
-      \const{O\_EXCL} ma la coda già esiste.
-    \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-    \item[\errcode{EINVAL}] Il file non supporta la funzione, o si è
+    \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e
+      \const{O\_EXCL} ma la coda già esiste.
+    \item[\errcode{EINVAL}] il file non supporta la funzione, o si è
       specificato \const{O\_CREAT} con una valore non nullo di \param{attr} e
       valori non validi di \var{mq\_maxmsg} e \var{mq\_msgsize}.
-    \item[\errcode{ENOENT}] Non si è specificato \const{O\_CREAT} ma la coda
+    \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda
       non esiste.
     \end{errlist}
     ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
-    \errval{EMFILE} ed \errval{ENFILE}.}
+    \errval{EMFILE}, \errval{EINTR} ed \errval{ENFILE}.
+}
 \end{functions}
 
 La funzione apre la coda di messaggi identificata dall'argomento \param{name}
 restituendo il descrittore ad essa associato, del tutto analogo ad un file
 descriptor, con l'unica differenza che lo standard prevede un apposito tipo
-\type{mqd\_t}.\footnote{nella implementazione citata questo è definito come
-  \ctyp{int}.} Se la coda esiste già il descrittore farà riferimento allo
-stesso oggetto, consentendo così la comunicazione fra due processi diversi.
-
-La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
+\type{mqd\_t}.\footnote{nel caso di Linux si tratta in effetti proprio di un
+  normale file descriptor; pertanto, anche se questo comportamento non è
+  portabile, lo si può tenere sotto osservazione con le funzioni dell'I/O
+  multiplexing (vedi sez.~\ref{sec:file_multiplexing}) come possibile
+  alternativa all'uso dell'interfaccia di notifica di \func{mq\_notify} (che
+  vedremo a breve).} Se la coda esiste già il descrittore farà riferimento
+allo stesso oggetto, consentendo così la comunicazione fra due processi
+diversi.
+
+La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria; i valori possibili per i vari bit sono quelli visti in
-tab.~\ref{tab:file_open_flags} dei quali però \func{mq\_open} riconosce solo i
+tab.~\ref{tab:file_open_flags} dei quali però \func{mq\_open} riconosce solo i
 seguenti:
-\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre la coda solo per la ricezione di messaggi. Il
-  processo potrà usare il descrittore con \func{mq\_receive} ma non con
+  processo potrà usare il descrittore con \func{mq\_receive} ma non con
   \func{mq\_send}.
 \item[\const{O\_WRONLY}] Apre la coda solo per la trasmissione di messaggi. Il
-  processo potrà usare il descrittore con \func{mq\_send} ma non con
+  processo potrà usare il descrittore con \func{mq\_send} ma non con
   \func{mq\_receive}.
 \item[\const{O\_RDWR}] Apre la coda solo sia per la trasmissione che per la
   ricezione. 
@@ -3404,28 +3422,29 @@ seguenti:
   presenza di questo bit richiede la presenza degli ulteriori argomenti
   \param{mode} e \param{attr}.
 \item[\const{O\_EXCL}] Se usato insieme a \const{O\_CREAT} fa fallire la
-  chiamata se la coda esiste già, altrimenti esegue la creazione atomicamente.
-\item[\const{O\_NONBLOCK}] Imposta la coda in modalità non bloccante, le
+  chiamata se la coda esiste già, altrimenti esegue la creazione atomicamente.
+\item[\const{O\_NONBLOCK}] Imposta la coda in modalità non bloccante, le
   funzioni di ricezione e trasmissione non si bloccano quando non ci sono le
   risorse richieste, ma ritornano immediatamente con un errore di
   \errcode{EAGAIN}.
 \end{basedescript}
 
-I primi tre bit specificano la modalità di apertura della coda, e sono fra
-loro esclusivi. Ma qualunque sia la modalità in cui si è aperta una coda,
-questa potrà essere riaperta più volte in una modalità diversa, e vi si potrà
-sempre accedere attraverso descrittori diversi, esattamente come si può fare
+I primi tre bit specificano la modalità di apertura della coda, e sono fra
+loro esclusivi. Ma qualunque sia la modalità in cui si è aperta una coda,
+questa potrà essere riaperta più volte in una modalità diversa, e vi si potrà
+sempre accedere attraverso descrittori diversi, esattamente come si può fare
 per i file normali.
 
 Se la coda non esiste e la si vuole creare si deve specificare
 \const{O\_CREAT}, in tal caso occorre anche specificare i permessi di
-creazione con l'argomento \param{mode}; i valori di quest'ultimo sono identici
-a quelli usati per \func{open}, anche se per le code di messaggi han senso
-solo i permessi di lettura e scrittura. Oltre ai permessi di creazione possono
-essere specificati anche gli attributi specifici della coda tramite
-l'argomento \param{attr}; quest'ultimo è un puntatore ad una apposita
-struttura \struct{mq\_attr}, la cui definizione è riportata in
-fig.~\ref{fig:ipc_mq_attr}.
+creazione con l'argomento \param{mode};\footnote{fino al 2.6.14 per un bug i
+  valori della \textit{umask} del processo non venivano applicati a questi
+  permessi.} i valori di quest'ultimo sono identici a quelli usati per
+\func{open}, anche se per le code di messaggi han senso solo i permessi di
+lettura e scrittura. Oltre ai permessi di creazione possono essere specificati
+anche gli attributi specifici della coda tramite l'argomento \param{attr};
+quest'ultimo è un puntatore ad una apposita struttura \struct{mq\_attr}, la
+cui definizione è riportata in fig.~\ref{fig:ipc_mq_attr}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -3438,72 +3457,70 @@ fig.~\ref{fig:ipc_mq_attr}.
   \label{fig:ipc_mq_attr}
 \end{figure}
 
-Per ls creazione della coda i campi della struttura che devono essere
-specificati sono \var{mq\_msgsize} e \var{mq\_maxmsg}, che indicano
-rispettivamente la dimensione massima di un messaggio ed il numero massimo di
-messaggi che essa può contenere. Il valore dovrà essere positivo e minore dei
-rispettivi limiti di sistema \const{MQ\_MAXMSG} e \const{MQ\_MSGSIZE},
-altrimenti la funzione fallirà con un errore di \errcode{EINVAL}.  Qualora si
-specifichi per \param{attr} un puntatore nullo gli attributi della coda
-saranno impostati ai valori predefiniti.
-
-Quando l'accesso alla coda non è più necessario si può chiudere il relativo
-descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
+Per la creazione della coda i campi della struttura che devono essere
+specificati sono \var{mq\_maxmsg} e \var{mq\_msgsize}, che indicano
+rispettivamente il numero massimo di messaggi che può contenere e la
+dimensione massima di un messaggio. Il valore dovrà essere positivo e minore
+dei rispettivi limiti di sistema \const{MQ\_MAXMSG} e \const{MQ\_MSGSIZE},
+altrimenti la funzione fallirà con un errore di \errcode{EINVAL}.
+Se \param{attr} è un puntatore nullo gli attributi della coda saranno
+impostati ai valori predefiniti.
+
+Quando l'accesso alla coda non è più necessario si può chiudere il relativo
+descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
 {int mq\_close(mqd\_t mqdes)}
 
 Chiude la coda \param{mqdes}.
   
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà i valori \errval{EBADF} o
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore;
+  nel quel caso \var{errno} assumerà i valori \errval{EBADF} o
   \errval{EINTR}.}
 \end{prototype}
 
-La funzione è analoga a \func{close},\footnote{in Linux, dove le code sono
-  implementate come file su un filesystem dedicato, è esattamente la stessa
-  funzione.} dopo la sua esecuzione il processo non sarà più in grado di usare
-il descrittore della coda, ma quest'ultima continuerà ad esistere nel sistema
-e potrà essere acceduta con un'altra chiamata a \func{mq\_open}. All'uscita di
-un processo tutte le code aperte, così come i file, vengono chiuse
+La funzione è analoga a \func{close},\footnote{in Linux, dove le code sono
+  implementate come file su un filesystem dedicato, è esattamente la stessa
+  funzione.} dopo la sua esecuzione il processo non sarà più in grado di usare
+il descrittore della coda, ma quest'ultima continuerà ad esistere nel sistema
+e potrà essere acceduta con un'altra chiamata a \func{mq\_open}. All'uscita di
+un processo tutte le code aperte, così come i file, vengono chiuse
 automaticamente. Inoltre se il processo aveva agganciato una richiesta di
-notifica sul descrittore che viene chiuso, questa sarà rilasciata e potrà
+notifica sul descrittore che viene chiuso, questa sarà rilasciata e potrà
 essere richiesta da qualche altro processo.
 
 
 Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la
-funzione \funcd{mq\_unlink}, il cui prototipo è:
+funzione \funcd{mq\_unlink}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
 {int mq\_unlink(const char *name)}
 
 Rimuove una coda di messaggi.
   
 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
+  errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
   \func{unlink}.}
 \end{prototype}
 
-Anche in questo caso il comportamento della funzione è analogo a quello di
+Anche in questo caso il comportamento della funzione è analogo a quello di
 \func{unlink} per i file,\footnote{di nuovo l'implementazione di Linux usa
-  direttamente \func{unlink}.} la funzione rimove la coda \param{name}, così
+  direttamente \func{unlink}.} la funzione rimuove la coda \param{name}, così
 che una successiva chiamata a \func{mq\_open} fallisce o crea una coda
 diversa. 
 
 Come per i file ogni coda di messaggi ha un contatore di riferimenti, per cui
 la coda non viene effettivamente rimossa dal sistema fin quando questo non si
 annulla. Pertanto anche dopo aver eseguito con successo \func{mq\_unlink} la
-coda resterà accessibile a tutti i processi che hanno un descrittore aperto su
+coda resterà accessibile a tutti i processi che hanno un descrittore aperto su
 di essa.  Allo stesso modo una coda ed i suoi contenuti resteranno disponibili
-all'interno del sistema anche quando quest'ultima non è aperta da nessun
-processo (questa è una delle differenze più rilevanti nei confronti di pipe e
-fifo).
-
-La sola differenza fra code di messaggi POSIX e file normali è che, essendo il
-filesystem delle code di messaggi virtuale e basato su oggetti interni al
-kernel, il suo contenuto viene perduto con il riavvio del sistema.
-
-Come accennato in precedenza ad ogni coda di messaggi è associata una
-struttura \struct{mq\_attr}, che può essere letta e modificata attraverso le
-due funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
+all'interno del sistema anche quando quest'ultima non è aperta da nessun
+processo (questa è una delle differenze più rilevanti nei confronti di pipe e
+fifo).  La sola differenza fra code di messaggi POSIX e file normali è che,
+essendo il filesystem delle code di messaggi virtuale e basato su oggetti
+interni al kernel, il suo contenuto viene perduto con il riavvio del sistema.
+
+Come accennato ad ogni coda di messaggi è associata una struttura
+\struct{mq\_attr}, che può essere letta e modificata attraverso le due
+funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
 \begin{functions}
   \headdecl{mqueue.h} 
   
@@ -3515,24 +3532,24 @@ due funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
   Modifica gli attributi di una coda di messaggi POSIX.
   
   \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in
-    caso di errore; nel quel caso \var{errno} assumerà i valori \errval{EBADF}
+    caso di errore; nel quel caso \var{errno} assumerà i valori \errval{EBADF}
     o \errval{EINVAL}.}
 \end{functions}
 
 La funzione \func{mq\_getattr} legge i valori correnti degli attributi della
 coda nella struttura puntata da \param{mqstat}; di questi l'unico relativo
-allo stato corrente della coda è \var{mq\_curmsgs} che indica il numero di
+allo stato corrente della coda è \var{mq\_curmsgs} che indica il numero di
 messaggi da essa contenuti, gli altri indicano le caratteristiche generali
 della stessa.
 
 La funzione \func{mq\_setattr} permette di modificare gli attributi di una
 coda tramite i valori contenuti nella struttura puntata da \param{mqstat}, ma
-può essere modificato solo il campo \var{mq\_flags}, gli altri campi vengono
+può essere modificato solo il campo \var{mq\_flags}, gli altri campi vengono
 ignorati. In particolare i valori di \var{mq\_maxmsg} e \var{mq\_msgsize}
 possono essere specificati solo in fase ci creazione della coda.  Inoltre i
 soli valori possibili per \var{mq\_flags} sono 0 e \const{O\_NONBLOCK}, per
-cui alla fine la funzione può essere utilizzata solo per abilitare o
-disabilitare la modalità non bloccante. L'argomento \param{omqstat} viene
+cui alla fine la funzione può essere utilizzata solo per abilitare o
+disabilitare la modalità non bloccante. L'argomento \param{omqstat} viene
 usato, quando diverso da \val{NULL}, per specificare l'indirizzo di una
 struttura su cui salvare i valori degli attributi precedenti alla chiamata
 della funzione.
@@ -3552,22 +3569,20 @@ Per inserire messaggi su di una coda sono previste due funzioni,
   \param{abs\_timeout}.
 
   
-  \bodydesc{Le funzioni restituiscono 0 in caso di successo e -1 in caso di
-    errore; nel quel caso \var{errno} assumerà i valori:
+  \bodydesc{Le funzioni restituiscono 0 in caso di successo e $-1$ per un
+    errore; nel quel caso \var{errno} assumerà i valori:
     \begin{errlist}
-    \item[\errcode{EAGAIN}] Si è aperta la coda con \const{O\_NONBLOCK}, e la
-      coda è piena.
-    \item[\errcode{EMSGSIZE}] La lunghezza del messaggio \param{msg\_len}
+    \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
+      coda è piena.
+    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
       eccede il limite impostato per la coda.
-    \item[\errcode{ENOMEM}] Il kernel non ha memoria sufficiente. Questo
-      errore può avvenire quando l'inserimento del messaggio
-    \item[\errcode{EINVAL}] Si è specificato un valore nullo per
+    \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_len}, o un valore di \param{msg\_prio} fuori dai limiti, o
       un valore non valido per \param{abs\_timeout}.
-    \item[\errcode{ETIMEDOUT}] L'inserimento del messaggio non è stato
+    \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
       effettuato entro il tempo stabilito.
     \end{errlist}    
-    ed inoltre \errval{EBADF} ed \errval{EINTR}.}
+    ed inoltre \errval{EBADF}, \errval{ENOMEM} ed \errval{EINTR}.}
 \end{functions}
 
 Entrambe le funzioni richiedono un puntatore al testo del messaggio
@@ -3575,19 +3590,24 @@ nell'argomento \param{msg\_ptr} e la relativa lunghezza in \param{msg\_len}.
 Se quest'ultima eccede la dimensione massima specificata da \var{mq\_msgsize}
 le funzioni ritornano immediatamente con un errore di \errcode{EMSGSIZE}.
 
-L'argomento \param{msg\_prio} indica la priorità dell'argomento; i messaggi di
-priorità maggiore vengono inseriti davanti a quelli di priorità inferiore (e
-quindi saranno riletti per primi). A parità del valore della priorità il
-messaggio sarà inserito in coda a tutti quelli con la stessa priorità. Il
-valore della priorità non può eccedere il limite di sistema
-\const{MQ\_PRIO\_MAX}, che nel caso è pari a 32768.
+L'argomento \param{msg\_prio} indica la priorità dell'argomento; i messaggi di
+priorità maggiore vengono inseriti davanti a quelli di priorità inferiore (e
+quindi saranno riletti per primi). A parità del valore della priorità il
+messaggio sarà inserito in coda a tutti quelli con la stessa priorità. Il
+valore della priorità non può eccedere il limite di sistema
+\const{MQ\_PRIO\_MAX}, che nel caso è pari a 32768.
 
 Qualora la coda sia piena, entrambe le funzioni si bloccano, a meno che non
-sia stata selezionata in fase di apertura la modalità non bloccante, nel qual
-caso entrambe ritornano \errcode{EAGAIN}. La sola differenza fra le due
-funzioni è che la seconda, passato il tempo massimo impostato con l'argomento
-\param{abs\_timeout}, ritorna comunque con un errore di \errcode{ETIMEDOUT}.
-
+sia stata selezionata in fase di apertura la modalità non
+bloccante,\footnote{o si sia impostato il flag \const{O\_NONBLOCK} sul file
+  descriptor della coda.} nel qual caso entrambe ritornano \errcode{EAGAIN}.
+La sola differenza fra le due funzioni è che la seconda, passato il tempo
+massimo impostato con l'argomento \param{abs\_timeout},\footnote{deve essere
+  specificato un tempo assoluto tramite una struttura \struct{timespec} (vedi
+  fig.~\ref{fig:sys_timespec_struct}) indicato in numero di secondi e
+  nanosecondi a partire dal 1 gennaio 1970.} ritorna comunque con un errore di
+\errcode{ETIMEDOUT}, se invece il tempo è già scaduto al momento della
+chiamata e la coda è vuota la funzione ritorna immediatamente.
 
 Come per l'inserimento, anche per l'estrazione dei messaggi da una coda sono
 previste due funzioni, \funcd{mq\_receive} e \funcd{mq\_timedreceive}, i cui
@@ -3605,117 +3625,126 @@ prototipi sono:
   \param{abs\_timeout}.
   
   \bodydesc{Le funzioni restituiscono il numero di byte del messaggio in caso
-    di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
+    di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
     valori:
     \begin{errlist}
-    \item[\errcode{EAGAIN}] Si è aperta la coda con \const{O\_NONBLOCK}, e la
-      coda è vuota.
-    \item[\errcode{EMSGSIZE}] La lunghezza del messaggio sulla coda eccede il
+    \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
+      coda è vuota.
+    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio sulla coda eccede il
       valore \param{msg\_len} specificato per la ricezione.
-    \item[\errcode{EINVAL}] Si è specificato un valore nullo per
+    \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_ptr}, o un valore non valido per \param{abs\_timeout}.
-    \item[\errcode{ETIMEDOUT}] La ricezione del messaggio non è stata
+    \item[\errcode{ETIMEDOUT}] la ricezione del messaggio non è stata
       effettuata entro il tempo stabilito.
     \end{errlist}    
     ed inoltre \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o
     \errval{EINVAL}.}
 \end{functions}
 
-La funzione estrae dalla coda il messaggio a priorità più alta, o il più
-vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio
+La funzione estrae dalla coda il messaggio a priorità più alta, o il più
+vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio
 viene tolto dalla coda e la sua dimensione viene restituita come valore di
-ritorno.
+ritorno.\footnote{si tenga presente che 0 è una dimensione valida e che la
+  condizione di errore è restituita dal valore -1; Stevens in \cite{UNP2} fa
+  notare che questo è uno dei casi in cui vale ciò che lo standard
+  \textsl{non} dice, una dimensione nulla infatti, pur non essendo citata, non
+  viene proibita.}
 
-Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere
+Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere
 il messaggio, entrambe le funzioni, al contrario di quanto avveniva nelle code
 di messaggi di SysV, ritornano un errore di \errcode{EMSGSIZE} senza estrarre
-il messaggio.  È pertanto opportuno eseguire sempre una chiamata a
+il messaggio.  È pertanto opportuno eseguire sempre una chiamata a
 \func{mq\_getaddr} prima di eseguire una ricezione, in modo da ottenere la
 dimensione massima dei messaggi sulla coda, per poter essere in grado di
 allocare dei buffer sufficientemente ampi per la lettura.
 
 Se si specifica un puntatore per l'argomento \param{msg\_prio} il valore della
-priorità del messaggio viene memorizzato all'indirizzo da esso indicato.
-Qualora non interessi usare la priorità dei messaggi si può specificare
-\var{NULL}, ed usare un valore nullo della priorità nelle chiamate a
+priorità del messaggio viene memorizzato all'indirizzo da esso indicato.
+Qualora non interessi usare la priorità dei messaggi si può specificare
+\var{NULL}, ed usare un valore nullo della priorità nelle chiamate a
 \func{mq\_send}.
 
-Si noti che con le code di messaggi POSIX non si ha la possibilità di
-selezionare quale messaggio estrarre con delle condizioni sulla priorità, a
+Si noti che con le code di messaggi POSIX non si ha la possibilità di
+selezionare quale messaggio estrarre con delle condizioni sulla priorità, a
 differenza di quanto avveniva con le code di messaggi di SysV che permettono
-invece la selezione in base al valore del campo \var{mtype}. Qualora non
-interessi usare la priorità dei messaggi si
+invece la selezione in base al valore del campo \var{mtype}. 
+
+% TODO inserire i dati di /proc/sys/fs/mqueue 
 
 Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si
-sia selezionata la modalità non bloccante; in tal caso entrambe ritornano
+sia selezionata la modalità non bloccante; in tal caso entrambe ritornano
 immediatamente con l'errore \errcode{EAGAIN}. Anche in questo caso la sola
-differenza fra le due funzioni è che la seconda non attende indefinitamente e
+differenza fra le due funzioni è che la seconda non attende indefinitamente e
 passato il tempo massimo \param{abs\_timeout} ritorna comunque con un errore
 di \errcode{ETIMEDOUT}.
 
 Uno dei problemi sottolineati da Stevens in \cite{UNP2}, comuni ad entrambe le
-tipologie di code messaggi, è che non è possibile per chi riceve identificare
-chi è che ha inviato il messaggio, in particolare non è possibile sapere da
+tipologie di code messaggi, è che non è possibile per chi riceve identificare
+chi è che ha inviato il messaggio, in particolare non è possibile sapere da
 quale utente esso provenga. Infatti, in mancanza di un meccanismo interno al
 kernel, anche se si possono inserire delle informazioni nel messaggio, queste
 non possono essere credute, essendo completamente dipendenti da chi lo invia.
-Vedremo però come, attraverso l'uso del meccanismo di notifica, sia possibile
+Vedremo però come, attraverso l'uso del meccanismo di notifica, sia possibile
 superare in parte questo problema.
 
-Una caratteristica specifica delle code di messaggi POSIX è la possibilità di
-usufruire di un meccanismo di notifica asincrono; questo può essere attivato
-usando la funzione \funcd{mq\_notify}, il cui prototipo è:
+Una caratteristica specifica delle code di messaggi POSIX è la possibilità di
+usufruire di un meccanismo di notifica asincrono; questo può essere attivato
+usando la funzione \funcd{mq\_notify}, il cui prototipo è:
 \begin{prototype}{mqueue.h}
 {int mq\_notify(mqd\_t mqdes, const struct sigevent *notification)}
 
 Attiva il meccanismo di notifica per la coda \param{mqdes}.
   
 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà i valori: 
+  errore; nel quel caso \var{errno} assumerà i valori: 
     \begin{errlist}
-    \item[\errcode{EBUSY}] C'è già un processo registrato per la notifica.
-    \item[\errcode{EBADF}] Il descrittore non fa riferimento ad una coda di
+    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+    \item[\errcode{EBADF}] il descrittore non fa riferimento ad una coda di
       messaggi.
     \end{errlist}}
 \end{prototype}
 
 Il meccanismo di notifica permette di segnalare in maniera asincrona ad un
-processo la presenza di dati sulla coda, in modo da evitare la necessità di
+processo la presenza di dati sulla coda, in modo da evitare la necessità di
 bloccarsi nell'attesa. Per far questo un processo deve registrarsi con la
-funzione \func{mq\_notify}, ed il meccanismo è disponibile per un solo
+funzione \func{mq\_notify}, ed il meccanismo è disponibile per un solo
 processo alla volta per ciascuna coda.
 
 Il comportamento di \func{mq\_notify} dipende dal valore dell'argomento
-\param{notification}, che è un puntatore ad una apposita struttura
-\struct{sigevent}, (definita in fig.~\ref{fig:file_sigevent}) introdotta dallo
-standard POSIX.1b per gestire la notifica di eventi; per altri dettagli si può
-vedere quanto detto in sez.~\ref{sec:file_asyncronous_io} a proposito dell'uso
-della stessa struttura per l'invio dei segnali usati per l'I/O asincrono.
-
-Attraverso questa struttura si possono impostare le modalità con cui viene
-effettuata la notifica; in particolare il campo \var{sigev\_notify} deve
-essere posto a \const{SIGEV\_SIGNAL}\footnote{il meccanismo di notifica basato
-  sui thread, specificato tramite il valore \const{SIGEV\_THREAD}, non è
-  implementato.} ed il campo \var{sigev\_signo} deve indicare il valore del
-segnale che sarà inviato al processo. Inoltre il campo \var{sigev\_value} è il
-puntatore ad una struttura \struct{sigval\_t} (definita in
-fig.~\ref{fig:sig_sigval}) che permette di restituire al gestore del segnale un
-valore numerico o un indirizzo,\footnote{per il suo uso si riveda la
+\param{notification}, che è un puntatore ad una apposita struttura
+\struct{sigevent}, (definita in fig.~\ref{fig:struct_sigevent}) introdotta
+dallo standard POSIX.1b per gestire la notifica di eventi; per altri dettagli
+si può vedere quanto detto in sez.~\ref{sec:sig_timer_adv} a proposito
+dell'uso della stessa struttura per la notifica delle scadenze dei
+\textit{timer}.
+
+Attraverso questa struttura si possono impostare le modalità con cui viene
+effettuata la notifica nel campo \var{sigev\_notify}, che può assumere i
+valori di tab.~\ref{tab:sigevent_sigev_notify}.\footnote{la pagina di manuale
+  riporta soltanto i primi tre (inizialmente era possibile solo
+  \const{SIGEV\_SIGNAL}).} Il metodo consigliato è quello di usare
+\const{SIGEV\_SIGNAL} usando il campo \var{sigev\_signo} per indicare il quale
+segnale deve essere inviato al processo. Inoltre il campo \var{sigev\_value} è
+un puntatore ad una struttura \struct{sigval\_t} (definita in
+fig.~\ref{fig:sig_sigval}) che permette di restituire al gestore del segnale
+un valore numerico o un indirizzo,\footnote{per il suo uso si riveda la
   trattazione fatta in sez.~\ref{sec:sig_real_time} a proposito dei segnali
-  real-time.} posto che questo sia installato nella forma estesa vista in
-sez.~\ref{sec:sig_sigaction}.
+  \textit{real-time}.} posto che questo sia installato nella forma estesa
+vista in sez.~\ref{sec:sig_sigaction}.
 
 La funzione registra il processo chiamante per la notifica se
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
-inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
-che un solo processo alla volta può essere registrato, la funzione fallisce
-con \errcode{EBUSY} se c'è un altro processo già registrato.  Si tenga
-presente inoltre che alla chiusura del descrittore associato alla coda (e
-quindi anche all'uscita del processo) ogni eventuale registrazione di notifica
-presente viene cancellata.
+inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
+che un solo processo alla volta può essere registrato, la funzione fallisce
+con \errcode{EBUSY} se c'è un altro processo già registrato.\footnote{questo
+  significa anche che se si registra una notifica con \const{SIGEV\_NONE} il
+  processo non la riceverà, ma impedirà anche che altri possano registrarsi
+  per poterlo fare.}  Si tenga presente inoltre che alla chiusura del
+descrittore associato alla coda (e quindi anche all'uscita del processo) ogni
+eventuale registrazione di notifica presente viene cancellata.
 
 La notifica del segnale avviene all'arrivo di un messaggio in una coda vuota
-(cioè solo se sulla coda non ci sono messaggi) e se non c'è nessun processo
+(cioè solo se sulla coda non ci sono messaggi) e se non c'è nessun processo
 bloccato in una chiamata a \func{mq\_receive}, in questo caso infatti il
 processo bloccato ha la precedenza ed il messaggio gli viene immediatamente
 inviato, mentre per il meccanismo di notifica tutto funziona come se la coda
@@ -3727,13 +3756,13 @@ la coda diventa disponibile per una ulteriore registrazione.  Questo comporta
 che se si vuole mantenere il meccanismo di notifica occorre ripetere la
 registrazione chiamando nuovamente \func{mq\_notify} all'interno del gestore
 del segnale di notifica. A differenza della situazione simile che si aveva con
-i segnali non affidabili,\footnote{l'argomento è stato affrontato in
+i segnali non affidabili,\footnote{l'argomento è stato affrontato in
   \ref{sec:sig_semantics}.} questa caratteristica non configura una
-race-condition perché l'invio di un segnale avviene solo se la coda è vuota;
-pertanto se si vuole evitare di correre il rischio di perdere eventuali
-ulteriori segnali inviati nel lasso di tempo che occorre per ripetere la
-richiesta di notifica basta avere cura di eseguire questa operazione prima di
-estrarre i messaggi presenti dalla coda.
+\itindex{race~condition} \textit{race condition} perché l'invio di un segnale
+avviene solo se la coda è vuota; pertanto se si vuole evitare di correre il
+rischio di perdere eventuali ulteriori segnali inviati nel lasso di tempo che
+occorre per ripetere la richiesta di notifica basta avere cura di eseguire
+questa operazione prima di estrarre i messaggi presenti dalla coda.
 
 L'invio del segnale di notifica avvalora alcuni campi di informazione
 restituiti al gestore attraverso la struttura \struct{siginfo\_t} (definita in
@@ -3741,65 +3770,31 @@ fig.~\ref{fig:sig_siginfo_t}). In particolare \var{si\_pid} viene impostato al
 valore del \acr{pid} del processo che ha emesso il segnale, \var{si\_uid}
 all'userid effettivo, \var{si\_code} a \const{SI\_MESGQ}, e \var{si\_errno} a
 0. Questo ci dice che, se si effettua la ricezione dei messaggi usando
-esclusivamente il meccanismo di notifica, è possibile ottenere le informazioni
+esclusivamente il meccanismo di notifica, è possibile ottenere le informazioni
 sul processo che ha inserito un messaggio usando un gestore per il segnale in
-forma estesa\footnote{di nuovo si faccia riferimento a quanto detto al
+forma estesa.\footnote{di nuovo si faccia riferimento a quanto detto al
   proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.}
 
 
 
-\subsection{Semafori}
-\label{sec:ipc_posix_sem}
-
-Dei semafori POSIX esistono sostanzialmente due implementazioni; una è fatta a
-livello di libreria ed è fornita dalla libreria dei thread; questa però li
-implementa solo a livello di thread e non di processi.\footnote{questo
-  significa che i semafori sono visibili solo all'interno dei thread creati da
-  un singolo processo, e non possono essere usati come meccanismo di
-  sincronizzazione fra processi diversi.} Esiste però anche una libreria
-realizzata da Konstantin Knizhnik, che reimplementa l'interfaccia POSIX usando
-i semafori di SysV IPC, e che non vale comunque la pena di usare visto che i
-problemi sottolineati in sez.~\ref{sec:ipc_sysv_sem} rimangono, anche se
-mascherati.
-
-In realtà a partire dal kernel 2.5.7 è stato introdotto un meccanismo di
-sincronizzazione completamente nuovo, basato sui cosiddetti
-\textit{futex}\footnote{la sigla sta per \textit{fast user mode mutex}.}, con
-il quale dovrebbe essere possibile implementare una versione nativa dei
-semafori; esso è già stato usato con successo per reimplementare in maniera
-più efficiente tutte le direttive di sincronizzazione previste per i thread
-POSIX. L'interfaccia corrente è stata stabilizzata a partire dal kernel
-2.5.40.
-
-
-
-
 \subsection{Memoria condivisa}
 \label{sec:ipc_posix_shm}
 
-La memoria condivisa è l'unico degli oggetti di IPC POSIX già presente nel
-kernel ufficiale; in realtà il supporto a questo tipo di oggetti è realizzato
-attraverso il filesystem \texttt{tmpfs}, uno speciale filesystem che mantiene
-tutti i suoi contenuti in memoria,\footnote{il filesystem \texttt{tmpfs} è
-  diverso da un normale RAM disk, anch'esso disponibile attraverso il
-  filesystem \texttt{ramfs}, proprio perché realizza una interfaccia
-  utilizzabile anche per la memoria condivisa; esso infatti non ha dimensione
-  fissa, ed usa direttamente la cache interna del kernel (che viene usata
-  anche per la shared memory in stile SysV). In più i suoi contenuti, essendo
-  trattati direttamente dalla memoria virtuale\index{memoria~virtuale} possono
-  essere salvati sullo swap automaticamente.} che viene attivato abilitando
-l'opzione \texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
-
-
-Per potere utilizzare l'interfaccia POSIX per le code di messaggi le
+La memoria condivisa è stato il primo degli oggetti di IPC POSIX inserito nel
+kernel ufficiale; il supporto a questo tipo di oggetti è realizzato attraverso
+il filesystem \texttt{tmpfs}, uno speciale filesystem che mantiene tutti i
+suoi contenuti in memoria, che viene attivato abilitando l'opzione
+\texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
+
+Per potere utilizzare l'interfaccia POSIX per la memoria condivisa le
 \acr{glibc}\footnote{le funzioni sono state introdotte con le glibc-2.2.}
-richiedono di compilare i programmi con l'opzione \code{-lrt}; inoltre è
+richiedono di compilare i programmi con l'opzione \code{-lrt}; inoltre è
 necessario che in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs};
-questo di norma viene eseguita aggiungendo una riga tipo:
+questo di norma viene fatto aggiungendo una riga del tipo di:
 \begin{verbatim}
 tmpfs   /dev/shm        tmpfs   defaults        0      0
 \end{verbatim}
-ad \file{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
+ad \conffile{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
 dove si vuole, per usarlo come RAM disk, con un comando del tipo:
 \begin{verbatim}
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
@@ -3807,37 +3802,42 @@ mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
 
 Il filesystem riconosce, oltre quelle mostrate, le opzioni \texttt{uid} e
 \texttt{gid} che identificano rispettivamente utente e gruppo cui assegnarne
-la titolarità, e \texttt{nr\_blocks} che permette di specificarne la
-dimensione in blocchi, cioè in multipli di \const{PAGECACHE\_SIZE} che in
-questo caso è l'unità di allocazione elementare.
+la titolarità, e \texttt{nr\_blocks} che permette di specificarne la
+dimensione in blocchi, cioè in multipli di \const{PAGECACHE\_SIZE} che in
+questo caso è l'unità di allocazione elementare.
 
 La funzione che permette di aprire un segmento di memoria condivisa POSIX, ed
-eventualmente di crearlo se non esiste ancora, è \funcd{shm\_open}; il suo
-prototipo è:
-\begin{prototype}{mqueue.h}
-{int shm\_open(const char *name, int oflag, mode\_t mode)}
+eventualmente di crearlo se non esiste ancora, è \funcd{shm\_open}; il suo
+prototipo è:
+\begin{functions}
+  \headdecl{sys/mman.h} 
+  \headdecl{sys/stat.h} 
+  \headdecl{fcntl.h} 
+
+  \funcdecl{int shm\_open(const char *name, int oflag, mode\_t mode)} 
 
-Apre un segmento di memoria condivisa.
+  Apre un segmento di memoria condivisa.
   
-\bodydesc{La funzione restituisce un file descriptor positivo in caso di
-  successo e -1 in caso di errore; nel quel caso \var{errno} assumerà gli
-  stessi valori riportati da \func{open}.}
-\end{prototype}
+  \bodydesc{La funzione restituisce un file descriptor positivo in caso di
+    successo e -1 in caso di errore; nel quel caso \var{errno} assumerà gli
+    stessi valori riportati da \func{open}.}
+\end{functions}
 
 La funzione apre un segmento di memoria condivisa identificato dal nome
-\param{name}. Come già spiegato in sez.~\ref{sec:ipc_posix_generic} questo nome
-può essere specificato in forma standard solo facendolo iniziare per \file{/}
-e senza ulteriori \file{/}, Linux supporta comunque nomi generici, che
-verranno intepretati prendendo come radice \file{/dev/shm}.\footnote{occorre
-  pertanto evitare di specificare qualcosa del tipo \file{/dev/shm/nome}
-  all'interno di \param{name}, perché questo comporta, da parte delle routine
-  di libereria, il tentativo di accedere a \file{/dev/shm/dev/shm/nome}.}
-
-La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
+\param{name}. Come già spiegato in sez.~\ref{sec:ipc_posix_generic} questo
+nome può essere specificato in forma standard solo facendolo iniziare per
+``\file{/}'' e senza ulteriori ``\file{/}''. Linux supporta comunque nomi
+generici, che verranno interpretati prendendo come radice
+\file{/dev/shm}.\footnote{occorre pertanto evitare di specificare qualcosa del
+  tipo \file{/dev/shm/nome} all'interno di \param{name}, perché questo
+  comporta, da parte delle funzioni di libreria, il tentativo di accedere a
+  \file{/dev/shm/dev/shm/nome}.}
+
+La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria comprendente almeno uno dei due valori \const{O\_RDONLY} e
 \const{O\_RDWR}; i valori possibili per i vari bit sono quelli visti in
-tab.~\ref{tab:file_open_flags} dei quali però \func{shm\_open} riconosce solo
+tab.~\ref{tab:file_open_flags} dei quali però \func{shm\_open} riconosce solo
 i seguenti:
 \begin{basedescript}{\desclabelwidth{2.0cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre il file descriptor associato al segmento di
@@ -3847,55 +3847,54 @@ i seguenti:
 \item[\const{O\_CREAT}] Necessario qualora si debba creare il segmento di
   memoria condivisa se esso non esiste; in questo caso viene usato il valore
   di \param{mode} per impostare i permessi, che devono essere compatibili con
-  le modalità con cui si è aperto il file.
+  le modalità con cui si è aperto il file.
 \item[\const{O\_EXCL}] Se usato insieme a \const{O\_CREAT} fa fallire la
-  chiamata a \func{shm\_open} se il segmento esiste già, altrimenti esegue la
+  chiamata a \func{shm\_open} se il segmento esiste già, altrimenti esegue la
   creazione atomicamente.
-\item[\const{O\_TRUNC}] Se il segmento di memoria condivisa esiste già, ne
+\item[\const{O\_TRUNC}] Se il segmento di memoria condivisa esiste già, ne
   tronca le dimensioni a 0 byte.
 \end{basedescript}
 
 In caso di successo la funzione restituisce un file descriptor associato al
-segmento di memoria condiviso con le stesse modalità di
-\func{open}\footnote{in realtà, come accennato, \func{shm\_open} è un semplice
+segmento di memoria condiviso con le stesse modalità di
+\func{open}\footnote{in realtà, come accennato, \func{shm\_open} è un semplice
   wrapper per \func{open}, usare direttamente quest'ultima avrebbe lo stesso
   effetto.}  viste in sez.~\ref{sec:file_open}; in particolare viene impostato
 il flag \const{FD\_CLOEXEC}.  Chiamate effettuate da diversi processi usando
 lo stesso nome, restituiranno file descriptor associati allo stesso segmento
-(così come, nel caso di file di dati, essi sono associati allo stesso inode).
-In questo modo è possibile effettuare una chiamata ad \func{mmap} sul file
-descriptor restituito da \func{shm\_open} ed i processi vedranno lo stesso
-segmento di memoria condivisa.
-
-Quando il nome non esiste il segmento può essere creato specificando
-\const{O\_CREAT}; in tal caso il segmento avrà (così come i nuovi file)
-lunghezza nulla. Dato che un segmento di lunghezza nulla è di scarsa utilità,
+(così come, nel caso di file di dati, essi sono associati allo stesso
+\index{inode} inode).  In questo modo è possibile effettuare una chiamata ad
+\func{mmap} sul file descriptor restituito da \func{shm\_open} ed i processi
+vedranno lo stesso segmento di memoria condivisa.
+
+Quando il nome non esiste il segmento può essere creato specificando
+\const{O\_CREAT}; in tal caso il segmento avrà (così come i nuovi file)
+lunghezza nulla. Dato che un segmento di lunghezza nulla è di scarsa utilità,
 per impostarne la dimensione si deve usare \func{ftruncate} (vedi
 sez.~\ref{sec:file_file_size}), prima di mapparlo in memoria con \func{mmap}.
-Si tenga presente che una volta chiamata \func{mmap} si può chiudere il file
+Si tenga presente che una volta chiamata \func{mmap} si può chiudere il file
 descriptor (con \func{close}), senza che la mappatura ne risenta.
 
-
 Come per i file, quando si vuole effettivamente rimuovere segmento di memoria
-condivisa, occorre usare la funzione \funcd{shm\_unlink}, il cui prototipo è:
-\begin{prototype}{mqueue.h}
+condivisa, occorre usare la funzione \funcd{shm\_unlink}, il cui prototipo è:
+\begin{prototype}{sys/mman.h}
 {int shm\_unlink(const char *name)}
 
 Rimuove un segmento di memoria condivisa.
   
 \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
+  errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
   \func{unlink}.}
 \end{prototype}
 
-La funzione è del tutto analoga ad \func{unlink}, e si limita a cancellare il
-nome del segmento da \file{/dev/shm}, senza nessun effetto né sui file
-descriptor precedentemente aperti con \func{shm\_open}, né sui segmenti già
+La funzione è del tutto analoga ad \func{unlink}, e si limita a cancellare il
+nome del segmento da \file{/dev/shm}, senza nessun effetto né sui file
+descriptor precedentemente aperti con \func{shm\_open}, né sui segmenti già
 mappati in memoria; questi verranno cancellati automaticamente dal sistema
 solo con le rispettive chiamate a \func{close} e \func{munmap}.  Una volta
-eseguita questa funzione però, qualora si richieda l'apertura di un segmento
-con lo stesso nome, la chiamata a \func{shm\_open} fallirà, a meno di non aver
-usato \const{O\_CREAT}, in quest'ultimo caso comunque si otterrà un file
+eseguita questa funzione però, qualora si richieda l'apertura di un segmento
+con lo stesso nome, la chiamata a \func{shm\_open} fallirà, a meno di non aver
+usato \const{O\_CREAT}, in quest'ultimo caso comunque si otterrà un file
 descriptor che fa riferimento ad un segmento distinto da eventuali precedenti.
 
 \begin{figure}[!htb]
@@ -3909,13 +3908,13 @@ descriptor che fa riferimento ad un segmento distinto da eventuali precedenti.
   \label{fig:ipc_posix_shmmem}
 \end{figure}
 
-Come esempio per l'uso di queste funzioni vediamo come è possibile riscrivere
+Come esempio per l'uso di queste funzioni vediamo come è possibile riscrivere
 una interfaccia semplificata analoga a quella vista in
 fig.~\ref{fig:ipc_sysv_shm_func} per la memoria condivisa in stile SysV. Il
-codice, riportato in fig.~\ref{fig:ipc_posix_shmmem}, è sempre contenuto nel
+codice, riportato in fig.~\ref{fig:ipc_posix_shmmem}, è sempre contenuto nel
 file \file{SharedMem.c} dei sorgenti allegati.
 
-La prima funzione (\texttt{\small 1--24}) è \func{CreateShm} che, dato un nome
+La prima funzione (\texttt{\small 1--24}) è \func{CreateShm} che, dato un nome
 nell'argomento \var{name} crea un nuovo segmento di memoria condivisa,
 accessibile in lettura e scrittura, e ne restituisce l'indirizzo. Anzitutto si
 definiscono (\texttt{\small 8}) i flag per la successiva (\texttt{\small 9})
@@ -3927,30 +3926,705 @@ prosegue impostando (\texttt{\small 14}) la dimensione del segmento con
 \func{ftruncate}. Di nuovo (\texttt{\small 15--16}) si esce immediatamente
 restituendo un puntatore nullo in caso di errore. Poi si passa (\texttt{\small
   18}) a mappare in memoria il segmento con \func{mmap} specificando dei
-diritti di accesso corrispondenti alla modalità di apertura.  Di nuovo si
+diritti di accesso corrispondenti alla modalità di apertura.  Di nuovo si
 restituisce (\texttt{\small 19--21}) un puntatore nullo in caso di errore,
 altrimenti si inizializza (\texttt{\small 22}) il contenuto del segmento al
 valore specificato dall'argomento \var{fill} con \func{memset}, e se ne
 restituisce (\texttt{\small 23}) l'indirizzo.
 
-La seconda funzione (\texttt{\small 25--40}) è \func{FindShm} che trova un
-segmento di memoria condiviso già esistente, restituendone l'indirizzo. In
+La seconda funzione (\texttt{\small 25--40}) è \func{FindShm} che trova un
+segmento di memoria condiviso già esistente, restituendone l'indirizzo. In
 questo caso si apre (\texttt{\small 31}) il segmento con \func{shm\_open}
-richiedendo che il segmento sia già esistente, in caso di errore
+richiedendo che il segmento sia già esistente, in caso di errore
 (\texttt{\small 31--33}) si ritorna immediatamente un puntatore nullo.
 Ottenuto il file descriptor del segmento lo si mappa (\texttt{\small 35}) in
 memoria con \func{mmap}, restituendo (\texttt{\small 36--38}) un puntatore
 nullo in caso di errore, o l'indirizzo (\texttt{\small 39}) dello stesso in
 caso di successo.
 
-La terza funzione (\texttt{\small 40--45}) è \func{RemoveShm}, e serve a
+La terza funzione (\texttt{\small 40--45}) è \func{RemoveShm}, e serve a
 cancellare un segmento di memoria condivisa. Dato che al contrario di quanto
 avveniva con i segmenti del SysV IPC gli oggetti allocati nel kernel vengono
-rilasciati automaticamente quando nessuna li usa più, tutto quello che c'è da
-fare (\texttt{\small 44}) in questo caso è chiamare \func{shm\_unlink},
-retituendo al chiamante il valore di ritorno.
+rilasciati automaticamente quando nessuna li usa più, tutto quello che c'è da
+fare (\texttt{\small 44}) in questo caso è chiamare \func{shm\_unlink},
+restituendo al chiamante il valore di ritorno.
+
+
 
 
+\subsection{Semafori}
+\label{sec:ipc_posix_sem}
+
+Fino alla serie 2.4.x del kernel esisteva solo una implementazione parziale
+dei semafori POSIX che li realizzava solo a livello di \itindex{thread}
+\textit{thread} e non di processi,\footnote{questo significava che i semafori
+  erano visibili solo all'interno dei \itindex{thread} \textit{thread} creati
+  da un singolo processo, e non potevano essere usati come meccanismo di
+  sincronizzazione fra processi diversi.} fornita attraverso la sezione delle
+estensioni \textit{real-time} delle \acr{glibc}.\footnote{quelle che si
+  accedono collegandosi alla libreria \texttt{librt}.} Esisteva inoltre una
+libreria che realizzava (parzialmente) l'interfaccia POSIX usando le funzioni
+dei semafori di SysV IPC (mantenendo così tutti i problemi sottolineati in
+sez.~\ref{sec:ipc_sysv_sem}).
+
+A partire dal kernel 2.5.7 è stato introdotto un meccanismo di
+sincronizzazione completamente nuovo, basato sui cosiddetti
+\textit{futex},\footnote{la sigla sta per \textit{fast user mode mutex}.} con
+il quale è stato possibile implementare una versione nativa dei semafori
+POSIX.  Grazie a questo con i kernel della serie 2.6 e le nuove versioni delle
+\acr{glibc} che usano questa nuova infrastruttura per quella che viene quella
+che viene chiamata \textit{New Posix Thread Library}, sono state implementate
+anche tutte le funzioni dell'interfaccia dei semafori POSIX.
+
+Anche in questo caso è necessario appoggiarsi alla libreria per le estensioni
+\textit{real-time} \texttt{librt}, questo significa che se si vuole utilizzare
+questa interfaccia, oltre ad utilizzare gli opportuni file di definizione,
+occorrerà compilare i programmi con l'opzione \texttt{-lrt}. 
+
+La funzione che permette di creare un nuovo semaforo POSIX, creando il
+relativo file, o di accedere ad uno esistente, è \funcd{sem\_open}, questa
+prevede due forme diverse a seconda che sia utilizzata per aprire un semaforo
+esistente o per crearne uno nuovi, i relativi prototipi sono:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{sem\_t *sem\_open(const char *name, int oflag)}
+  
+  \funcdecl{sem\_t *sem\_open(const char *name, int oflag, mode\_t mode,
+    unsigned int value)} 
+
+  Crea un semaforo o ne apre uno esistente.
+  
+  \bodydesc{La funzione restituisce l'indirizzo del semaforo in caso di
+    successo e \const{SEM\_FAILED} in caso di errore; nel quel caso
+    \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EACCESS}] il semaforo esiste ma non si hanno permessi
+      sufficienti per accedervi.
+    \item[\errcode{EEXIST}] si sono specificati \const{O\_CREAT} e
+      \const{O\_EXCL} ma il semaforo esiste.
+    \item[\errcode{EINVAL}] il valore di \param{value} eccede
+      \const{SEM\_VALUE\_MAX}.
+    \item[\errcode{ENAMETOOLONG}] si è utilizzato un nome troppo lungo.
+    \item[\errcode{ENOENT}] non si è usato \const{O\_CREAT} ed il nome
+      specificato non esiste.
+    \end{errlist}    
+    ed inoltre \errval{ENFILE} ed \errval{ENOMEM}.}
+\end{functions}
+
+L'argomento \param{name} definisce il nome del semaforo che si vuole
+utilizzare, ed è quello che permette a processi diversi di accedere allo
+stesso semaforo. Questo deve essere specificato con un pathname nella forma
+\texttt{/qualchenome}, che non ha una corrispondenza diretta con un pathname
+reale; con Linux infatti i file associati ai semafori sono mantenuti nel
+filesystem virtuale \texttt{/dev/shm}, e gli viene assegnato automaticamente
+un nome nella forma \texttt{sem.qualchenome}.\footnote{si ha cioè una
+  corrispondenza per cui \texttt{/qualchenome} viene rimappato, nella
+  creazione tramite \func{sem\_open}, su \texttt{/dev/shm/sem.qualchenome}.}
+
+L'argomento \param{oflag} è quello che controlla le modalità con cui opera la
+funzione, ed è passato come maschera binaria; i bit corrispondono a quelli
+utilizzati per l'analogo argomento di \func{open}, anche se dei possibili
+valori visti in sez.~\ref{sec:file_open} sono utilizzati soltanto
+\const{O\_CREAT} e \const{O\_EXCL}.
+
+Se si usa \const{O\_CREAT} si richiede la creazione del semaforo qualora
+questo non esista, ed in tal caso occorre utilizzare la seconda forma della
+funzione, in cui si devono specificare sia un valore iniziale con l'argomento
+\param{value},\footnote{e si noti come così diventa possibile, differenza di
+  quanto avviene per i semafori del \textit{SysV IPC}, effettuare in maniera
+  atomica creazione ed inizializzazione di un semaforo usando una unica
+  funzione.} che una maschera dei permessi con l'argomento
+\param{mode};\footnote{anche questo argomento prende gli stessi valori
+  utilizzati per l'analogo di \func{open}, che si sono illustrati in dettaglio
+  sez.~\ref{sec:file_perm_overview}.} questi verranno assegnati al semaforo
+appena creato. Se il semaforo esiste già i suddetti valori saranno invece
+ignorati. Usando il flag \const{O\_EXCL} si richiede invece la verifica che il
+semaforo non esiste, usandolo insieme ad \const{O\_CREAT} la funzione fallisce
+qualora un semaforo con lo stesso nome sia già presente.
+
+La funzione restituisce in caso di successo un puntatore all'indirizzo del
+semaforo con un valore di tipo \ctyp{sem\_t *}, è questo valore che dovrà
+essere passato alle altre funzioni per operare sul semaforo stesso. Si tenga
+presente che, come accennato in sez.~\ref{sec:ipc_posix_generic}, i semafori
+usano la semantica standard dei file per quanto riguarda i controlli di
+accesso. 
+
+Questo significa che un nuovo semaforo viene sempre creato con l'user-ID ed il
+group-ID effettivo del processo chiamante, e che i permessi indicati con
+\param{mode} vengono filtrati dal valore della \itindex{umask} \textit{umask}
+del processo.  Inoltre per poter aprire un semaforo è necessario avere su di
+esso sia il permesso di lettura che quello di scrittura.
+
+Una volta che si sia ottenuto l'indirizzo di un semaforo, sarà possibile
+utilizzarlo; se si ricorda quanto detto all'inizio di
+sez.~\ref{sec:ipc_sysv_sem}, dove si sono introdotti i concetti generali
+relativi ai semafori, le operazioni principali sono due, quella che richiede
+l'uso di una risorsa bloccando il semaforo e quella che rilascia la risorsa
+liberando il semaforo. La prima operazione è effettuata dalla funzione
+\funcd{sem\_wait}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_wait(sem\_t *sem)}
+  
+  Blocca il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione cerca di decrementare il valore del semaforo indicato dal
+puntatore \param{sem}, se questo ha un valore positivo, cosa che significa che
+la risorsa è disponibile, la funzione ha successo, il valore del semaforo
+viene diminuito di 1 ed essa ritorna immediatamente; se il valore è nullo la
+funzione si blocca fintanto che il valore del semaforo non torni
+positivo\footnote{ovviamente per opera di altro processo che lo rilascia
+  chiamando \func{sem\_post}.} così che poi essa possa decrementarlo con
+successo e proseguire. 
+
+Si tenga presente che la funzione può sempre essere interrotta da un segnale
+(nel qual caso si avrà un errore di \const{EINTR}) e che questo avverrà
+comunque, anche se si è richiesta la semantica BSD installando il relativo
+gestore con \const{SA\_RESTART} (vedi sez.~\ref{sec:sig_sigaction}) per
+riavviare le system call interrotte.
+
+Della funzione \func{sem\_wait} esistono due varianti che consentono di
+gestire diversamente le modalità di attesa in caso di risorsa occupata, la
+prima di queste è \funcd{sem\_trywait}, che serve ad effettuare un tentativo
+di acquisizione senza bloccarsi; il suo prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_trywait(sem\_t *sem)}
+  
+  Tenta di bloccare il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà gli stessi valori:
+    \begin{errlist}
+    \item[\errcode{EAGAIN}] il semaforo non può essere acquisito senza
+      bloccarsi. 
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione è identica a \func{sem\_wait} ed se la risorsa è libera ha lo
+stesso effetto, vale a dire che in caso di semaforo diverso da zero la
+funzione lo decrementa e ritorna immediatamente; la differenza è che nel caso
+in cui il semaforo è occupato essa non si blocca e di nuovo ritorna
+immediatamente, restituendo però un errore di \errval{EAGAIN}, così che il
+programma possa proseguire.
+
+La seconda variante di \func{sem\_wait} è una estensione specifica che può
+essere utilizzata soltanto se viene definita la macro \macro{\_XOPEN\_SOURCE}
+ad un valore di 600 prima di includere \texttt{semaphore.h}, la funzione è
+\func{sem\_timedwait}, ed il suo prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+
+  \funcdecl{int sem\_timedwait(sem\_t *sem, const struct timespec
+    *abs\_timeout)}
+  
+  Blocca il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà gli stessi valori:
+    \begin{errlist}
+    \item[\errcode{ETIMEDOUT}] è scaduto il tempo massimo di attesa. 
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+    \end{errlist}    
+}
+\end{functions}
+
+Anche in questo caso il comportamento della funzione è identico a quello di
+\func{sem\_wait}, la sola differenza consiste nel fatto che con questa
+funzione è possibile impostare tramite l'argomento \param{abs\_timeout} un
+tempo limite per l'attesa, scaduto il quale la funzione ritorna comunque,
+anche se non è possibile acquisire il semaforo. In tal caso la funzione
+fallirà, riportando un errore di \errval{ETIMEDOUT}.
+
+La seconda funzione principale utilizzata per l'uso dei semafori è
+\funcd{sem\_post}, che viene usata per rilasciare un semaforo occupato o, in
+generale, per aumentare di una unità il valore dello stesso anche qualora non
+fosse occupato;\footnote{si ricordi che in generale un semaforo viene usato
+  come indicatore di un numero di risorse disponibili.} il suo prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_post(sem\_t *sem)}
+  
+  Rilascia il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione incrementa di uno il valore corrente del semaforo indicato
+dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà
+sbloccata, cosicché un altro processo (o \itindex{thread} \textit{thread})
+eventualmente bloccato in una \func{sem\_wait} sul semaforo potrà essere
+svegliato e rimesso in esecuzione.  Si tenga presente che la funzione è sicura
+\index{funzioni!sicure} per l'uso all'interno di un gestore di segnali (si
+ricordi quanto detto in sez.~\ref{sec:sig_signal_handler}).
+
+Se invece di operare su un semaforo se ne vuole solamente leggere il valore,
+si può usare la funzione \funcd{sem\_getvalue}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_getvalue(sem\_t *sem, int *sval)}
+  
+  Richiede il valore del semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione legge il valore del semaforo indicato dall'argomento \param{sem} e
+lo restituisce nella variabile intera puntata dall'argomento
+\param{sval}. Qualora ci siano uno o più processi bloccati in attesa sul
+semaforo lo standard prevede che la funzione possa restituire un valore nullo
+oppure il numero di processi bloccati in una \func{sem\_wait} sul suddetto
+semaforo; nel caso di Linux vale la prima opzione.
+
+Questa funzione può essere utilizzata per avere un suggerimento sullo stato di
+un semaforo, ovviamente non si può prendere il risultato riportato in
+\param{sval} che come indicazione, il valore del semaforo infatti potrebbe
+essere già stato modificato al ritorno della funzione.
+
+% TODO verificare comportamento sem_getvalue
+
+Una volta che non ci sia più la necessità di operare su un semaforo se ne può
+terminare l'uso con la funzione \funcd{sem\_close}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_close(sem\_t *sem)}
+  
+  Chiude il semaforo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il semaforo \param{sem} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione chiude il semaforo indicato dall'argomento \param{sem}; questo
+comporta che tutte le risorse che il sistema può avere assegnato al processo
+nell'uso dello stesso vengono rilasciate. Questo significa che un altro
+processo bloccato sul semaforo a causa della acquisizione da parte del
+processo che chiama \func{sem\_close} potrà essere riavviato.
+
+Si tenga presente poi che come per i file all'uscita di un processo tutti i
+semafori che questo aveva aperto vengono automaticamente chiusi; questo
+comportamento risolve il problema che si aveva con i semafori del \textit{SysV
+  IPC} (di cui si è parlato in sez.~\ref{sec:ipc_sysv_sem}) per i quali le
+risorse possono restare bloccate. Si tenga poi presente che, a differenza di
+quanto avviene per i file, in caso di una chiamata ad \func{execve} tutti i
+semafori vengono chiusi automaticamente.
+
+Come per i semafori del \textit{SysV IPC} anche quelli POSIX hanno una
+persistenza di sistema; questo significa che una volta che si è creato un
+semaforo con \func{sem\_open} questo continuerà ad esistere fintanto che il
+kernel resta attivo (vale a dire fino ad un successivo riavvio) a meno che non
+lo si cancelli esplicitamente. Per far questo si può utilizzare la funzione
+\funcd{sem\_unlink}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_unlink(const char *name)}
+  
+  Rimuove il semaforo \param{name}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EACCESS}] non si hanno i permessi necessari a cancellare il
+      semaforo.
+    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+    \item[\errcode{ENOENT}] il semaforo \param{name} non esiste.
+    \end{errlist}    
+}
+\end{functions}
+
+La funzione rimuove il semaforo indicato dall'argomento \param{name}, che
+prende un valore identico a quello usato per creare il semaforo stesso con
+\func{sem\_open}. Il semaforo viene rimosso dal filesystem immediatamente; ma
+il semaforo viene effettivamente cancellato dal sistema soltanto quando tutti
+i processi che lo avevano aperto lo chiudono. Si segue cioè la stessa
+semantica usata con \func{unlink} per i file, trattata in dettaglio in
+sez.~\ref{sec:file_link}.
+
+Una delle caratteristiche peculiari dei semafori POSIX è che questi possono
+anche essere utilizzati anche in forma anonima, senza necessità di fare
+ricorso ad un nome sul filesystem o ad altri indicativi.  In questo caso si
+dovrà porre la variabile che contiene l'indirizzo del semaforo in un tratto di
+memoria che sia accessibile a tutti i processi in gioco.  La funzione che
+consente di inizializzare un semaforo anonimo è \funcd{sem\_init}, il cui
+prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_init(sem\_t *sem, int pshared, unsigned int value)}
+
+  Inizializza il semaforo anonimo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il valore di \param{value} eccede
+      \const{SEM\_VALUE\_MAX}.
+    \item[\errcode{ENOSYS}] il valore di \param{pshared} non è nullo ed il
+      sistema non supporta i semafori per i processi.
+    \end{errlist}
+}
+\end{functions}
+
+La funzione inizializza un semaforo all'indirizzo puntato dall'argomento
+\param{sem}, e come per \func{sem\_open} consente di impostare un valore
+iniziale con \param{value}. L'argomento \param{pshared} serve ad indicare se
+il semaforo deve essere utilizzato dai \itindex{thread} \textit{thread} di uno
+stesso processo (con un valore nullo) o condiviso fra processi diversi (con un
+valore non nullo).
+
+Qualora il semaforo debba essere condiviso dai \itindex{thread}
+\textit{thread} di uno stesso processo (nel qual caso si parla di
+\textit{thread-shared semaphore}), occorrerà che \param{sem} sia l'indirizzo
+di una variabile visibile da tutti i \itindex{thread} \textit{thread}, si
+dovrà usare cioè una variabile globale o una variabile allocata dinamicamente
+nello \itindex{heap} \textit{heap}.
+
+Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si
+parla di \textit{process-shared semaphore}) la sola scelta possibile per
+renderlo visibile a tutti è di porlo in un tratto di memoria condivisa. Questo
+potrà essere ottenuto direttamente sia con \func{shmget} (vedi
+sez.~\ref{sec:ipc_sysv_shm}) che con \func{shm\_open} (vedi
+sez.~\ref{sec:ipc_posix_shm}), oppure, nel caso che tutti i processi in gioco
+abbiano un genitore comune, con una mappatura anonima con \func{mmap} (vedi
+sez.~\ref{sec:file_memory_map}),\footnote{si ricordi che i tratti di memoria
+  condivisa vengono mantenuti nei processi figli attraverso la funzione
+  \func{fork}.} a cui essi poi potranno accedere.
+
+Una volta inizializzato il semaforo anonimo con \func{sem\_init} lo si potrà
+utilizzare nello stesso modo dei semafori normali con \func{sem\_wait} e
+\func{sem\_post}. Si tenga presente però che inizializzare due volte lo stesso
+semaforo può dar luogo ad un comportamento indefinito. 
+
+Una volta che non si intenda più utilizzare un semaforo anonimo questo può
+essere eliminato dal sistema; per far questo di deve utilizzare una apposita
+funzione, \funcd{sem\_destroy}, il cui prototipo è:
+\begin{functions}
+  \headdecl{semaphore.h} 
+  
+  \funcdecl{int sem\_destroy(sem\_t *sem)}
+
+  Elimina il semaforo anonimo \param{sem}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore; nel quel caso \var{errno} assumerà i valori:
+    \begin{errlist}
+    \item[\errcode{EINVAL}] il valore di \param{value} eccede
+      \const{SEM\_VALUE\_MAX}.
+    \end{errlist}
+}
+\end{functions}
+
+La funzione prende come unico argomento l'indirizzo di un semaforo che deve
+essere stato inizializzato con \func{sem\_init}; non deve quindi essere
+applicata a semafori creati con \func{sem\_open}. Inoltre si deve essere
+sicuri che il semaforo sia effettivamente inutilizzato, la distruzione di un
+semaforo su cui sono presenti processi (o \itindex{thread} \textit{thread}) in
+attesa (cioè bloccati in una \func{sem\_wait}) provoca un comportamento
+indefinito.
+
+Si tenga presente infine che utilizzare un semaforo che è stato distrutto con
+\func{sem\_destroy} di nuovo può dare esito a comportamenti indefiniti.  Nel
+caso ci si trovi in una tale evenienza occorre reinizializzare il semaforo una
+seconda volta con \func{sem\_init}.
+
+Come esempio di uso sia della memoria condivisa che dei semafori POSIX si sono
+scritti due semplici programmi con i quali è possibile rispettivamente
+monitorare il contenuto di un segmento di memoria condivisa e modificarne il
+contenuto. 
+
+\begin{figure}[!h]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/message_getter.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Sezione principale del codice del programma
+    \file{message\_getter.c}.}
+  \label{fig:ipc_posix_sem_shm_message_server}
+\end{figure}
+
+Il corpo principale del primo dei due, il cui codice completo è nel file
+\file{message\_getter.c} dei sorgenti allegati, è riportato in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server}; si è tralasciata la parte che
+tratta la gestione delle opzioni a riga di comando (che consentono di
+impostare un nome diverso per il semaforo e il segmento di memoria condivisa)
+ed il controllo che al programma venga fornito almeno un argomento, contenente
+la stringa iniziale da inserire nel segmento di memoria condivisa.
+
+Lo scopo del programma è quello di creare un segmento di memoria condivisa su
+cui registrare una stringa, e tenerlo sotto osservazione stampando la stessa
+una volta al secondo. Si utilizzerà un semaforo per proteggere l'accesso in
+lettura alla stringa, in modo che questa non possa essere modificata
+dall'altro programma prima di averla finita di stampare.
+
+La parte iniziale del programma contiene le definizioni (\texttt{\small 1--8})
+del gestore del segnale usato per liberare le risorse utilizzate, delle
+variabili globali contenenti i nomi di default del segmento di memoria
+condivisa e del semaforo (il default scelto è \texttt{messages}), e delle
+altre variabili utilizzate dal programma.
+
+Come prima istruzione (\texttt{\small 10}) si è provveduto ad installare un
+gestore di segnale che consentirà di effettuare le operazioni di pulizia
+(usando la funzione \func{Signal} illustrata in
+fig.~\ref{fig:sig_Signal_code}), dopo di che (\texttt{\small 10--16}) si è
+creato il segmento di memoria condivisa con la funzione \func{CreateShm} che
+abbiamo appena trattato in sez.~\ref{sec:ipc_posix_shm}, uscendo con un
+messaggio in caso di errore. 
+
+Si tenga presente che la funzione \func{CreateShm} richiede che il segmento
+non sia già presente e fallirà qualora un'altra istanza, o un altro programma
+abbia già allocato un segmento con quello stesso nome. Per semplicità di
+gestione si è usata una dimensione fissa pari a 256 byte, definita tramite la
+costante \texttt{MSGMAXSIZE}.
+
+Il passo successivo (\texttt{\small 17--21}) è quello della creazione del
+semaforo che regola l'accesso al segmento di memoria condivisa con
+\func{sem\_open}; anche in questo caso si gestisce l'uscita con stampa di un
+messaggio in caso di errore. Anche per il semaforo, avendo specificato la
+combinazione di flag \code{O\_CREAT|O\_EXCL} come secondo argomento, si esce
+qualora fosse già esistente; altrimenti esso verrà creato con gli opportuni
+permessi specificati dal terzo argomento, (indicante lettura e scrittura in
+notazione ottale). Infine il semaforo verrà inizializzato ad un valore nullo
+(il quarto argomento), corrispondete allo stato in cui risulta bloccato.
+
+A questo punto (\texttt{\small 23}) si potrà inizializzare il messaggio posto
+nel segmento di memoria condivisa usando la stringa passata come argomento al
+programma. Essendo il semaforo stato creato già bloccato non ci si dovrà
+preoccupare di eventuali \itindex{race~condition} \textit{race condition}
+qualora il programma di modifica del messaggio venisse lanciato proprio in
+questo momento.  Una volta inizializzato il messaggio occorrerà però
+rilasciare il semaforo (\texttt{\small 25--28}) per consentirne l'uso; in
+tutte queste operazioni si provvederà ad uscire dal programma con un opportuno
+messaggio in caso di errore.
+
+Una volta completate le inizializzazioni il ciclo principale del programma
+(\texttt{\small 29--47}) viene ripetuto indefinitamente (\texttt{\small 29})
+per stampare sia il contenuto del messaggio che una serie di informazioni di
+controllo. Il primo passo (\texttt{\small 30--34}) è quello di acquisire (con
+\func{sem\_getvalue}, con uscita in caso di errore) e stampare il valore del
+semaforo ad inizio del ciclo; seguito (\texttt{\small 35--36}) dal tempo
+corrente.
+
+\begin{figure}[!h]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/HandSigInt.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Codice del gestore di segnale del programma
+    \file{message\_getter.c}.}
+  \label{fig:ipc_posix_sem_shm_message_server_handler}
+\end{figure}
+
+Prima della stampa del messaggio invece si deve acquisire il semaforo
+(\texttt{\small 31--34}) per evitare accessi concorrenti alla stringa da parte
+del programma di modifica. Una volta eseguita la stampa (\texttt{\small 41})
+il semaforo dovrà essere rilasciato (\texttt{\small 42--45}). Il passo finale
+(\texttt{\small 46}) è attendere per un secondo prima di eseguire da capo il
+ciclo. 
+
+Per uscire in maniera corretta dal programma sarà necessario interromperlo con
+il break da tastiera (\texttt{C-c}), che corrisponde all'invio del segnale
+\const{SIGINT}, per il quale si è installato (\texttt{\small 10}) una
+opportuna funzione di gestione, riportata in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server_handler}. La funzione è molto
+semplice e richiama le funzioni di rimozione sia per il segmento di memoria
+condivisa che per il semaforo, garantendo così che possa essere riaperto
+ex-novo senza errori in un futuro riutilizzo del comando.
+
+\begin{figure}[!h]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/message_setter.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Sezione principale del codice del programma
+    \file{message\_setter.c}.}
+  \label{fig:ipc_posix_sem_shm_message_setter}
+\end{figure}
+
+Il secondo programma di esempio è \file{message\_setter.c}, di cui si è
+riportato il corpo principale in
+fig.~\ref{fig:ipc_posix_sem_shm_message_setter},\footnote{al solito il codice
+  completo è nel file dei sorgenti allegati.} dove si è tralasciata, non
+essendo significativa per quanto si sta trattando, la parte relativa alla
+gestione delle opzioni a riga di comando e degli argomenti, che sono identici
+a quelli usati da \file{message\_getter}, con l'unica aggiunta di un'opzione
+``\texttt{-t}'' che consente di indicare un tempo di attesa (in secondi) in
+cui il programma si ferma tenendo bloccato il semaforo.
+
+Una volta completata la gestione delle opzioni e degli argomenti (ne deve
+essere presente uno solo, contenente la nuova stringa da usare come
+messaggio), il programma procede (\texttt{\small 10--14}) con l'acquisizione
+del segmento di memoria condivisa usando la funzione \func{FindShm} (trattata
+in sez.~\ref{sec:ipc_posix_shm}) che stavolta deve già esistere.  Il passo
+successivo (\texttt{\small 16--19}) è quello di aprire il semaforo, e a
+differenza di \file{message\_getter}, in questo caso si richiede a
+\func{sem\_open} che questo esista, passando uno zero come secondo ed unico
+argomento.
+
+Una volta completate con successo le precedenti inizializzazioni, il passo
+seguente (\texttt{\small 21--24}) è quello di acquisire il semaforo, dopo di
+che sarà possibile eseguire la sostituzione del messaggio (\texttt{\small 25})
+senza incorrere in possibili \itindex{race~condition} \textit{race condition}
+con la stampa dello stesso da parte di \file{message\_getter}.
+
+Una volta effettuata la modifica viene stampato (\texttt{\small 26}) il tempo
+di attesa impostato con l'opzione ``\texttt{-t}'' dopo di che (\texttt{\small
+  27}) viene eseguita la stessa, senza rilasciare il semaforo che resterà
+quindi bloccato (causando a questo punto una interruzione delle stampe
+eseguite da \file{message\_getter}). Terminato il tempo di attesa si rilascerà
+(\texttt{\small 29--32}) il semaforo per poi uscire.
+
+Per verificare il funzionamento dei programmi occorrerà lanciare per primo
+\file{message\_getter}\footnote{lanciare per primo \file{message\_setter} darà
+  luogo ad un errore, non essendo stati creati il semaforo ed il segmento di
+  memoria condivisa.} che inizierà a stampare una volta al secondo il
+contenuto del messaggio ed i suoi dati, con qualcosa del tipo:
+\begin{Verbatim}
+piccardi@hain:~/gapil/sources$  ./message_getter messaggio
+sem=1, Fri Dec 31 14:12:41 2010
+message: messaggio
+sem=1, Fri Dec 31 14:12:42 2010
+message: messaggio
+...
+\end{Verbatim}
+%$
+proseguendo indefinitamente fintanto che non si prema \texttt{C-c} per farlo
+uscire. Si noti come il valore del semaforo risulti sempre pari ad 1 (in
+quanto al momento esso sarà sempre libero). 
+
+A questo punto si potrà lanciare \file{message\_setter} per cambiare il
+messaggio, nel nostro caso per rendere evidente il funzionamento del blocco
+richiederemo anche una attesa di 3 secondi, ed otterremo qualcosa del tipo:
+\begin{Verbatim}
+piccardi@hain:~/gapil/sources$ ./message_setter -t 3 ciao
+Sleeping for 3 seconds
+\end{Verbatim}
+%$
+dove il programma si fermerà per 3 secondi prima di rilasciare il semaforo e
+terminare. 
+
+L'effetto di questo programma si potrà però apprezzare meglio nell'uscita di
+\file{message\_getter}, che verrà interrotta per questo stesso tempo, prima di
+ricominciare con il nuovo testo:
+\begin{Verbatim}
+...
+sem=1, Fri Dec 31 14:16:27 2010
+message: messaggio
+sem=1, Fri Dec 31 14:16:28 2010
+message: messaggio
+sem=0, Fri Dec 31 14:16:29 2010
+message: ciao
+sem=1, Fri Dec 31 14:16:32 2010
+message: ciao
+sem=1, Fri Dec 31 14:16:33 2010
+message: ciao
+...
+\end{Verbatim}
+%$
+
+E si noterà come nel momento in cui si è lanciato \file{message\_setter} le
+stampe di \file{message\_getter} si bloccheranno, come corretto, dopo aver
+registrato un valore nullo per il semaforo.  Il programma infatti resterà
+bloccato nella \func{sem\_wait} (quella di riga (\texttt{\small 37}) in
+fig.~\ref{fig:ipc_posix_sem_shm_message_server}) fino alla scadenza
+dell'attesa di \file{message\_setter} (con l'esecuzione della \func{sem\_post}
+della riga (\texttt{\small 29}) di
+fig.~\ref{fig:ipc_posix_sem_shm_message_setter}), e riprenderanno con il nuovo
+testo alla terminazione di quest'ultimo.
+
+
+% LocalWords:  like fifo System POSIX RPC Calls Common Object Request Brocker
+% LocalWords:  Architecture descriptor kernel unistd int filedes errno EMFILE
+% LocalWords:  ENFILE EFAULT BUF sez fig fork Stevens siblings EOF read SIGPIPE
+% LocalWords:  EPIPE shell CGI Gateway Interface HTML JPEG URL mime type gs dup
+% LocalWords:  barcode PostScript race condition stream BarCodePage WriteMess
+% LocalWords:  size PS switch wait popen pclose stdio const char command NULL
+% LocalWords:  EINVAL cap fully buffered Ghostscript l'Encapsulated epstopsf of
+% LocalWords:  PDF EPS lseek ESPIPE PPM Portable PixMap format pnmcrop PNG pnm
+% LocalWords:  pnmmargin png BarCode inode filesystem l'inode mknod mkfifo RDWR
+% LocalWords:  ENXIO deadlock client reinviate fortunes fortunefilename daemon
+% LocalWords:  FortuneServer FortuneParse FortuneClient pid libgapil  LD librt
+% LocalWords:  PATH linker pathname ps tmp killall fortuned crash socket domain
+% LocalWords:  socketpair BSD sys protocol sv EAFNOSUPPORT EPROTONOSUPPORT AF
+% LocalWords:  EOPNOTSUPP SOCK SysV IPC Process Comunication ipc perm key exec
+% LocalWords:  header ftok proj stat libc SunOS glibc XPG dell'inode number uid
+% LocalWords:  cuid cgid gid tab MSG shift group umask seq MSGMNI SEMMNI SHMMNI
+% LocalWords:  shmmni msgmni sem sysctl IPCMNI IPCTestId msgget EACCES EEXIST
+% LocalWords:  CREAT EXCL EIDRM ENOENT ENOSPC ENOMEM novo proc MSGMAX msgmax ds
+% LocalWords:  MSGMNB msgmnb linked list msqid msgid linux msg qnum lspid lrpid
+% LocalWords:  rtime ctime qbytes first last cbytes msgctl semctl shmctl ioctl
+% LocalWords:  cmd struct buf EPERM RMID msgsnd msgbuf msgp msgsz msgflg EAGAIN
+% LocalWords:  NOWAIT EINTR mtype mtext long message sizeof LENGTH ts sleep BIG
+% LocalWords:  msgrcv ssize msgtyp NOERROR EXCEPT ENOMSG multiplexing select ls
+% LocalWords:  poll polling queue MQFortuneServer write init HandSIGTERM  l'IPC
+% LocalWords:  MQFortuneClient mqfortuned mutex risorse' inter semaphore semget
+% LocalWords:  nsems SEMMNS SEMMSL semid otime semval sempid semncnt semzcnt nr
+% LocalWords:  SEMVMX SEMOPM semop SEMMNU SEMUME SEMAEM semnum union semun arg
+% LocalWords:  ERANGE SETALL SETVAL GETALL array GETNCNT GETPID GETVAL GETZCNT
+% LocalWords:  sembuf sops unsigned nsops UNDO flg nsop num undo pending semadj
+% LocalWords:  sleeper scheduler running next semundo MutexCreate semunion lock
+% LocalWords:  MutexFind wrapper MutexRead MutexLock MutexUnlock unlock locking
+% LocalWords:  MutexRemove shmget SHMALL SHMMAX SHMMIN shmid shm segsz atime FD
+% LocalWords:  dtime lpid cpid nattac shmall shmmax SHMLBA SHMSEG EOVERFLOW brk
+% LocalWords:  memory shmat shmdt void shmaddr shmflg SVID RND RDONLY rounded
+% LocalWords:  SIGSEGV nattch exit SharedMem ShmCreate memset fill ShmFind home
+% LocalWords:  ShmRemove DirMonitor DirProp chdir GaPiL shmptr DirScan ipcs NFS
+% LocalWords:  ComputeValues ReadMonitor touch SIGTERM dirmonitor unlink fcntl
+% LocalWords:  LockFile UnlockFile CreateMutex FindMutex LockMutex SETLKW GETLK
+% LocalWords:  UnlockMutex RemoveMutex ReadMutex UNLCK WRLCK RDLCK mapping MAP
+% LocalWords:  SHARED ANONYMOUS thread patch names strace system call userid Di
+% LocalWords:  groupid Michal Wronski Krzysztof Benedyczak wrona posix mqueue
+% LocalWords:  lmqueue gcc mount mqd name oflag attr maxmsg msgsize receive ptr
+% LocalWords:  send WRONLY NONBLOCK close mqdes EBADF getattr setattr mqstat to
+% LocalWords:  omqstat curmsgs flags timedsend len prio timespec abs EMSGSIZE
+% LocalWords:  ETIMEDOUT timedreceive getaddr notify sigevent notification l'I
+% LocalWords:  EBUSY sigev SIGNAL signo value sigval siginfo all'userid MESGQ
+% LocalWords:  Konstantin Knizhnik futex tmpfs ramfs cache shared swap CONFIG
+% LocalWords:  lrt blocks PAGECACHE TRUNC CLOEXEC mmap ftruncate munmap FindShm
+% LocalWords:  CreateShm RemoveShm LIBRARY Library libmqueue FAILED EACCESS has
+% LocalWords:  ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
+% LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy it
+% LocalWords:  xffffffff Arrays owner perms Queues used bytes messages device
+% LocalWords:  Cannot find such Segments getter Signal MSGMAXSIZE been stable
+% LocalWords:  for now it's break Berlin sources Let's an accidental feature
+% LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
+% LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds
+
 
 %%% Local Variables: 
 %%% mode: latex