Aggiornamento copyright
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 11e9c26d445e4190779e99c344d2ecc985bf629d..2fc13a8f67d44d6c99e325885e20937d8b4282e6 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2009 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2017 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",
 %% License".
 %%
 
-\chapter{Lcomunicazione fra processi}
+\chapter{L'intercomunicazione 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ù
-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.
+dettaglio in un secondo tempo.  Non affronteremo neanche meccanismi più
+complessi ed evoluti come le RPC (\textit{Remote Procedure Calls}) che in
+genere sono implementati da un ulteriore livello di librerie sopra i
+meccanismi elementari.
 
 
-\section{Lcomunicazione fra processi tradizionale}
+\section{L'intercomunicazione fra processi tradizionale}
 \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
-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
-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 è:
-\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},
-    \errval{ENFILE} e \errval{EFAULT}.}
-\end{prototype}
+uno dei più usati, meccanismi di comunicazione fra processi. Si tratta in
+sostanza di una coppia di file descriptor connessi fra di loro in modo che
+quanto scrive su di uno si può rileggere dall'altro.  Si viene così a
+costituire un canale di comunicazione realizzato tramite i due file
+descriptor, che costituisce appunto una sorta di \textsl{tubo} (che appunto il
+significato del termine inglese \textit{pipe}) attraverso cui si possono far
+passare i dati.
+
+In pratica si tratta di un buffer circolare in memoria in cui il kernel
+appoggia i dati immessi nel file descriptor su cui si scrive per farli poi
+riemergere dal file descriptor da cui si legge. Si tenga ben presente che in
+questo passaggio di dati non è previsto nessun tipo di accesso al disco e che
+nonostante l'uso dei file descriptor le \textit{pipe} non han nulla a che fare
+con i file di dati di cui si è parlato al cap.~\ref{cha:file_IO_interface}.
+
+La funzione di sistema che permette di creare questa speciale coppia di file
+descriptor associati ad una \textit{pipe} è appunto \funcd{pipe}, ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int pipe(int filedes[2])}
+\fdesc{Crea la coppia di file descriptor di una \textit{pipe}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EFAULT}] \param{filedes} non è un indirizzo valido.
+  \end{errlist}
+  ed inoltre \errval{EMFILE} e \errval{ENFILE} nel loro significato generico.}
+\end{funcproto}
 
 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
-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, 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.
-
-\begin{figure}[htb]
+\param{filedes}, il primo è aperto in lettura ed il secondo in scrittura. Come
+accennato concetto di funzionamento di una \textit{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, come
+accennato, 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
+\textit{pipe} è illustrato in fig.~\ref{fig:ipc_pipe_singular}, in cui sono
+indicati i due capi della \textit{pipe}, associati a ciascun file descriptor,
+con le frecce che indicano la direzione del flusso dei dati.
+
+\begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipe}
-  \caption{Schema della struttura di una pipe.}
+  \caption{Schema della struttura di una \textit{pipe}.}
   \label{fig:ipc_pipe_singular}
 \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
-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
+Della funzione di sistema esiste una seconda versione, \funcd{pipe2},
+introdotta con il kernel 2.6.27 e le \acr{glibc} 2.9 e specifica di Linux
+(utilizzabile solo definendo la macro \macro{\_GNU\_SOURCE}), che consente di
+impostare atomicamente le caratteristiche dei file descriptor restituiti, il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{fcntl.h}
+\fdecl{int pipe2(int pipefd[2], int flags)}
+\fdesc{Crea la coppia di file descriptor di una \textit{pipe}.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EINVAL}] il valore di \param{flags} non valido.
+  \end{errlist}
+  e gli altri già visti per \func{pipe} con lo stesso significato.}
+\end{funcproto}
+
+Utilizzando un valore nullo per \param{flags} la funzione è identica a
+\func{pipe}, si può però passare come valore l'OR aritmetico di uno qualunque
+fra \const{O\_NONBLOCK} o \const{O\_CLOEXEC} che hanno l'effetto di impostare
+su entrambi i file descriptor restituiti dalla funzione i relativi flag, già
+descritti per \func{open} in tab.~\ref{tab:open_operation_flag}, che attivano
+rispettivamente la modalità di accesso \textsl{non-bloccante} ed il
+\textit{close-on-exec}.
+
+Chiaramente creare una \textit{pipe} all'interno di un singolo processo non
+serve a niente; se però ricordiamo quanto esposto in
+sez.~\ref{sec:file_shared_access} riguardo al comportamento dei file
+descriptor nei processi figli, è immediato capire come una \textit{pipe} possa
+diventare un meccanismo di intercomunicazione. Un processo figlio infatti
+condivide gli stessi file descriptor del padre, compresi quelli associati ad
+una \textit{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 \textit{pipe}, l'altro può leggere.
 
-\begin{figure}[htb]
+\begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipefork}
-  \caption{Schema dei collegamenti ad una pipe, condivisi fra processo padre e
-    figlio dopo l'esecuzione \func{fork}.}
+  \caption{Schema dei collegamenti ad una \textit{pipe}, condivisi fra
+    processo padre e figlio dopo l'esecuzione \func{fork}.}
   \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
-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.
-
-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
-segnale sia ignorato o bloccato).
-
-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
-da altri processi.
-
-
-\subsection{Un esempio dell'uso delle pipe}
+Tutto ciò ci mostra come sia immediato realizzare un meccanismo di
+comunicazione fra processi attraverso una \textit{pipe}, utilizzando le
+proprietà ordinarie dei file, ma ci mostra anche qual è il principale limite
+nell'uso delle \textit{pipe}.\footnote{Stevens in \cite{APUE} riporta come
+  limite anche il fatto che la comunicazione è unidirezionale, ma in realtà
+  questo è un limite superabile usando una coppia di \textit{pipe}, anche se
+  al costo di una maggiore complessità di gestione.}  È necessario infatti che
+i processi possano condividere i file descriptor della \textit{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 \textit{pipe}, o, più comunemente, essere nella
+relazione padre/figlio.
+
+A differenza di quanto avviene con i file normali, la lettura da una
+\textit{pipe} può essere bloccante (qualora non siano presenti dati), inoltre
+se si legge da una \textit{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 \textit{pipe} il cui
+capo in lettura non è aperto il processo riceverà il segnale \signal{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 \textit{pipe} (\const{PIPE\_BUF}) ci dà inoltre
+un'altra importante informazione riguardo il comportamento delle operazioni di
+lettura e scrittura su di una \textit{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 da altri processi.
+
+La dimensione originale del buffer era di 4096 byte (uguale ad una pagina di
+memoria) fino al kernel 2.6.11, ed è stata portata in seguito a 64kb; ma a
+partire dal kernel 2.6.35 è stata resa disponibile l'operazione di controllo
+\const{F\_SETPIPE\_SZ} (vedi sez.~\ref{sec:ipc_pipes}) che consente di
+modificarne la dimensione.
+
+
+
+\subsection{Un esempio dell'uso delle \textit{pipe}}
 \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
-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
-  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.
+Per capire meglio il funzionamento delle \textit{pipe} faremo un esempio di
+quello 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{quella dei CGI (\textit{Common Gateway Interface}) è una
+  interfaccia che consente ad un server web di eseguire un programma il cui
+  output (che deve essere opportunamente formattato seguendo le specifiche
+  dell'interfaccia) può essere presentato come risposta ad una richiesta HTTP
+  al posto del contenuto di un file, e che ha costituito probabilmente la
+  prima modalità con cui sono state create pagine HTML dinamiche.}  che genera
+una immagine JPEG di un codice a barre, specificato come argomento in
+ingresso.
 
 Un programma che deve essere eseguito come \textit{CGI} deve rispondere a
 delle caratteristiche specifiche, esso infatti non viene lanciato da una
 shell, ma dallo stesso web server, alla richiesta di una specifica URL, che di
 solito ha la forma:
-\begin{verbatim}
-    http://www.sito.it/cgi-bin/programma?argomento
-\end{verbatim}
+\begin{Example}
+http://www.sito.it/cgi-bin/programma?argomento
+\end{Example}
 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.
-
-Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
-\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.
+che ne descrive il \textit{mime-type}) sullo \textit{standard output}, in modo
+che il server web possa reinviarlo al browser che ha effettuato la richiesta,
+che in questo modo è in grado di visualizzarlo opportunamente.
 
-\begin{figure}[htb]
+\begin{figure}[!htb]
   \centering
   \includegraphics[height=5cm]{img/pipeuse}
-  \caption{Schema dell'uso di una pipe come mezzo di comunicazione fra
+  \caption{Schema dell'uso di una \textit{pipe} come mezzo di comunicazione fra
     due processi attraverso l'esecuzione una \func{fork} e la chiusura dei
     capi non utilizzati.}
   \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 \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 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
+Per realizzare quanto voluto useremo in sequenza i programmi \cmd{barcode} e
+\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 \textit{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.
+
+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} può essere eseguito più volte in contemporanea, e si avrebbe una
+evidente \textit{race condition} in caso di accesso simultaneo a detto file da
+istanze diverse. Il problema potrebbe essere superato utilizzando un sempre
+diverso per il file temporaneo, che verrebbe creato all'avvio di ogni istanza,
+utilizzato dai sottoprocessi, e cancellato alla fine della sua esecuzione; ma
+a questo punto le cose non sarebbero più tanto semplici.  L'uso di una
+\textit{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
 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
-(che abbiamo visto in sez.~\ref{sec:file_std_descr} e
-sez.~\ref{sec:file_std_stream}) sulla pipe. In
+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 tab.~\ref{tab:file_std_files} e
+sez.~\ref{sec:file_stream}) sulla \textit{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}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/BarCodePage.c}
   \end{minipage} 
   \normalsize 
@@ -202,183 +258,203 @@ trova nella directory dei sorgenti.
   \label{fig:ipc_barcodepage_code}
 \end{figure}
 
-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
-  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
-\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.
+La prima operazione del programma (\texttt{\small 4-12}) è quella di creare
+le due \textit{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. 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 \textit{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.
 
 Per poter utilizzare queste caratteristiche prima di eseguire \cmd{barcode} si
-chiude (\texttt{\small 20}) il capo aperto in scrittura della prima pipe, e se
-ne collega (\texttt{\small 21}) il capo in lettura allo standard input, usando
-\func{dup2}. Si ricordi che invocando \func{dup2} il secondo file, qualora
-risulti aperto, viene, come nel caso corrente, chiuso prima di effettuare la
-duplicazione. Allo stesso modo, dato che \cmd{barcode} scrive l'immagine
-PostScript del codice a barre sullo standard output, per poter effettuare una
-ulteriore redirezione il capo in lettura della seconda pipe viene chiuso
-(\texttt{\small 22}) mentre il capo in scrittura viene collegato allo standard
-output (\texttt{\small 23}).
+chiude (\texttt{\small 20}) il capo aperto in scrittura della prima
+\textit{pipe}, e se ne collega (\texttt{\small 21}) il capo in lettura allo
+\textit{standard input} usando \func{dup2}. Si ricordi che invocando
+\func{dup2} il secondo file, qualora risulti aperto, viene, come nel caso
+corrente, chiuso prima di effettuare la duplicazione. Allo stesso modo, dato
+che \cmd{barcode} scrive l'immagine PostScript del codice a barre sullo
+standard output, per poter effettuare una ulteriore redirezione il capo in
+lettura della seconda \textit{pipe} viene chiuso (\texttt{\small 22}) mentre
+il capo in scrittura viene collegato allo standard 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 \textit{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
-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
-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
-programma \cmd{gs}. Per questo si crea (\texttt{\small 30--34}) un secondo
-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
-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},
-provvedendo gli appositi switch che consentono di leggere il file da
-convertire dallo standard input e di inviare la conversione sullo standard
-output.
+(\texttt{\small 26}) il capo inutilizzato della prima \textit{pipe} (quello in
+ingresso) e poi scrive (\texttt{\small 27}) la stringa da convertire sul capo
+in uscita, così che \cmd{barcode} possa riceverla dallo \textit{standard
+  input}. A questo punto l'uso della prima \textit{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
+PostScript del codice a barre sul capo in scrittura della seconda
+\textit{pipe}; a 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 leggendo l'immagine PostScript creata da
+\cmd{barcode} dallo \textit{standard input}, per convertirla in JPEG.
+
+Per fare tutto ciò anzitutto si chiude (\texttt{\small 37}) il capo in
+scrittura della seconda \textit{pipe}, e se ne collega (\texttt{\small 38}) il
+capo in lettura allo \textit{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 \textit{mime-type} in testa allo \textit{standard output}. A questo punto
+si può invocare \texttt{\small 41}) \cmd{gs}, provvedendo le opportune opzioni
+del comando che consentono di leggere il file da convertire dallo
+\textit{standard input} e di inviare la conversione sullo \textit{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 è
-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}
-non ritornerebbe.
+capo in scrittura della seconda \textit{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 \textit{pipe} è necessaria, infatti, se non venisse chiusa, \cmd{gs},
+che legge il suo \textit{standard input} da detta \textit{pipe}, resterebbe
+bloccato in attesa di ulteriori dati in ingresso (l'unico modo che un
+programma ha per sapere che i dati in ingresso sono terminati è rilevare che
+lo \textit{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
-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 è:
-\begin{prototype}{stdio.h}
-{FILE *popen(const char *command, const char *type)}
-
-Esegue il programma \param{command}, di cui, a seconda di \param{type},
-restituisce, lo standard input o lo standard output nella pipe collegata allo
-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.}
-\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
-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
-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à
-\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 è:
-\begin{prototype}{stdio.h}
-{int pclose(FILE *stream)}
-
-Chiude il file \param{stream}, restituito da una precedente \func{popen}
-attendendo la terminazione del processo ad essa associato.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso il valore di \var{errno} deriva dalle sottostanti
-  chiamate.}
-\end{prototype}
-\noindent che oltre alla chiusura dello stream si incarica anche di attendere
-(tramite \func{wait4}) la conclusione del processo creato dalla precedente
-\func{popen}.
+Come si è visto la modalità più comune di utilizzo di una \textit{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 è:
+
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{FILE *popen(const char *command, const char *type)}
+\fdesc{Esegue un programma dirottando l'uscita su una \textit{pipe}.} 
+}
+
+{La funzione ritorna l'indirizzo dello stream associato alla \textit{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.}
+\end{funcproto}
+
+La funzione crea una \textit{pipe}, esegue una \func{fork} creando un nuovo
+processo nel quale 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 richiedere che la \textit{pipe} restituita come valore di
+ritorno sia collegata allo \textit{standard input} o allo \textit{standard
+  output} del comando invocato.
+
+La funzione restituisce il puntatore ad uno stream associato alla
+\textit{pipe} creata, che sarà aperto in sola lettura (e quindi associato allo
+\textit{standard output} del programma indicato) in caso si sia indicato
+\code{r}, o in sola scrittura (e quindi associato allo \textit{standard
+  input}) in caso di \code{w}. A partire dalla versione 2.9 delle \acr{glibc}
+(questa è una estensione specifica di Linux) all'argomento \param{type} può
+essere aggiunta la lettera ``\texttt{e}'' per impostare automaticamente il
+flag di \textit{close-on-exec} sul file descriptor sottostante (si ricordi
+quanto spiegato in sez.~\ref{sec:file_open_close}).
+
+Lo \textit{stream} restituito da \func{popen} è identico a tutti gli effetti
+ai \textit{file stream} visti in sez.~\ref{sec:files_std_interface}, anche se
+è collegato ad una \textit{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 è:
+
+\begin{funcproto}{
+\fhead{stdio.h}
+\fdecl{int pclose(FILE *stream)}
+\fdesc{Chiude una \textit{pipe} creata con \func{popen}.} 
+}
+
+{La funzione ritorna lo stato del processo creato da \func{popen} in caso di
+  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà i valori
+  derivanti dalle sottostanti funzioni \func{fclose} e \func{wait4}.}
+\end{funcproto}
+
+La funzione chiude il file \param{stream} associato ad una \textit{pipe}
+creato da una precedente \func{popen}, ed oltre alla chiusura dello stream si
+incarica anche di attendere (tramite \func{wait4}) la conclusione del processo
+creato dalla precedente \func{popen}. Se lo stato di uscita non può essere
+letto la funzione restituirà per \var{errno} un errore di \errval{ECHILD}.
 
 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
-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.
+quanto funzionante, è volutamente codificato in maniera piuttosto complessa,
+inoltre doveva scontare un problema di \cmd{gs} che non era in grado di
+riconoscere correttamente l'Encapsulated PostScript,\footnote{si fa
+  riferimento alla versione di GNU Ghostscript 6.53 (2002-02-13), usata quando
+  l'esempio venne scritto per la prima volta.} per cui si era utilizzato il
+PostScript semplice, generando 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
-generato da \cmd{barcode} utilizzando lo switch \cmd{-E}).  Utilizzando un PDF
+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 l'opzione \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 è
-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
-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
-tutti prevedono una lettura sequenziale del loro input.
-
-Per questo motivo si è dovuto utilizzare un procedimento diverso, eseguendo
+Questo approccio però non può funzionare per via di una delle caratteristiche
+principali delle \textit{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 \textit{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 tutti prevedono una lettura sequenziale del loro input.
+
+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ò
-essere infine trasformata in PNG (con \cmd{pnm2png}).
-
-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
+  memorizzare le immagini, anche se per questo è estremamente inefficiente
+  come formato di archiviazione.}  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,
+inviando l'uscita di ciascuno all'ingresso del successivo, per poi ottenere il
+risultato finale sullo \textit{standard output}: un caso classico di
+utilizzazione delle \textit{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 la sua uscita sullo
+\textit{standard input} del successivo, occorrerà usare \func{popen} aprendo
+la \textit{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
-dopo.
+lettura su una \textit{pipe} è bloccante, per cui un processo, anche se
+lanciato per primo, se non ottiene i dati che gli servono si bloccherà in
+attesa sullo \textit{standard input} finché non otterrà il risultato
+dell'elaborazione del processo che li deve creare, che pur essendo logicamente
+precedente, viene lanciato dopo di lui.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/BarCode.c}
   \end{minipage} 
   \normalsize 
@@ -386,145 +462,157 @@ 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
-provvedere alla redirezione.
-
-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
-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
-ciclo che chiuda, nell'ordine inverso rispetto a quello in cui le si sono
-create, tutte le pipe create con \func{pclose}.
+Nel nostro caso il primo passo (\texttt{\small 14}) è scrivere il
+\textit{mime-type} sullo \textit{standard output}; a questo punto il processo
+padre non necessita più di eseguire ulteriori operazioni sullo
+\textit{standard output} e può tranquillamente provvedere alla redirezione.
+
+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 \textit{pipe} (\texttt{\small 17}) per la scrittura
+eseguendo il programma con \func{popen}, in modo che essa sia collegata allo
+\textit{standard input}, e poi redirige (\texttt{\small 18}) lo
+\textit{standard output} su detta \textit{pipe}.
+
+In questo modo il primo processo ad essere invocato (che è l'ultimo della
+catena) scriverà ancora sullo \textit{standard output} del processo padre, ma
+i successivi, a causa di questa redirezione, scriveranno sulla \textit{pipe}
+associata allo \textit{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 \textit{pipe}, che è
+collegata al suo \textit{standard input}, infine si può eseguire
+(\texttt{\small 24-27}) un ciclo che chiuda con \func{pclose}, nell'ordine
+inverso rispetto a quello in cui le si sono create, tutte le \textit{pipe}
+create in precedenza.
 
 
 \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 \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;
-\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
-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
-\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.
-
-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.
-
-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
-  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
-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
-stallo.\footnote{se si cerca di leggere da una fifo che non contiene dati si
-  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, è
-piuttosto frequente l'utilizzo di una fifo come canale di comunicazione nelle
-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
-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
-riporta in \cite{APUE} altre due casistiche principali per l'uso delle fifo:
-\begin{itemize}
+o nella relazione padre/figlio. Per superare questo problema lo standard
+POSIX.1 ha introdotto le \textit{fifo}, che hanno le stesse caratteristiche
+delle \textit{pipe}, ma che invece di essere visibili solo attraverso un file
+descriptor creato all'interno di un processo da una \textit{system call}
+apposita, costituiscono un oggetto che risiede sul filesystem (si rammenti
+quanto detto in sez.~\ref{sec:file_file_types}) che può essere aperto come un
+qualunque file, 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
+\textit{pipe}, attraverso un buffer nel kernel, senza transitare dal
+filesystem. Il fatto che siano associate ad un \textit{inode} presente sul
+filesystem serve infatti solo a fornire un punto di accesso per i processi,
+che permetta a questi ultimi di accedere alla stessa \textit{fifo} senza avere
+nessuna relazione, con una semplice \func{open}. Il comportamento delle
+funzioni di lettura e scrittura è identico a quello illustrato per le
+\textit{pipe} in sez.~\ref{sec:ipc_pipes}.
+
+Abbiamo già trattato in sez.~\ref{sec:file_mknod} le funzioni \func{mknod} e
+\func{mkfifo} che permettono di creare una \textit{fifo}. Per utilizzarne una
+un processo non avrà che da aprire il relativo file speciale o in lettura o
+scrittura; nel primo caso il processo sarà collegato al capo di uscita della
+\textit{fifo}, e dovrà leggere, nel secondo al capo di ingresso, e dovrà
+scrivere.
+
+Il kernel alloca un singolo buffer per ciascuna \textit{fifo} che sia stata
+aperta, e questa potrà 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 \textit{fifo} la funzione \func{open} di norma
+si blocca se viene eseguita quando l'altro capo non è aperto.
+
+Le \textit{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 \textit{fifo} anche in lettura/scrittura (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 comunque
+una \textit{fifo} in scrittura anche se non ci sono ancora processi il
+lettura. Infine è possibile anche usare la \textit{fifo} all'interno di un
+solo processo, nel qual caso però occorre stare molto attenti alla possibili
+situazioni di stallo: se si cerca di leggere da una \textit{fifo} che non
+contiene dati si avrà infatti un \textit{deadlock} immediato, dato che il
+processo si blocca e quindi non potrà mai eseguire le funzioni di scrittura.
+
+Per la loro caratteristica di essere accessibili attraverso il filesystem, è
+piuttosto frequente l'utilizzo di una \textit{fifo} come canale di
+comunicazione nelle 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 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
+riporta in \cite{APUE} altre due casistiche principali per l'uso delle
+\textit{fifo}:
+\begin{itemize*}
 \item Da parte dei comandi di shell, per evitare la creazione di file
   temporanei quando si devono inviare i dati di uscita di un processo
-  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}).
-\end{itemize}
-
-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,
-con il comando \cmd{tee}, sulle varie fifo.
-
-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
-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
-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
-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.
-
-\begin{figure}[htb]
+  sull'input di parecchi altri (attraverso l'uso del comando \cmd{tee}).  
+\item Come canale di comunicazione fra un client ed un
+  server (il modello \textit{client-server} è illustrato in
+  sez.~\ref{sec:net_cliserv}).
+\end{itemize*}
+
+Nel primo caso quello che si fa è creare tante \textit{fifo} da usare come
+\textit{standard input} quanti sono i processi a cui i vogliono inviare i
+dati; questi ultimi saranno stati posti in esecuzione ridirigendo lo
+\textit{standard input} dalle \textit{fifo}, si potrà poi eseguire il processo
+che fornisce l'output replicando quest'ultimo, con il comando \cmd{tee}, sulle
+varie \textit{fifo}.
+
+Il secondo caso è relativamente semplice qualora si debba comunicare con un
+processo alla volta, nel qual caso basta usare due \textit{fifo}, una per
+leggere ed una per scrivere. Le cose diventano invece molto più complesse
+quando si vuole effettuare una comunicazione fra un server ed un numero
+imprecisato di client. Se il primo infatti può ricevere le richieste
+attraverso una \textit{fifo} ``\textsl{nota}'', per le risposte non si può
+fare altrettanto, dato che, per la struttura sequenziale delle \textit{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
+illustrata in fig.~\ref{fig:ipc_fifo_server_arch} in cui i client
+inviano le richieste al server su una \textit{fifo} nota mentre le
+risposte vengono reinviate dal server a ciascuno di essi su una
+\textit{fifo} temporanea creata per l'occasione.
+
+\begin{figure}[!htb]
   \centering
   \includegraphics[height=9cm]{img/fifoserver}
-  \caption{Schema dell'utilizzo delle fifo nella realizzazione di una
-  architettura di comunicazione client/server.}
+  \caption{Schema dell'utilizzo delle \textit{fifo} nella realizzazione di una
+    architettura di comunicazione client/server.}
   \label{fig:ipc_fifo_server_arch}
 \end{figure}
 
-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
-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
-\file{FortuneServer.c}.
-
-\begin{figure}[!htb]
+Come esempio di uso questa architettura e dell'uso delle \textit{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 impostabili 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 l'impostazione 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 \file{FortuneServer.c}.
+
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/FortuneServer.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del server di \textit{fortunes}
-    basato sulle fifo.}
+    basato sulle \textit{fifo}.}
   \label{fig:ipc_fifo_server}
 \end{figure}
 
@@ -532,155 +620,161 @@ 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
-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
+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 \textit{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
-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
-  23}) la funzione \func{daemon} per far proseguire l'esecuzione del programma
-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
-dal capo in lettura, l'esecuzione di \func{read} ritorna con zero byte (si ha
-cioè una condizione di end-of-file).
-
-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.
-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
-  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.}
+Il passo successivo (\texttt{\small 17-22}) è quello di creare con
+\func{mkfifo} la \textit{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 \textit{fifo}).
+
+Una volta che si è certi che la \textit{fifo} di ascolto esiste la procedura
+di inizializzazione è completata. A questo punto (\texttt{\small 23}) si può
+chiamare la funzione \func{daemon} per far proseguire l'esecuzione del
+programma in background come demone.  Si può quindi procedere (\texttt{\small
+  24-33}) alla apertura della \textit{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
+\textit{fifo} è aperta solo dal capo in lettura, l'esecuzione di \func{read}
+ritorna con zero byte (si ha cioè una condizione di \textit{end-of-file}).
+
+Nel nostro caso la prima apertura si bloccherà fintanto che un qualunque
+client non apre a sua volta la \textit{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 \textit{fifo}.  A questo punto il server resta (se non ci sono
+altri client che stanno effettuando richieste) con la \textit{fifo} chiusa sul
+lato in lettura, ed in questo stato la funzione \func{read} non si bloccherà
+in attesa di dati in ingresso, ma ritornerà in continuazione, restituendo una
+condizione di \textit{end-of-file}.
+
+Si è usata questa tecnica per compatibilità, Linux infatti supporta l'apertura
+delle \textit{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.
 
 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 è
-  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
-a \func{read} possono bloccarsi.
-
-A questo punto si può entrare nel ciclo principale del programma che fornisce
-le risposte ai client (\texttt{\small 34--50}); questo viene eseguito
+  24-28}),\footnote{di solito si effettua l'apertura del capo in lettura di
+  una \textit{fifo} in modalità non bloccante, per evitare il rischio di uno
+  stallo: se infatti nessuno apre la \textit{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 \textit{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
+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 funzione di chiusura che cancella la fifo).
-
-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
-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})
-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ù.
-
-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
+modo da passare attraverso la funzione di chiusura che cancella la
+\textit{fifo}).
+
+Il server è progettato per accettare come richieste dai client delle stringhe
+che contengono il nome della \textit{fifo} sulla quale deve essere inviata la
+risposta.  Per cui prima (\texttt{\small 35-39}) si esegue la lettura dalla
+stringa di richiesta dalla \textit{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}) all'apertura della \textit{fifo} per la risposta, che poi 
+(\texttt{\small 47-48}) vi sarà scritta. Infine (\texttt{\small 49}) si
+chiude la \textit{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
 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]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/FortuneClient.c}
   \end{minipage} 
   \normalsize 
   \caption{Sezione principale del codice del client di \textit{fortunes}
-    basato sulle fifo.}
+    basato sulle \textit{fifo}.}
   \label{fig:ipc_fifo_client}
 \end{figure}
 
-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
+La prima istruzione (\texttt{\small 12}) compone il nome della \textit{fifo}
+che dovrà essere utilizzata per ricevere la risposta dal server.  Si usa il
+\ids{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).
-
-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}).
-
-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
+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
+questo prima si apre la \textit{fifo} nota (\texttt{\small 19-23}), e poi ci
+si scrive (\texttt{\small 24}) la stringa composta in precedenza, che contiene
+il nome della \textit{fifo} da utilizzare per la risposta. Infine si richiude
+la \textit{fifo} del server che a questo punto non serve più (\texttt{\small
+  25}). 
+
+Inoltrata la richiesta si può passare alla lettura della risposta; anzitutto
+si apre (\texttt{\small 26-30}) la \textit{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
 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
+\textit{fifo} e si cancella (\texttt{\small 34}) il relativo file.  Si noti
+come la \textit{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
 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}
-in modo che il linker dinamico possa accedervi.
-
-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
-il server, facendogli leggere una decina di frasi, con:
-\begin{verbatim}
-[piccardi@gont sources]$ ./fortuned -n10
-\end{verbatim}
+state raccolte nella libreria \file{libgapil.so}, e per poterla usare
+occorrerà definire la variabile di ambiente \envvar{LD\_LIBRARY\_PATH} in modo
+che il linker dinamico possa accedervi.
+
+In generale questa variabile indica il \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 il server,
+facendogli leggere una decina di frasi, con:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./fortuned -n10}
+\end{Console}
+%$
 
 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}
-[piccardi@gont sources]$ ps aux
+\begin{Console}
+[piccardi@gont sources]$ \textbf{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
-ascolto \file{fortune.fifo}. A questo punto potremo interrogare il server con
-il programma client; otterremo così:
-\begin{verbatim}
-[piccardi@gont sources]$ ./fortune
+\end{Console}
+%$
+e si potrà verificare anche che in \file{/tmp} è stata creata la \textit{fifo}
+di ascolto \file{fortune.fifo}. A questo punto potremo interrogare il server
+con il programma client; otterremo così:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./fortune}
 Linux ext2fs has been stable for a long time, now it's time to break it
-        -- Linuxkongreß '95 in Berlin
-[piccardi@gont sources]$ ./fortune
+        -- Linuxkongreß '95 in Berlin
+[piccardi@gont sources]$ \textbf{./fortune}
 Let's call it an accidental feature.
         --Larry Wall
-[piccardi@gont sources]$ ./fortune
+[piccardi@gont sources]$ \textbf{./fortune}
 .........    Escape the 'Gates' of Hell
   `:::'                  .......  ......
    :::  *                  `::.    ::'
@@ -691,305 +785,320 @@ 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{Console}
+%$
 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
-\code{killall fortuned} e potremo verificare che il gestore del segnale ha
-anche correttamente cancellato la fifo di ascolto da \file{/tmp}.
+Infine per chiudere il server basterà inviargli un segnale di terminazione (ad
+esempio con \cmd{killall fortuned}) e potremo verificare che il gestore del
+segnale ha anche correttamente cancellato la \textit{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
-  far restare le fifo temporanee sul filesystem, di come sia necessario
-  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 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.
+  per il server sapere se un client è andato in crash, con la possibilità di
+  far restare le \textit{fifo} temporanee sul filesystem, di come sia
+  necessario intercettare \signal{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 \textit{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.
 
 
 
 \subsection{La funzione \func{socketpair}}
 \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
-\textsl{socket locali} (o \textit{Unix domain socket}). Tratteremo l'argomento
-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 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, 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 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:
+Un meccanismo di comunicazione molto simile alle \textit{pipe}, ma che non
+presenta il problema della unidirezionalità del flusso dei dati, è quello dei
+cosiddetti \textsl{socket locali} (o \textit{Unix domain socket}).  Tratteremo
+in generale i socket in cap.~\ref{cha:socket_intro}, nell'ambito
+dell'interfaccia che essi forniscono per la programmazione di rete, e vedremo
+anche (in~sez.~\ref{sec:sock_sa_local}) come si possono utilizzare i file
+speciali di tipo socket, analoghi a quelli associati alle \textit{fifo} (si
+rammenti sez.~\ref{sec:file_file_types}) cui si accede però attraverso quella
+medesima interfaccia; vale però la pena esaminare qui una modalità di uso dei
+socket locali che li rende sostanzialmente identici ad una \textit{pipe}
+bidirezionale.
+
+La funzione di sistema \funcd{socketpair}, introdotta da BSD ma supportata in
+genere da qualunque sistema che fornisca l'interfaccia dei socket ed inclusa
+in POSIX.1-2001, consente infatti di creare una coppia di file descriptor
+connessi fra 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{funcproto}{
+\fhead{sys/types.h} 
+\fhead{sys/socket.h}
+\fdecl{int socketpair(int domain, int type, int protocol, int sv[2])}
+\fdesc{Crea una coppia di socket connessi fra loro.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
   \begin{errlist}
   \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.
+  \item[\errcode{EPROTONOSUPPORT}] il protocollo specificato non è supportato.
   \end{errlist}
-  ed inoltre \errval{EMFILE},  \errval{EFAULT}.
-}
-\end{functions}
+  ed inoltre \errval{EFAULT}, \errval{EMFILE} e \errval{ENFILE} nel loro
+  significato generico.}
+\end{funcproto}
 
 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 (vedi
-sez.~\ref{sec:sock_creation}) che è quella che fornisce il substrato per
+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}.
+\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
+A partire dal kernel 2.6.27 la funzione supporta nell'indicazione del tipo di
+socket anche i due flag \const{SOCK\_NONBLOCK} e \const{SOCK\_CLOEXEC}
+(trattati in sez.~\ref{sec:sock_type}), con effetto identico agli analoghi
+\const{O\_CLOEXEC} e \const{O\_NONBLOCK} di una \func{open} (vedi
+tab.~\ref{tab:open_operation_flag}).
+
+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
+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}).
+questa funzionalità in sez.~\ref{sec:sock_fd_passing}).
 
 
-\section{Il sistema di comunicazione fra processi di System V}
+\section{L'intercomunicazione 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 è
-rigidamente sequenziale: una situazione in cui un processo scrive qualcosa che
-molti altri devono poter leggere non può essere implementata con una pipe.
+Benché le \textit{pipe} e le \textit{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 \textit{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à.
-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
-\textit{Inter-Process Comunication}).
+programmazione, poi inclusa anche in POSIX.1-2001, 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 \textit{Inter-Process
+  Comunication}).
 
 
 
 \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.
-
-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
-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
-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
-  IPC} vengono creati direttamente dal kernel, e sono accessibili solo
-specificando il relativo \textsl{identificatore}. Questo è un numero
-progressivo (un po' come il \acr{pid} dei processi) che il kernel assegna a
+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 per
+\textit{pipe} e \textit{fifo}, la memoria allocata per questi oggetti non
+viene rilasciata 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 è, dato che non c'è
+come per i file un contatore del numero di riferimenti che ne indichi l'essere
+in uso, che essi possono essere cancellati anche se ci sono dei processi che
+li stanno utilizzando, con tutte le conseguenze (ovviamente assai sgradevoli)
+del caso.
+
+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
+progressivo (un po' come il \ids{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
-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
-stesso oggetto.
+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 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 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.
+  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.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/ipc_perm.h}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \structd{ipc\_perm}, come definita in
-    \file{sys/ipc.h}.}
+    \headfiled{sys/ipc.h}.}
   \label{fig:ipc_ipc_perm}
 \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 \constd{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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  
-  \funcdecl{key\_t ftok(const char *pathname, int proj\_id)}
-  
-  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
-    errore di \func{stat}.}
-\end{functions}
+nome di un file ed un numero di versione; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h} 
+\fhead{sys/ipc.h} 
+\fdecl{key\_t ftok(const char *pathname, int proj\_id)}
+\fdesc{Restituisce una chiave per identificare un oggetto del \textit{SysV
+    IPC}.}}
+
+{La funzione ritorna la chiave in caso di successo e $-1$ per un errore, nel
+  qual caso \var{errno} assumerà uno dei possibili codici di errore di
+  \func{stat}.}
+\end{funcproto}
 
 La funzione determina un valore della chiave sulla base di \param{pathname},
-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
-  \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 \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
-\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
+che deve specificare il \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. Nelle \acr{libc4} e \acr{libc5}, come avviene in SunOS,
+l'argomento \param{proj\_id} è dichiarato tipo \ctyp{char}, la \acr{glibc} usa
+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 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}.
+
+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
-effettuata una revisione completa nello standard POSIX.1b, che tratteremo in
-sez.~\ref{sec:ipc_posix}.
+file, e tutta l'interfaccia è inutilmente complessa.  Per questo se ne
+sconsiglia assolutamente l'uso nei nuovi programmi, considerato che è ormai
+disponibile una revisione completa dei meccanismi di IPC fatta secondo quanto
+indicato dallo standard POSIX.1b, che presenta una realizzazione più sicura ed
+una interfaccia più semplice, che tratteremo in sez.~\ref{sec:ipc_posix}.
 
 
 \subsection{Il controllo di accesso}
 \label{sec:ipc_sysv_access_control}
 
-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,
-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ù
+Oltre alle chiavi, abbiamo visto in fig.~\ref{fig:ipc_ipc_perm} 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, 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ù
 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},
-  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
-  costanti non sono definite.} e come per i file definiscono gli accessi per
-il proprietario, il suo gruppo e tutti gli altri.
+tab.~\ref{tab:file_mode_flags} e come per i file definiscono gli accessi per
+il proprietario, il suo gruppo e tutti gli altri. 
+
+Se però si vogliono usare le costanti simboliche di
+tab.~\ref{tab:file_mode_flags} occorrerà includere anche il file
+\headfile{sys/stat.h}; alcuni sistemi definiscono le costanti \constd{MSG\_R}
+(il valore ottale \texttt{0400}) e \constd{MSG\_W} (il valore ottale
+\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 costanti non sono
+definite.
 
 Quando l'oggetto viene creato i campi \var{cuid} e \var{uid} di
 \struct{ipc\_perm} ed i campi \var{cgid} e \var{gid} vengono impostati
-rispettivamente al valore dell'user-ID e del group-ID effettivo del processo
+rispettivamente al valore dell'\ids{UID} e del \ids{GID} 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
-  consentito. 
-\item se l'user-ID effettivo del processo corrisponde o al valore del campo
+controlli è simile a quello dei file, ed avviene secondo questa sequenza:
+\begin{itemize*}
+\item se il processo ha i privilegi di amministratore (più precisamente la
+  capacità \const{CAP\_IPC\_OWNER}) l'accesso è sempre consentito.
+\item se l'\ids{UID} 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.
-\item se il group-ID effettivo del processo corrisponde o al
+    di lettura per le operazioni di lettura.} l'accesso è consentito.
+\item se il \ids{GID} 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 \itindex{umask} \textit{umask} (si ricordi quanto esposto in
+differenza rispetto a quanto avviene per i file è che per gli oggetti di IPC
+il valore di \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
@@ -1001,42 +1110,30 @@ 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.
-
-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 \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
-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
-  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.
+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, fino al kernel
+2.2.x questi erano definiti dalle costanti \const{MSGMNI}, \const{SEMMNI} e
+\const{SHMMNI}, e potevano essere cambiati (come tutti gli altri limiti
+relativi al \textit{SysV-IPC}) solo con una ricompilazione del kernel.  A
+partire dal kernel 2.4.x è possibile cambiare questi valori a sistema attivo
+scrivendo sui file \sysctlrelfile{kernel}{shmmni},
+\sysctlrelfile{kernel}{msgmni} e \sysctlrelfiled{kernel}{sem} di
+\file{/proc/sys/kernel} o con l'uso di \func{sysctl}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/IPCTestId.c}
   \end{minipage} 
   \normalsize 
   \label{fig:ipc_sysv_idtest}
 \end{figure}
 
-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
-delle opzioni a riga di comando, che permette di specificare quante volte
-effettuare il ciclo \var{n}, e su quale tipo di oggetto eseguirlo.
-
-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
-del tipo:
-\begin{verbatim}
-piccardi@gont sources]$ ./ipctestid
+Per ciascun tipo di oggetto di IPC 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 precedenza, per restituire il nuovo identificatore al
+numero di oggetti presenti viene sommato il valore corrente del campo
+\var{seq}, moltiplicato per il numero massimo di oggetti di quel tipo.
+
+Questo in realtà è quanto avveniva fino ai kernel della serie 2.2, dalla serie
+2.4 viene usato lo stesso fattore di moltiplicazione per qualunque tipo di
+oggetto, utilizzando il valore dalla costante \constd{IPCMNI} (definita in
+\file{include/linux/ipc.h}), che indica il limite massimo complessivo per il
+numero di tutti gli oggetti presenti nel \textit{SysV-IPC}, ed il cui default
+è 32768.  Si evita così il riutilizzo degli stessi numeri, e si fa sì che
+l'identificatore assuma tutti i valori possibili.
+
+In fig.~\ref{fig:ipc_sysv_idtest} è riportato il codice di un semplice
+programma di test che si limita a creare un oggetto di IPC (specificato con
+una opzione a riga di comando), stamparne il numero di identificatore, e
+cancellarlo, il tutto un numero di volte specificato tramite una seconda
+opzione.  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 per 5 ripetizioni
+del ciclo. Per questo motivo se non si utilizzano opzioni verrà eseguito per
+cinque volte il ciclo (\texttt{\small 7-11}), in cui si crea una coda di
+messaggi (\texttt{\small 8}), se ne stampa l'identificativo (\texttt{\small
+  9}) e la si rimuove (\texttt{\small 10}). Non stiamo ad approfondire adesso
+il significato delle funzioni utilizzate, che verranno esaminate nelle
+prossime sezioni.
+
+Quello che ci interessa infatti è verificare l'allocazione degli
+identificativi associati agli oggetti; lanciando il comando si otterrà
+pertanto qualcosa del tipo:
+\begin{Console}
+piccardi@gont sources]$ \textbf{./ipctestid}
 Identifier Value 0 
 Identifier Value 32768 
 Identifier Value 65536 
 Identifier Value 98304 
-Identifier Value 131072 
-\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}
-[piccardi@gont sources]$ ./ipctestid
-Identifier Value 163840 
+Identifier Value 131072
+\end{Console}
+%$
+il che ci mostra che stiamo lavorando con un kernel posteriore alla serie 2.2
+nel quale non avevamo ancora usato nessuna coda di messaggi (il valore nullo
+del primo identificativo indica che il campo \var{seq} era zero). Ripetendo il
+comando, e quindi eseguendolo in un processo diverso, in cui non può esistere
+nessuna traccia di quanto avvenuto in precedenza, otterremo come nuovo
+risultato:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./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à
-mantenuta staticamente all'interno del sistema.
+\end{Console}
+%$
+in cui la sequenza numerica prosegue, cosa che ci mostra come il valore di
+\var{seq} continui ad essere incrementato e costituisca in effetti una
+quantità mantenuta all'interno del sistema ed indipendente dai processi.
 
 
 \subsection{Code di messaggi}
 \label{sec:ipc_sysv_mq}
 
-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
-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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/msg.h} 
-  
-  \funcdecl{int msgget(key\_t key, int flag)}
-  
-  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:
+Il primo oggetto introdotto dal \textit{SysV-IPC} è quello delle code di
+messaggi.  Le code di messaggi sono oggetti analoghi alle \textit{pipe} o alle
+\textit{fifo} ed il loro scopo principale è quello di fornire a processi
+diversi un meccanismo con cui scambiarsi dei dati in forma di messaggio. Dato
+che le \textit{pipe} e le \textit{fifo} costituiscono una ottima alternativa,
+ed in genere sono molto più semplici da usare, le code di messaggi sono il
+meno utilizzato degli oggetti introdotti dal \textit{SysV-IPC}.
+
+La funzione di sistema che permette di ottenere l'identificativo di una coda
+di messaggi esistente per potervi accedere, oppure di creare una nuova coda
+qualora quella indicata non esista ancora, è \funcd{msgget}, e il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h} 
+\fhead{sys/msg.h} 
+\fdecl{int msgget(key\_t key, int flag)}
+\fdesc{Ottiene o crea una coda di messaggi.} 
+}
+
+{La funzione ritorna l'identificatore (un intero positivo) in caso di successo
+  e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \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à
-  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{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à
+    esiste, ma erano specificati sia \const{IPC\_CREAT} che \const{IPC\_EXCL}.
+  \item[\errcode{EIDRM}] la coda richiesta è marcata per essere cancellata
+    (solo fino al kernel 2.3.20).
+  \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}.
-}
-\end{functions}
+ \end{errlist}
+ ed inoltre \errval{ENOMEM} nel suo significato generico.}
+\end{funcproto}
 
 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 è
-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
+\const{IPC\_PRIVATE}, nel qual caso la coda è creata ex-novo e non vi è
+associata alcuna chiave (per questo viene detta \textsl{privata}), ed il
+processo e i suoi eventuali figli potranno farvi riferimento solo attraverso
+l'identificatore.
+
+Se invece si specifica un valore diverso da \const{IPC\_PRIVATE} (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
 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
+corrispondente al valore \constd{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 \constd{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
-processi di accedere alla coda (se hanno privilegi sufficienti) una volta che
-questi possano indovinare o ricavare (ad esempio per tentativi)
+processi di accedere alla coda, se hanno privilegi sufficienti, una volta che
+questi possano indovinare o ricavare, ad esempio per tentativi,
 l'identificatore ad essa associato. Per come sono implementati gli oggetti di
-IPC infatti non esiste una maniera che  garantisca l'accesso esclusivo ad una
-coda di messaggi.  Usare \const{IPC\_PRIVATE} o const{IPC\_CREAT} e
-\const{IPC\_EXCL} per \param{flag} comporta solo la creazione di una nuova
-coda.
+IPC infatti non esiste alcun modo in cui si possa garantire l'accesso
+esclusivo ad una coda di messaggi.  Usare \const{IPC\_PRIVATE} o
+\const{IPC\_CREAT} e \const{IPC\_EXCL} per \param{flag} comporta solo la
+creazione di una nuova coda.
 
 \begin{table}[htb]
   \footnotesize
   \centering
   \begin{tabular}[c]{|c|r|l|l|}
     \hline
-    \textbf{Costante} & \textbf{Valore} & \textbf{File in \texttt{proc}}
+    \textbf{Costante} & \textbf{Valore} & \textbf{File in \file{/proc}}
     & \textbf{Significato} \\
     \hline
     \hline
-    \const{MSGMNI}&   16& \file{msgmni} & Numero massimo di code di
+    \constd{MSGMNI}&   16& \file{msgmni} & Numero massimo di code di
                                           messaggi.\\
-    \const{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo
+    \constd{MSGMAX}& 8192& \file{msgmax} & Dimensione massima di un singolo
                                           messaggio.\\
-    \const{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di 
+    \constd{MSGMNB}&16384& \file{msgmnb} & Dimensione massima del contenuto di 
                                           una coda.\\
     \hline
   \end{tabular}
@@ -1174,43 +1304,65 @@ coda.
   \label{tab:ipc_msg_limits}
 \end{table}
 
-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
-modificare questi limiti attraverso l'uso di \func{sysctl} o scrivendo nei
-file \procrelfile{/proc/sys/kernel}{msgmax},
-\procrelfile{/proc/sys/kernel}{msgmnb} e
-\procrelfile{/proc/sys/kernel}{msgmni} di \file{/proc/sys/kernel/}.
+Le code di messaggi sono caratterizzate da tre limiti fondamentali, un tempo
+definiti staticamente e corrispondenti alle prime tre costanti riportate in
+tab.~\ref{tab:ipc_msg_limits}.  Come accennato però con tutte le versioni più
+recenti del kernel con Linux è possibile modificare questi limiti attraverso
+l'uso di \func{sysctl} o scrivendo nei file \sysctlrelfiled{kernel}{msgmax},
+\sysctlrelfiled{kernel}{msgmnb} e \sysctlrelfiled{kernel}{msgmni} di
+\file{/proc/sys/kernel/}.
+
+\itindbeg{linked~list}
+
+Una coda di messaggi è costituita da una \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 uno schema semplificato con cui queste strutture vengono mantenute
+dal kernel. Lo schema illustrato in realtà è una semplificazione di quello
+usato fino ai kernel della serie 2.2. A partire della serie 2.4 la gestione
+delle code di messaggi è effettuata in maniera diversa (e non esiste una
+struttura \kstruct{msqid\_ds} nel kernel), ma abbiamo mantenuto lo schema
+precedente dato che illustra in maniera più che adeguata i principi di
+funzionamento delle code di messaggi.
+
+\itindend{linked~list}
 
-
-\begin{figure}[htb]
-  \centering \includegraphics[width=15cm]{img/mqstruct}
-  \caption{Schema della struttura di una coda messaggi.}
+\begin{figure}[!htb]
+  \centering \includegraphics[width=13cm]{img/mqstruct}
+  \caption{Schema delle strutture di una coda di messaggi
+    (\kstructd{msqid\_ds} e \kstructd{msg}).}
   \label{fig:ipc_mq_schema}
 \end{figure}
 
 
-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.}
+A ciascuna coda è associata una struttura \kstruct{msqid\_ds} la cui
+definizione è riportata in fig.~\ref{fig:ipc_msqid_ds} ed a cui si accede
+includendo \headfiled{sys/msg.h};
+%
+% INFO: sotto materiale obsoleto e non interessante
+% In questa struttura il
+% kernel mantiene le principali informazioni riguardo lo stato corrente della
+% coda. Come accennato questo vale fino ai kernel della serie 2.2, essa viene
+% usata nei kernel della serie 2.4 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{include/linux/msg.h}, e fanno riferimento
+% alla definizione della omonima struttura usata nel kernel. 
+%In fig.~\ref{fig:ipc_msqid_ds} sono elencati i campi definiti in
+%\headfile{sys/msg.h};  
+si tenga presente che il campo \var{\_\_msg\_cbytes} non è previsto dallo
+standard POSIX.1-2001 e che alcuni campi fino al kernel 2.2 erano definiti
+come \ctyp{short}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{.90\textwidth}
     \includestruct{listati/msqid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1219,164 +1371,139 @@ cui queste strutture vengono mantenute dal kernel.\footnote{lo schema
   \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
-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
-  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
-  struttura usata nel kernel.} In fig.~\ref{fig:ipc_msqid_ds} sono elencati i
-campi significativi definiti in \file{sys/msg.h}, a cui si sono aggiunti gli
-ultimi tre campi che sono previsti dalla implementazione originale di System
-V, ma non dallo standard Unix98.
-
 Quando si crea una nuova coda con \func{msgget} questa struttura viene
-inizializzata, in particolare il campo \var{msg\_perm} viene inizializzato
-come illustrato in sez.~\ref{sec:ipc_sysv_access_control}, per quanto riguarda
-gli altri campi invece:
+inizializzata,\footnote{in realtà viene inizializzata una struttura interna al
+  kernel, ma i dati citati sono gli stessi.} in particolare il campo
+\var{msg\_perm} che esprime i permessi di accesso viene inizializzato nella
+modalità illustrata in sez.~\ref{sec:ipc_sysv_access_control}. Per quanto
+riguarda gli altri campi invece:
 \begin{itemize*}
 \item il campo \var{msg\_qnum}, che esprime il numero di messaggi presenti
   sulla coda, viene inizializzato a 0.
 \item i campi \var{msg\_lspid} e \var{msg\_lrpid}, che esprimono
-  rispettivamente il \acr{pid} dell'ultimo processo che ha inviato o ricevuto
+  rispettivamente il \ids{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.
-\item il campo \var{msg\_qbytes} che esprime la dimensione massima del
+\item il campo \var{msg\_ctime}, che esprime il tempo di ultima modifica della
+  coda, viene inizializzato al tempo corrente.
+\item il campo \var{msg\_qbytes}, che esprime la dimensione massima del
   contenuto della coda (in byte) viene inizializzato al valore preimpostato
   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 è
-  inizializzato a zero. Questi campi sono ad uso interno dell'implementazione
-  e non devono essere utilizzati da programmi in user space).
+\item il campo \var{\_\_msg\_cbytes}, che esprime la dimensione in byte dei
+  messaggi presenti sulla coda, viene inizializzato a zero.
+% 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 è
+%   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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/msg.h} 
-  
-  \funcdecl{int msgctl(int msqid, int cmd, struct msqid\_ds *buf)}
-  
-  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:
+effettuate con la funzione di sistema \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 è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/msg.h}
+\fdecl{int msgctl(int msqid, int cmd, struct msqid\_ds *buf)}
+\fdesc{Esegue una operazione su una coda.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un 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}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
-}
-\end{functions}
-
-La funzione permette di accedere ai valori della struttura \struct{msqid\_ds},
-mantenuta all'indirizzo \param{buf}, per la coda specificata
-dall'identificatore \param{msqid}. Il comportamento della funzione dipende dal
-valore dell'argomento \param{cmd}, che specifica il tipo di azione da
-eseguire; i valori possibili sono:
-\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{IPC\_STAT}] Legge le informazioni riguardo la coda nella
-  struttura indicata da \param{buf}. Occorre avere il permesso di lettura
-  sulla coda.
-\item[\const{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
+  generico.}
+\end{funcproto}
+
+La funzione permette di eseguire una operazione di controllo per la coda
+specificata dall'identificatore \param{msqid}, utilizzando i valori della
+struttura \struct{msqid\_ds}, mantenuta all'indirizzo \param{buf}. Il
+comportamento della funzione dipende dal valore dell'argomento \param{cmd},
+che specifica il tipo di azione da eseguire. I valori possibili
+per \param{cmd} sono:
+\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{IPC\_STAT}] Legge le informazioni riguardo la coda nella
+  struttura \struct{msqid\_ds} indicata da \param{buf}. Occorre avere il
+  permesso di lettura sulla coda.
+\item[\constd{IPC\_RMID}] Rimuove la coda, cancellando tutti i dati, con
   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
-  con user-ID effettivo corrispondente al creatore o al proprietario della
+  il medesimo errore. Questo comando può essere eseguito solo da un processo
+  con \ids{UID} effettivo corrispondente al creatore o al proprietario della
   coda, o all'amministratore.
-\item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
+\item[\constd{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in
   essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una
-  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
-  incrementarne il valore a limiti superiori a \const{MSGMNB}.
+  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 e lo stesso vale per \var{msg\_qbytes}. Infine solo
+  l'amministratore (più precisamente un processo con la capacità
+  \const{CAP\_IPC\_RESOURCE}) ha la facoltà di incrementarne il valore a
+  limiti superiori a \const{MSGMNB}. Se eseguita con successo la funzione
+  aggiorna anche il campo \var{msg\_ctime}.
 \end{basedescript}
 
+A questi tre valori, che sono quelli previsti dallo standard, su Linux se ne
+affiancano altri tre (\constd{IPC\_INFO}, \constd{MSG\_STAT} e
+\constd{MSG\_INFO}) introdotti ad uso del programma \cmd{ipcs} per ottenere le
+informazioni generali relative alle risorse usate dalle code di
+messaggi. Questi potranno essere modificati o rimossi in favore dell'uso di
+\texttt{/proc}, per cui non devono essere usati e non li tratteremo.
 
 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} 
-  \headdecl{sys/msg.h} 
-  
-  \funcdecl{int msgsnd(int msqid, struct msgbuf *msgp, size\_t msgsz, int
-    msgflg)} 
+messaggio su una coda si utilizza la funzione di sistema \funcd{msgsnd}, il
+cui prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/msg.h}
+\fdecl{int msgsnd(int msqid, struct msgbuf *msgp, size\_t msgsz, int msgflg)}
+\fdesc{Invia un messaggio su una coda.}
+}
 
-  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:
+{La funzione ritorna $0$ in caso di successo e $-1$ per un 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 è
-  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
+  \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{EIDRM}] la coda è stata cancellata.
+  \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}.
-}
-\end{functions}
+  ed inoltre \errval{EFAULT}, \errval{EINTR} e \errval{ENOMEM} nel loro
+  significato generico.}
+\end{funcproto}
 
 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 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
-\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
-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
-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
-consideriamo il caso dell'esempio in fig.~\ref{fig:ipc_msbuf}, \param{msgsz}
-dovrà essere pari a \const{LENGTH}).
-
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.8\textwidth}
     \includestruct{listati/msgbuf.h}
   \end{minipage} 
   \normalsize 
@@ -1385,28 +1512,50 @@ dovr
   \label{fig:ipc_msbuf}
 \end{figure}
 
+La struttura di fig.~\ref{fig:ipc_msbuf} è comunque solo un modello, tanto che
+la definizione contenuta in \headfile{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 \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
+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
+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
+consideriamo il caso dell'esempio in fig.~\ref{fig:ipc_msbuf}, \param{msgsz}
+dovrà essere pari a \var{LENGTH}).
+
 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
-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
-all'indirizzo specificato da \var{msg\_spot}.
+fig.~\ref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo
+messaggio sarà aggiunto in fondo alla lista inserendo una nuova struttura
+\kstruct{msg}, il puntatore \var{msg\_last} di \kstruct{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 all'indirizzo specificato da \var{msg\_spot}.
 
 Il valore dell'argomento \param{flag} permette di specificare il comportamento
 della funzione. Di norma, quando si specifica un valore nullo, la funzione
 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
-di \errcode{EAGAIN}.
+caso si blocca.  Se si specifica per \param{flag} il valore
+\constd{IPC\_NOWAIT} la funzione opera in 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}).
@@ -1415,124 +1564,121 @@ Una volta completato con successo l'invio del messaggio sulla coda, la
 funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare
 vengono modificati:
 \begin{itemize*}
-\item Il valore di \var{msg\_lspid}, che viene impostato al \acr{pid} del
+\item Il valore di \var{msg\_lspid}, che viene impostato al \ids{PID} del
   processo chiamante.
 \item Il valore di \var{msg\_qnum}, che viene incrementato di uno.
 \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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/msg.h} 
+La funzione di sistema che viene utilizzata per estrarre un messaggio da una
+coda è \funcd{msgrcv}, ed il suo prototipo è:
 
-  \funcdecl{ssize\_t msgrcv(int msqid, struct msgbuf *msgp, size\_t msgsz,
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h} 
+\fhead{sys/msg.h}
+\fdecl{ssize\_t msgrcv(int msqid, struct msgbuf *msgp, size\_t msgsz,
     long msgtyp, int msgflg)}
-  
-  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
-    dei valori:
+\fdesc{Legge un messaggio da una coda.} 
+}
+
+{La funzione ritorna il numero di byte letti in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
+  \item[\errcode{E2BIG}] il testo del messaggio è più lungo di \param{msgsz} e
+    non si è specificato \const{MSG\_NOERROR} in \param{msgflg}.
   \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{EIDRM}] la coda è stata cancellata.
+  \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}.
-}
-\end{functions}
+  ed inoltre \errval{EFAULT} nel suo significato generico.}
+\end{funcproto}
 
-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
-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}).
+La funzione legge un messaggio dalla coda specificata da \param{msqid},
+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 dalla coda.  L'argomento \param{msgsz} indica la
+lunghezza massima del testo del messaggio (equivalente al valore del parametro
+\var{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
-\const{MSG\_NOERROR}, il messaggio viene troncato e la parte in eccesso viene
+rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
+\constd{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:
-\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
+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
   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}
+\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: \constd{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
-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
-\var{errno} impostata a \errcode{EIDRM}) o se il processo viene interrotto da
-un segnale (con \var{errno} impostata a \errcode{EINTR}).
+disponibili per la lettura, è di bloccare il processo. 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 \var{errno} impostata a \errcode{EIDRM}) o se
+il processo viene interrotto da un segnale (con \var{errno} impostata a
+\errcode{EINTR}).
 
 Una volta completata con successo l'estrazione del messaggio dalla coda, la
 funzione aggiorna i dati mantenuti in \struct{msqid\_ds}, in particolare
 vengono modificati:
 \begin{itemize*}
-\item Il valore di \var{msg\_lrpid}, che viene impostato al \acr{pid} del
+\item Il valore di \var{msg\_lrpid}, che viene impostato al \ids{PID} del
   processo chiamante.
 \item Il valore di \var{msg\_qnum}, che viene decrementato di uno.
 \item Il valore \var{msg\_rtime}, che viene impostato al tempo corrente.
 \end{itemize*}
 
 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
-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
-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
+\textit{SysV-IPC} che essendo questi permanenti restano nel sistema occupando
+risorse anche quando un processo è terminato, al contrario delle \textit{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 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 è che 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 \itindex{polling} \textit{polling} che esegua un ciclo di attesa su
-ciascuna di esse.
+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} che esegua un ciclo di attesa su ciascuna di esse.
 
 Come esempio dell'uso delle code di messaggi possiamo riscrivere il nostro
-server di \textit{fortunes} usando queste al posto delle fifo. In questo caso
-useremo una sola coda di messaggi, usando il tipo di messaggio per comunicare
-in maniera indipendente con client diversi.
+server di \textit{fortunes} usando queste al posto delle \textit{fifo}. In
+questo caso useremo una sola coda di messaggi, usando il tipo di messaggio per
+comunicare in maniera indipendente con client diversi.
 
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/MQFortuneServer.c}
   \end{minipage} 
   \normalsize 
@@ -1541,30 +1687,30 @@ 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ò
-non essere sequenziale, proprio grazie alla classificazione dei messaggi sulla
-base del loro tipo.
+usando il \ids{PID} di questi ultimi come identificativo. Questo è possibile
+in quanto, al contrario di una \textit{fifo}, la lettura di una coda di
+messaggi può non essere sequenziale, proprio grazie alla classificazione dei
+messaggi sulla base del loro tipo.
 
 Il programma, oltre alle solite variabili per il nome del file da cui leggere
 le \textit{fortunes} e per il vettore di stringhe che contiene le frasi,
 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
-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
-(\texttt{\small 23}) vengono lette nel vettore in memoria con la stessa
-funzione \code{FortuneParse} usata anche per il server basato sulle fifo.
+\var{msgbuf\_read} vengono passate (\texttt{\small 8-11}) le richieste mentre
+con \var{msgbuf\_write} vengono restituite (\texttt{\small 12-15}) le frasi.
+
+La gestione delle opzioni si è al solito omessa, essa si curerà di impostare
+nella variabile \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 vengono
+lette (\texttt{\small 23}) nel vettore in memoria con la stessa funzione
+\code{FortuneParse} usata anche per il server basato sulle \textit{fifo}.
 
 Una volta inizializzato il vettore di stringhe coi messaggi presi dal file
 delle \textit{fortune} si procede (\texttt{\small 25}) con la generazione di
@@ -1572,20 +1718,20 @@ una chiave per identificare la coda di messaggi (si usa il nome del file dei
 sorgenti del server) con la quale poi si esegue (\texttt{\small 26}) la
 creazione della stessa (si noti come si sia chiamata \func{msgget} con un
 valore opportuno per l'argomento \param{flag}), avendo cura di abortire il
-programma (\texttt{\small 27--29}) in caso di errore.
+programma (\texttt{\small 27-29}) in caso di errore.
 
 Finita la fase di inizializzazione il server prima (\texttt{\small 32}) chiama
 la funzione \func{daemon} per andare in background e poi esegue in permanenza
-il ciclo principale (\texttt{\small 33--40}). Questo inizia (\texttt{\small
+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
-richiesta sono di dimensione fissa (e contengono solo il \acr{pid} del
+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 \ids{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 \ids{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
@@ -1594,19 +1740,19 @@ 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.
+al valore del \ids{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.
 
-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}).
 
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/MQFortuneClient.c}
   \end{minipage} 
   \normalsize 
@@ -1615,46 +1761,47 @@ 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
-messaggio di richiesta (\texttt{\small 12--13}) in \var{msg\_read}, usando 1
-per il tipo ed inserendo il proprio \acr{pid} come dato da passare al server.
-Calcolata (\texttt{\small 14}) la dimensione, provvede (\texttt{\small 15}) ad
-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
-messaggio ricevuto.
+Una volta acquisito l'identificatore della coda il client compone
+(\texttt{\small 12-13}) il messaggio di richiesta in \var{msg\_read}, usando
+1 per il tipo ed inserendo il proprio \ids{PID} come dato da passare al
+server.  Calcolata (\texttt{\small 14}) la dimensione, provvede
+(\texttt{\small 15}) ad immettere la richiesta sulla coda.
+
+A questo punto non resta che rileggere la risposta (\texttt{\small 16}) dalla
+coda del server richiedendo a \func{msgrcv} di selezionare i messaggi di tipo
+corrispondente al valore del \ids{PID} inviato nella richiesta. L'ultimo 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\_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}%$
+\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 \textit{fifo}, potremo far partire il server con:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mqfortuned -n10}
+\end{Console}
+%$
 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
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
@@ -1665,137 +1812,140 @@ key        semid      owner      perms      nsems
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
 0x0102dc6a 0          piccardi   666        0            0           
-\end{verbatim}
+\end{Console}
+%$
 a questo punto potremo usare il client per ottenere le nostre frasi:
-\begin{verbatim}
-[piccardi@gont sources]$ ./mqfortune
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./mqfortune}
 Linux ext2fs has been stable for a long time, now it's time to break it
-        -- Linuxkongreß '95 in Berlin
-[piccardi@gont sources]$ ./mqfortune
+        -- Linuxkongreß '95 in Berlin
+[piccardi@gont sources]$ \textbf{./mqfortune}
 Let's call it an accidental feature.
         --Larry Wall
-\end{verbatim}
+\end{Console} 
 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
-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 \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.
-
-
-
-\subsection{Semafori}
+  mqfortuned}, verificando che effettivamente la coda di messaggi venga
+rimossa.
+
+Benché funzionante questa architettura risente dello stesso inconveniente
+visto anche nel caso del precedente server basato sulle \textit{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
+\textit{fifo} si aveva il problema delle \textit{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
+\textit{inode} di un filesystem, sia perché, con il riutilizzo dei \ids{PID}
+da parte dei processi, un client eseguito in un momento successivo potrebbe
+ricevere un messaggio non indirizzato a lui.
+
+
+\subsection{I semafori}
 \label{sec:ipc_sysv_sem}
 
-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 \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
-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à
-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
-alla risorsa, incremento del semaforo).
+I semafori non sono propriamente meccanismi di intercomunicazione come
+\textit{pipe}, \textit{fifo} e code di messaggi, poiché non consentono di
+scambiare dati fra processi, ma servono piuttosto come meccanismi di
+sincronizzazione o di protezione per le \textsl{sezioni critiche} del codice
+(si ricordi quanto detto in sez.~\ref{sec:proc_race_cond}).  Un semaforo
+infatti non è altro che un contatore mantenuto nel kernel che determina se
+consentire o meno la prosecuzione dell'esecuzione di un programma. In questo
+modo si può controllare l'accesso ad una risorsa condivisa da più processi,
+associandovi un semaforo che assicuri che non possa essere usata da più di un
+processo alla volta.
+
+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 condivisa 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 la risorsa viene
+considerata non disponibile, ed il processo si bloccherà fin quando chi la sta
+utilizzando non la rilascerà, incrementando il valore del semaforo. Non appena
+il semaforo diventa positivo, indicando che la risorsa è tornata disponibile,
+il processo bloccato in attesa riprenderà l'esecuzione, e 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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semget(key\_t key, int nsems, int flag)}
-  
-  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:
-    \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
-      (\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
-      maggiore del limite sul numero di semafori per ciascun insieme
-      (\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
-      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 è
+Il sistema di intercomunicazione di \textit{SysV-IPC} prevede anche una
+implementazione dei semafori, ma gli oggetti utilizzati sono tuttavia non
+semafori singoli, ma gruppi (più propriamente \textsl{insiemi}) di semafori
+detti ``\textit{semaphore set}''. La funzione di sistema che permette di
+creare o ottenere l'identificatore di un insieme di semafori è \funcd{semget},
+ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semget(key\_t key, int nsems, int flag)}
+\fdesc{Restituisce l'identificatore di un insieme di semafori.} 
+}
+
+{La funzione ritorna l'identificatore (un intero positivo) in caso di successo
+  e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{ENOSPC}] si è superato il limite di sistema per il numero
+    totale di semafori (\const{SEMMNS}) o di insiemi (\const{SEMMNI}).
+  \item[\errcode{EINVAL}] \param{nsems} è minore di zero o maggiore del limite
+    sul numero di semafori di un insieme (\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
+    contenere le strutture per un nuovo insieme di semafori.
+  \end{errlist}
+  ed inoltre \errval{EACCES}, \errval{EEXIST}, \errval{EIDRM} e
+  \errval{ENOENT} con lo stesso significato che hanno per \func{msgget}.}
+\end{funcproto}
+
+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 dell'interfaccia, il problema è che i semafori forniti
+dal \textit{SysV-IPC} soffrono di altri due difetti progettuali molto più
+gravi.
 
-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. Eventuali
+accessi che possono avvenire fra la creazione e l'inizializzazione potranno
+avere effetti imprevisti.
 
 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
-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
-diventa necessario indicare esplicitamente che si vuole il ripristino del
-semaforo all'uscita del processo.
+\textit{SysV-IPC} di essere risorse globali di sistema, che non vengono
+cancellate quando nessuno le usa più. In questo caso il problema è più grave
+perché ci si 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 diventa necessario indicare
+esplicitamente che si vuole il ripristino del semaforo all'uscita del
+processo, e la gestione diventa più complicata.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/semid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1804,40 +1954,28 @@ semaforo all'uscita del processo.
   \label{fig:ipc_semid_ds}
 \end{figure}
 
-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
-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
+A ciascun insieme di semafori è associata una struttura \struct{semid\_ds},
+riportata in fig.~\ref{fig:ipc_semid_ds}.\footnote{anche in questo caso in
+  realtà il kernel usa una sua specifica struttura interna, ma i dati
+  significativi sono sempre quelli citati.}  Come nel 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}, che
+esprime i permessi di accesso, 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
   nell'insieme, viene inizializzato al valore di \param{nsems}.
-\item il campo \var{sem\_ctime}, che esprime il tempo di creazione
+\item il campo \var{sem\_ctime}, che esprime il tempo di ultimo cambiamento
   dell'insieme, viene inizializzato al tempo corrente.
 \item il campo \var{sem\_otime}, che esprime il tempo dell'ultima operazione
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
-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
-  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
-specificati possono essere letti in maniera indiretta, attraverso l'uso delle
-funzioni di controllo.
-
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
@@ -1846,16 +1984,33 @@ funzioni di controllo.
   \label{fig:ipc_sem}
 \end{figure}
 
-I dati mantenuti nella struttura, ed elencati in fig.~\ref{fig:ipc_sem},
-indicano rispettivamente:
-\begin{description*}
+Ciascun semaforo dell'insieme è realizzato come una struttura di tipo
+\struct{sem} che ne contiene i dati essenziali, la cui definizione è riportata
+in fig.~\ref{fig:ipc_sem}.\footnote{in realtà in fig~\ref{fig:ipc_sem} si è
+  riportata la definizione originaria del kernel 1.0, che contiene la prima
+  realizzazione del \textit{SysV-IPC} in Linux; ormai questa struttura è
+  ridotta ai soli due primi membri, e gli altri vengono calcolati
+  dinamicamente, la si è usata solo a scopo di esempio, perché indica tutti i
+  valori associati ad un semaforo, restituiti dalle funzioni di controllo, e
+  citati dalle pagine di manuale.}  Questa struttura non è accessibile
+direttamente dallo \textit{user space}, ma i valori in essa specificati
+possono essere letti in maniera indiretta, attraverso l'uso delle opportune
+funzioni di controllo.  I dati mantenuti nella struttura, ed elencati in
+fig.~\ref{fig:ipc_sem}, indicano rispettivamente:
+\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
 \item[\var{semval}] il valore numerico del semaforo.
-\item[\var{sempid}] il \acr{pid} dell'ultimo processo che ha eseguito una
+\item[\var{sempid}] il \ids{PID} dell'ultimo processo che ha eseguito una
   operazione sul semaforo.
 \item[\var{semncnt}] il numero di processi in attesa che esso venga
   incrementato.
 \item[\var{semzcnt}] il numero di processi in attesa che esso si annulli.
-\end{description*}
+\end{basedescript}
+
+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 \sysctlfile{kernel/sem}.
 
 \begin{table}[htb]
   \footnotesize
@@ -1865,17 +2020,17 @@ indicano rispettivamente:
     \textbf{Costante} & \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \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.\\
-    \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
-                                   all'uscita. \\
+    \constd{SEMMNI}&          128 & Numero massimo di insiemi di semafori.\\
+    \constd{SEMMSL}&          250 & Numero massimo di semafori per insieme.\\
+    \constd{SEMMNS}&\const{SEMMNI}*\const{SEMMSL}& Numero massimo di semafori
+                                                   nel sistema.\\
+    \constd{SEMVMX}&        32767 & Massimo valore per un semaforo.\\
+    \constd{SEMOPM}&           32 & Massimo numero di operazioni per chiamata a
+                                    \func{semop}. \\
+    \constd{SEMMNU}&\const{SEMMNS}& Massimo numero di strutture di ripristino.\\
+    \constd{SEMUME}&\const{SEMOPM}& Massimo numero di voci di ripristino.\\
+    \constd{SEMAEM}&\const{SEMVMX}& Valore massimo per l'aggiustamento
+                                    all'uscita. \\
     \hline
   \end{tabular}
   \caption{Valori delle costanti associate ai limiti degli insiemi di
@@ -1883,122 +2038,132 @@ indicano rispettivamente:
   \label{tab:ipc_sem_limits}
 \end{table}
 
-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 \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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semctl(int semid, int semnum, int cmd)}
-  \funcdecl{int semctl(int semid, int semnum, int cmd, union semun arg)}
-  
-  Esegue le operazioni di controllo su un semaforo o un insieme di semafori.
-  
-  \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
-    valori:
-    \begin{errlist}
-    \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}
-      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
-      di \const{SEMVMX}.
-  \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}.
+
+La funzione di sistema 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 è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semctl(int semid, int semnum, int cmd)}
+\fdecl{int semctl(int semid, int semnum, int cmd, union semun arg)}
+\fdesc{Esegue le operazioni di controllo su un semaforo o un insieme di
+  semafori.}
 }
-\end{functions}
 
-La funzione può avere tre o quattro argomenti, a seconda dell'operazione
+{La funzione ritorna in caso di successo un valore positivo quanto usata con
+  tre argomenti ed un valore nullo quando usata con quattro e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] i permessi assegnati al semaforo non consentono
+    l'operazione di lettura o scrittura richiesta e non si hanno i privilegi
+    di amministratore.
+    \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 è né il creatore né il proprietario del semaforo e
+      non ha i privilegi di amministratore.
+    \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} nel loro significato
+   generico.}
+\end{funcproto}
+
+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}. 
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
-  \caption{La definizione dei possibili valori di una \direct{union}
+  \caption{La definizione dei possibili valori di una \dirct{union}
     \structd{semun}, usata come quarto argomento della funzione
     \func{semctl}.}
   \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
-unificare l'argomento esso deve essere passato come una \struct{semun}, la cui
-definizione, con i possibili valori che può assumere, è riportata in
-fig.~\ref{fig:ipc_semun}.
+Qualora la funzione operi con quattro argomenti \param{arg} è un argomento
+generico, che conterrà un dato diverso a seconda dell'azione richiesta; per
+unificare detto argomento esso deve essere passato come una unione
+\struct{semun}, la cui 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
+Nelle versioni più vecchie delle \acr{glibc} questa unione veniva definita in
+\file{sys/sem.h}, ma nelle versioni più recenti questo non avviene più in
+quanto lo standard POSIX.1-2001 richiede che sia sempre definita a cura del
+chiamante. In questa seconda evenienza le \acr{glibc} definiscono però la
+macro \macrod{\_SEM\_SEMUN\_UNDEFINED} che può essere usata per controllare la
+situazione.
+
+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
-seguenti:
-\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
-\item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiando il
-  contenuto della relativa struttura \struct{semid\_ds} all'indirizzo
-  specificato con \var{arg.buf}. Occorre avere il permesso di lettura.
+\param{cmd}, che specifica l'azione da intraprendere. Per questo argomento i
+valori validi, quelli cioè che non causano un errore di \errcode{EINVAL}, sono
+seguenti:
+\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}}
+\item[\const{IPC\_STAT}] Legge i dati dell'insieme di semafori, copiandone i
+  valori nella struttura \struct{semid\_ds} posta all'indirizzo specificato
+  con \var{arg.buf}. Occorre avere il permesso di lettura.
   L'argomento \param{semnum} viene ignorato.
 \item[\const{IPC\_RMID}] Rimuove l'insieme di semafori e le relative strutture
-  dati, con effetto immediato. Tutti i processi che erano stato di
-  \textit{sleep} vengono svegliati, ritornando con un errore di
-  \errcode{EIDRM}.  L'user-ID effettivo del processo deve corrispondere o al
-  creatore o al proprietario dell'insieme, o all'amministratore. L'argomento
+  dati, con effetto immediato. Tutti i processi che erano bloccati in attesa
+  vengono svegliati, ritornando con un errore di \errcode{EIDRM}.  L'\ids{UID}
+  effettivo del processo deve corrispondere o al creatore o al proprietario
+  dell'insieme, o all'amministratore. L'argomento
   \param{semnum} viene ignorato.
 \item[\const{IPC\_SET}] Permette di modificare i permessi ed il proprietario
   dell'insieme. I valori devono essere passati in una struttura
-  \struct{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto i
-  campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno
-  significativi di \var{sem\_perm.mode}. L'user-ID effettivo del processo deve
-  corrispondere o al creatore o al proprietario dell'insieme, o
-  all'amministratore.  L'argomento \param{semnum} viene ignorato.
-\item[\const{GETALL}] Restituisce il valore corrente di ciascun semaforo
+  \struct{semid\_ds} puntata da \param{arg.buf} di cui saranno usati soltanto
+  i campi \var{sem\_perm.uid}, \var{sem\_perm.gid} e i nove bit meno
+  significativi di \var{sem\_perm.mode}. La funziona aggiorna anche il campo
+  \var{sem\_ctime}.  L'\ids{UID} effettivo del processo deve corrispondere o
+  al creatore o al proprietario dell'insieme, o all'amministratore.
+  L'argomento \param{semnum} viene ignorato.
+\item[\constd{GETALL}] Restituisce il valore corrente di ciascun semaforo
   dell'insieme (corrispondente al campo \var{semval} di \struct{sem}) nel
   vettore indicato da \param{arg.array}. Occorre avere il permesso di lettura.
   L'argomento \param{semnum} viene ignorato.
-\item[\const{GETNCNT}] Restituisce come valore di ritorno della funzione il
+\item[\constd{GETNCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il semaforo \param{semnum} dell'insieme
   \param{semid} venga incrementato (corrispondente al campo \var{semncnt} di
-  \struct{sem}); va invocata con tre argomenti.  Occorre avere il permesso di
+  \struct{sem}). Va invocata con tre argomenti.  Occorre avere il permesso di
   lettura.
-\item[\const{GETPID}] Restituisce come valore di ritorno della funzione il
-  \acr{pid} dell'ultimo processo che ha compiuto una operazione sul semaforo
+\item[\constd{GETPID}] Restituisce come valore di ritorno della funzione il
+  \ids{PID} dell'ultimo processo che ha compiuto una operazione sul semaforo
   \param{semnum} dell'insieme \param{semid} (corrispondente al campo
-  \var{sempid} di \struct{sem}); va invocata con tre argomenti.  Occorre avere
+  \var{sempid} di \struct{sem}). Va invocata con tre argomenti.  Occorre avere
   il permesso di lettura.
-\item[\const{GETVAL}] Restituisce come valore di ritorno della funzione il il
+\item[\constd{GETVAL}] Restituisce come valore di ritorno della funzione il il
   valore corrente del semaforo \param{semnum} dell'insieme \param{semid}
-  (corrispondente al campo \var{semval} di \struct{sem}); va invocata con tre
+  (corrispondente al campo \var{semval} di \struct{sem}). Va invocata con tre
   argomenti.  Occorre avere il permesso di lettura.
-\item[\const{GETZCNT}] Restituisce come valore di ritorno della funzione il
+\item[\constd{GETZCNT}] Restituisce come valore di ritorno della funzione il
   numero di processi in attesa che il valore del semaforo \param{semnum}
   dell'insieme \param{semid} diventi nullo (corrispondente al campo
-  \var{semncnt} di \struct{sem}); va invocata con tre argomenti.  Occorre avere
-  il permesso di lettura.
-\item[\const{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
+  \var{semncnt} di \struct{sem}). Va invocata con tre argomenti.  Occorre
+  avere il permesso di lettura.
+\item[\constd{SETALL}] Inizializza il valore di tutti i semafori dell'insieme,
   aggiornando il campo \var{sem\_ctime} di \struct{semid\_ds}. I valori devono
   essere passati nel vettore indicato da \param{arg.array}.  Si devono avere i
-  privilegi di scrittura sul semaforo.  L'argomento \param{semnum} viene
-  ignorato.
-\item[\const{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato
+  privilegi di scrittura.  L'argomento \param{semnum} viene ignorato.
+\item[\constd{SETVAL}] Inizializza il semaforo \param{semnum} al valore passato
   dall'argomento \param{arg.val}, aggiornando il campo \var{sem\_ctime} di
-  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura sul semaforo.
+  \struct{semid\_ds}.  Si devono avere i privilegi di scrittura.
 \end{basedescript}
 
+Come per \func{msgctl} esistono tre ulteriori valori, \const{IPC\_INFO},
+\constd{SEM\_STAT} e \constd{SEM\_INFO}, specifici di Linux e fuori da ogni
+standard, creati specificamente ad uso del comando \cmd{ipcs}. Dato che anche
+questi potranno essere modificati o rimossi, non devono essere utilizzati e
+pertanto non li tratteremo.
+
 Quando si imposta il valore di un semaforo (sia che lo si faccia per tutto
 l'insieme con \const{SETALL}, che per un solo semaforo con \const{SETVAL}), i
 processi in attesa su di esso reagiscono di conseguenza al cambiamento di
@@ -2025,55 +2190,99 @@ 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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/sem.h} 
-  
-  \funcdecl{int semop(int semid, struct sembuf *sops, unsigned nsops)}
-  
-  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:
-    \begin{errlist}
-    \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
-      non ha le risorse per allocare la struttura di ripristino.
+vengono effettuate con la funzione di sistema \funcd{semop}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semop(int semid, struct sembuf *sops, unsigned nsops)}
+\fdesc{Esegue operazioni ordinarie su un semaforo o un insieme di semafori.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+    \item[\errcode{E2BIG}] l'argomento \param{nsops} è maggiore del numero
+      massimo di operazioni \const{SEMOPM}.
+    \item[\errcode{EACCES}] il processo non ha i permessi per eseguire
+      l'operazione richiesta e non ha i privilegi di amministratore.
     \item[\errcode{EAGAIN}] un'operazione comporterebbe il blocco del processo,
-      ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
+      ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg}.
+    \item[\errcode{EFBIG}] il valore del campo \var{sem\_num} è negativo o
+      maggiore o uguale al numero di semafori dell'insieme.
+    \item[\errcode{EIDRM}] l'insieme di semafori è stato cancellato.
     \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
-      massimo di operazioni \const{SEMOPM}.
+    \item[\errcode{ENOMEM}] si è richiesto un \const{SEM\_UNDO} ma il sistema
+      non ha le risorse per allocare la struttura di ripristino.
     \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}.
-}
-\end{functions}
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
+  generico.}
+\end{funcproto}
 
 La funzione permette di eseguire operazioni multiple sui singoli semafori di
 un insieme. La funzione richiede come primo argomento l'identificatore
-\param{semid} dell'insieme su cui si vuole operare. Il numero di operazioni da
+\param{semid} dell'insieme su cui si vuole operare, il numero di operazioni da
 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,
+ed in tal caso vengono eseguite nella sequenza passata nel
+vettore \param{sops}.
+
+Con lo standard POSIX.1-2001 è stata introdotta una variante di \func{semop}
+che consente di specificare anche un tempo massimo di attesa. La nuova
+funzione di sistema, disponibile a partire dal kernel 2.4.22 e dalle
+\acr{glibc} 2.3.3, ed utilizzabile solo dopo aver definito la macro
+\macro{\_GNU\_SOURCE}, è \funcd{semtimedop}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/sem.h}
+\fdecl{int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
+                      struct timespec *timeout)}
+\fdesc{Esegue operazioni ordinarie su un semaforo o un insieme di semafori.} 
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori: 
+  \begin{errlist}
+  \item[\errcode{EAGAIN}] l'operazione comporterebbe il blocco del processo,
+    ma si è specificato \const{IPC\_NOWAIT} in \var{sem\_flg} oppure si è
+    atteso oltre quanto indicato da \param{timeout}.
+  \end{errlist}
+  e gli altri valori già visti per \func{semop}, con lo stesso significato.}
+\end{funcproto}
+
+Rispetto a \func{semop} la funzione consente di specificare un tempo massimo
+di attesa, indicato con una struttura \struct{timespec} (vedi
+fig.~\ref{fig:sys_timespec_struct}), per le operazioni che verrebbero
+bloccate. Alla scadenza di detto tempo la funzione ritorna comunque con un
+errore di \errval{EAGAIN} senza che nessuna delle operazioni richieste venga
+eseguita. 
+
+Si tenga presente che la precisione della temporizzazione è comunque limitata
+dalla risoluzione dell'orologio di sistema, per cui il tempo di attesa verrà
+arrotondato per eccesso. In caso si passi un valore \val{NULL}
+per \param{timeout} il comportamento di \func{semtimedop} è identico a quello
+di \func{semop}.
+
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sembuf.h}
   \end{minipage} 
   \normalsize 
@@ -2082,65 +2291,73 @@ effettivamente eseguite se e soltanto se 
   \label{fig:ipc_sembuf}
 \end{figure}
 
-Il contenuto di ciascuna operazione deve essere specificato attraverso una
-opportuna struttura \struct{sembuf} (la cui definizione è riportata in
+Come indicato il contenuto di ciascuna operazione deve essere specificato
+attraverso una 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.
+semaforo su cui operare, il tipo di operazione, ed un flag di controllo.  
+
 Il campo \var{sem\_num} serve per indicare a quale semaforo dell'insieme fa
-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}.
+riferimento l'operazione. Si ricordi che i semafori sono numerati come gli
+elementi di un vettore, per cui il primo semaforo di un insieme 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
-che il processo vada in stato di \textit{sleep}), \func{semop} ritorni
-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
-e determina il comportamento della chiamata a \func{semop}; tre sono i casi
-possibili:
-\begin{basedescript}{\desclabelwidth{2.0cm}}
-\item[\var{sem\_op}$>0$] In questo caso il valore di \var{sem\_op} viene
-  aggiunto al valore corrente di \var{semval}. La funzione ritorna
-  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
-  alterazione (scrittura) sull'insieme di semafori.
+\constd{SEM\_UNDO}.  Impostando \const{IPC\_NOWAIT} si fa si che in tutti quei
+casi in cui l'esecuzione di una operazione richiederebbe di porre il processo
+vada nello stato di \textit{sleep}, invece di bloccarsi \func{semop} ritorni
+immediatamente (abortendo così le eventuali operazioni restanti) con un errore
+di \errcode{EAGAIN}.  Impostando \const{SEM\_UNDO} si richiede invece che
+l'operazione in questione venga registrata, in modo che il valore del semaforo
+possa essere ripristinato all'uscita del processo.
+
+Infine \var{sem\_op} è il campo che controlla qual'è l'operazione che viene
+eseguita e determina in generale il comportamento della chiamata a
+\func{semop}. I casi possibili per il valore di questo campo sono tre:
+\begin{basedescript}{\desclabelwidth{1.8cm}}
+\item[\var{sem\_op} $>0$] In questo caso il valore viene aggiunto al valore
+  corrente di \var{semval} per il semaforo indicato. Questa operazione non
+  causa mai un blocco del processo, ed eventualmente \func{semop} ritorna
+  immediatamente con un errore di \errcode{ERANGE} qualora si sia superato il
+  limite \const{SEMVMX}. Se l'operazione ha successo si passa immediatamente
+  alla successiva.  Specificando \const{SEM\_UNDO} si aggiorna il contatore
+  per il ripristino 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
-  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:
+\item[\var{sem\_op} $=0$] Nel caso \var{semval} sia zero l'operazione ha
+  successo immediato, e o si passa alla successiva o \func{semop} ritorna con
+  successo se questa era l'ultima. Se \var{semval} è diverso da zero il
+  comportamento è controllato da \var{sem\_flg}, se è stato impostato
+  \const{IPC\_NOWAIT} \func{semop} ritorna immediatamente abortendo tutte le
+  operazioni con un errore di \errcode{EAGAIN}, altrimenti viene incrementato
+  \var{semzcnt} di uno ed il processo viene bloccato fintanto che non si
+  verifica una delle condizioni seguenti:
   \begin{itemize*}
   \item \var{semval} diventa zero, nel qual caso \var{semzcnt} viene
-    decrementato di uno.
-  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop} ritorna
-    un errore di \errcode{EIDRM}.
+    decrementato di uno, l'operazione ha successo e si passa alla successiva,
+    oppure \func{semop} ritorna con successo se questa era l'ultima.
+  \item l'insieme di semafori viene rimosso, nel qual caso \func{semop}
+    ritorna abortendo tutte le operazioni con un errore di \errcode{EIDRM}.
   \item il processo chiamante riceve un segnale, nel qual caso \var{semzcnt}
-    viene decrementato di uno e \func{semop} ritorna un errore di
-    \errcode{EINTR}.
+    viene decrementato di uno e \func{semop} ritorna abortendo tutte le
+    operazioni con un errore di \errcode{EINTR}.
   \end{itemize*}
-  Al processo chiamante è richiesto il privilegio di lettura dell'insieme dei
-  semafori.
+  Al processo chiamante è richiesto soltanto 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
-  positiva o nulla) i valori vengono sommati e la funzione ritorna
-  immediatamente; qualora si sia impostato \const{SEM\_UNDO} viene anche
+\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 l'operazione ha successo e si
+  passa alla successiva, oppure \func{semop} ritorna con successo se questa
+  era l'ultima. 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
-  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:
+  contrario (quando cioè la somma darebbe luogo ad un valore di \var{semval}
+  negativo) se si è impostato \const{IPC\_NOWAIT} \func{semop} ritorna
+  immediatamente abortendo tutte le operazioni 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:
   \begin{itemize*}
   \item \var{semval} diventa maggiore o uguale del valore assoluto di
     \var{sem\_op}, nel qual caso \var{semncnt} viene decrementato di uno, il
@@ -2148,110 +2365,116 @@ possibili:
     impostato \const{SEM\_UNDO} viene aggiornato il contatore per il
     ripristino del valore del semaforo.
   \item l'insieme di semafori viene rimosso, nel qual caso \func{semop}
-    ritorna un errore di \errcode{EIDRM}.
+    ritorna abortendo tutte le operazioni con un errore di \errcode{EIDRM}.
   \item il processo chiamante riceve un segnale, nel qual caso \var{semncnt}
-    viene decrementato di uno e \func{semop} ritorna un errore di
-    \errcode{EINTR}.
+    viene decrementato di uno e \func{semop} ritorna abortendo tutte le
+    operazioni con 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}
 
-In caso di successo della funzione viene aggiornato il campo \var{sempid} per
-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
-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
-\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
-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ù
-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
-  vecchie versioni delle librerie del C, come le libc5.}
-
-\begin{figure}[htb]
-  \centering \includegraphics[width=13cm]{img/semtruct}
-  \caption{Schema della struttura di un insieme di semafori.}
+Qualora si sia usato \func{semtimedop} alle condizioni di errore precedenti si
+aggiunge anche quella di scadenza del tempo di attesa indicato
+con \param{timeout} che farà abortire la funzione, qualora resti bloccata
+troppo a lungo nell'esecuzione delle operazioni richieste, con un errore di
+\errcode{EAGAIN}.
+
+In caso di successo (sia per \func{semop} che per \func{semtimedop}) per ogni
+semaforo modificato verrà aggiornato il campo \var{sempid} al valore del
+\ids{PID} del processo chiamante; inoltre verranno 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
+semafori possono restare occupati, abbiamo visto come \func{semop} (e
+\func{semtimedop}) permetta di attivare un meccanismo di ripristino attraverso
+l'uso del flag \const{SEM\_UNDO}. Il meccanismo è implementato tramite una
+apposita struttura \kstruct{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 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ù
+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à (in particolare con le vecchie
+versioni delle librerie del C, come le \acr{libc5}).
+
+\begin{figure}[!htb]
+  \centering \includegraphics[width=12cm]{img/semtruct}
+  \caption{Schema delle varie strutture di un insieme di semafori
+    (\kstructd{semid\_ds}, \kstructd{sem}, \kstructd{sem\_queue} e
+    \kstructd{sem\_undo}).}
   \label{fig:ipc_sem_schema}
 \end{figure}
 
 Alla creazione di un nuovo insieme viene allocata una nuova strutture
-\struct{semid\_ds} ed il relativo vettore di strutture \struct{sem}. Quando si
-richiede una operazione viene anzitutto verificato che tutte le operazioni
+\kstruct{semid\_ds} ed il relativo vettore di strutture \kstruct{sem}. Quando
+si richiede una operazione viene anzitutto verificato che tutte le operazioni
 possono avere successo; se una di esse comporta il blocco del processo il
-kernel crea una struttura \struct{sem\_queue} che viene aggiunta in fondo alla
-coda di attesa associata a ciascun insieme di semafori\footnote{che viene
-  referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last}
-  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
-al processo corrente (nel campo \var{sleeper}) poi quest'ultimo viene messo
-stato di attesa e viene invocato lo \itindex{scheduler} scheduler per passare
-all'esecuzione di un altro processo.
+kernel crea una struttura \kstruct{sem\_queue} che viene aggiunta in fondo
+alla coda di attesa associata a ciascun insieme di semafori, che viene
+referenziata tramite i campi \var{sem\_pending} e \var{sem\_pending\_last} di
+\kstruct{semid\_ds}.  Nella struttura viene memorizzato il riferimento alle
+operazioni richieste (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
+\textit{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
-struttura \struct{sem\_queue} viene rimossa e lo stato del processo associato
+operazioni sospese in precedenza può essere eseguita, nel qual caso la
+struttura \kstruct{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 ciascun insieme di semafori una apposita struttura \struct{sem\_undo} che
+per un'operazione si è specificato il flag \const{SEM\_UNDO} viene mantenuta
+per ciascun insieme di semafori una apposita struttura \kstruct{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
 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
-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
-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
-atomicamente.
-
-Il punto è cosa succede quando una delle operazioni previste per il ripristino
-non può essere eseguita immediatamente perché ad esempio il semaforo è
+Queste strutture sono mantenute in due liste (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 operazione con \func{semctl},
+l'altra associata al processo che ha eseguito l'operazione, attraverso il
+campo \var{semundo} di \kstruct{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 ripristino per semafori differenti
+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 atomicamente.
+
+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]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/Mutex.c}
   \end{minipage} 
   \normalsize 
@@ -2260,114 +2483,143 @@ 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},
+(\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
-  11--13}) si restituisce il valore di ritorno di \func{semctl}, altrimenti
+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.
 
-La quarta e la quinta funzione (\texttt{\small 36--44}) sono \func{MutexLock},
+La quarta e la quinta funzione (\texttt{\small 36-44}) sono \func{MutexLock},
 e \func{MutexUnlock}, che permettono rispettivamente di bloccare e sbloccare
 il mutex. Entrambe fanno da wrapper per \func{semop}, utilizzando le due
 strutture \var{sem\_lock} e \var{sem\_unlock} definite in precedenza
-(\texttt{\small 27--34}). Si noti come per queste ultime si sia fatto uso
+(\texttt{\small 27-34}). Si noti come per queste ultime si sia fatto uso
 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 \index{file!locking} \textit{file locking}.
+problemi, usando il \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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/shm.h}
-  
-  \funcdecl{int shmget(key\_t key, int size, int flag)}
-  
-  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:
-    \begin{errlist}
-    \item[\errcode{ENOSPC}] si è superato il limite (\const{SHMMNI}) sul numero
+Il terzo oggetto introdotto dal \textit{SysV-IPC} è quello dei segmenti di
+memoria condivisa. La funzione di sistema che permette di ottenerne uno è
+\funcd{shmget}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h}
+\fhead{sys/ipc.h}
+\fhead{sys/shm.h}
+\fdecl{int shmget(key\_t key, int size, int flag)}
+\fdesc{Ottiene o crea una memoria condivisa.} 
+}
+
+{La funzione ritorna l'identificatore (un intero positivo) in caso di successo
+  e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \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.
+      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
-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,
+    \item[\errcode{ENOMEM}] si è specificato \const{IPC\_HUGETLB} ma non si
+      hanno i privilegi di amministratore.
+   \end{errlist}
+   ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST},
+   \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.}
+\end{funcproto}
+
+
+La funzione, come \func{semget}, è 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}.  A partire dal kernel 2.6
+però sono stati introdotti degli ulteriori bit di controllo per
+l'argomento \param{flag}, specifici di \func{shmget}, attinenti alle modalità
+di gestione del segmento di memoria condivisa in relazione al sistema della
+memoria virtuale.
+
+Il primo dei due flag è \constd{SHM\_HUGETLB} che consente di richiedere la
+creazione del segmento usando una \textit{huge page}, le pagine di memoria di
+grandi dimensioni introdotte con il kernel 2.6 per ottimizzare le prestazioni
+nei sistemi più recenti che hanno grandi quantità di memoria. L'operazione è
+privilegiata e richiede che il processo abbia la \textit{capability}
+\const{CAP\_IPC\_LOCK}. Questa funzionalità è specifica di Linux e non è
+portabile.
+
+Il secondo flag aggiuntivo, introdotto a partire dal kernel 2.6.15, è
+\constd{SHM\_NORESERVE}, ed ha lo stesso scopo del flag \const{MAP\_NORESERVE}
+di \func{mmap} (vedi sez.~\ref{sec:file_memory_map}): non vengono riservate
+delle pagine di swap ad uso del meccanismo del \textit{copy on write} per
+mantenere le modifiche fatte sul segmento. Questo significa che caso di
+scrittura sul segmento quando non c'è più memoria disponibile, si avrà
+l'emissione di un \signal{SIGSEGV}.
+
+Infine l'argomento \param{size} specifica la dimensione del segmento di
+memoria condivisa; il valore deve essere specificato in byte, ma verrà
+comunque arrotondato al multiplo superiore di \const{PAGE\_SIZE}. Il valore
+deve essere specificato quando si crea un nuovo segmento di memoria con
+\const{IPC\_CREAT} o \const{IPC\_PRIVATE}, se invece si accede ad un segmento
+di memoria condivisa esistente non può essere maggiore del valore con cui esso
+è stato creato.
+
+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
@@ -2379,7 +2631,7 @@ norma, significa insieme a dei semafori.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -2388,7 +2640,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
@@ -2396,21 +2648,21 @@ campo \var{shm\_perm} viene inizializzato come illustrato in
 sez.~\ref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
 relativamente ai permessi di accesso; per quanto riguarda gli altri campi
 invece:
-\begin{itemize}
+\begin{itemize*}
 \item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
   inizializzato al valore di \param{size}.
 \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
+\item il campo \var{shm\_lpid}, che esprime il \ids{PID} del processo che ha
   eseguito l'ultima operazione, viene inizializzato a zero.
-\item il campo \var{shm\_cpid}, che esprime il \acr{pid} del processo che ha
-  creato il segmento, viene inizializzato al \acr{pid} del processo chiamante.
+\item il campo \var{shm\_cpid}, che esprime il \ids{PID} del processo che ha
+  creato il segmento, viene inizializzato al \ids{PID} del processo chiamante.
 \item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
   al segmento viene inizializzato a zero.
-\end{itemize}
+\end{itemize*}
 
 Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
 di memoria condivisa esistono una serie di limiti imposti dal sistema.  Alcuni
@@ -2433,25 +2685,27 @@ che permettono di cambiarne il valore.
     & \textbf{Significato} \\
     \hline
     \hline
-    \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
+    \constd{SHMALL}& 0x200000&\sysctlrelfiled{kernel}{shmall}
+                             & Numero massimo di pagine che 
+                               possono essere usate per i segmenti di
+                               memoria condivisa.\\
+    \constd{SHMMAX}&0x2000000&\sysctlrelfiled{kernel}{shmmax} 
+                             & Dimensione massima di un segmento di memoria
+                               condivisa.\\ 
+    \constd{SHMMNI}&     4096&\sysctlrelfiled{kernel}{shmmni}
+                             & Numero massimo di segmenti di memoria condivisa
                               presenti nel kernel.\\ 
-    \const{SHMMIN}&        1& ---         & Dimensione minima di un segmento di
-                                            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).\\
-    \const{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
-                                            memoria condivisa per ciascun
-                                            processo.\\
+    \constd{SHMMIN}&        1& ---         & Dimensione minima di un segmento di
+                                             memoria condivisa.\\
+    \constd{SHMLBA}&\const{PAGE\_SIZE}&--- & Limite inferiore per le dimensioni
+                                             minime di un segmento (deve essere
+                                             allineato alle dimensioni di una
+                                             pagina di memoria).\\
+    \constd{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
+                                             memoria condivisa per ciascun
+                                             processo (l'implementazione non
+                                             prevede l'esistenza di questo
+                                             limite).\\
 
 
     \hline
@@ -2462,167 +2716,197 @@ che permettono di cambiarne il valore.
   \label{tab:ipc_shm_limits}
 \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 è:
-\begin{functions}
-  \headdecl{sys/ipc.h} 
-  \headdecl{sys/shm.h}
-  
-  \funcdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
-  
-  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:
-    \begin{errlist}
-    \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma i permessi non
+Al solito la funzione di sistema che permette di effettuare le operazioni di
+controllo su un segmento di memoria condivisa è \funcd{shmctl}; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/ipc.h}
+\fhead{sys/shm.h}
+\fdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)}
+
+\fdesc{Esegue le operazioni di controllo su un segmento di memoria condivisa.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \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{EFAULT}] l'indirizzo specificato con \param{buf} non è
+      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
+      segmento che è stato cancellato.
+    \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o
+      \param{cmd} non è un comando valido.
+    \item[\errcode{ENOMEM}] si è richiesto un \textit{memory lock} di
+      dimensioni superiori al massimo consentito.
+    \item[\errcode{EOVERFLOW}] si è tentato il comando \const{IPC\_STAT} ma il
+      valore del \ids{GID} o dell'\ids{UID} è troppo grande per essere
       memorizzato nella struttura puntata da \param{buf}.
-    \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è
-      valido.
-    \end{errlist}
-}
-\end{functions}
+    \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o
+      \const{IPC\_RMID} senza i permessi necessari.
+  \end{errlist}
+}  
+\end{funcproto}
 
 Il comando specificato attraverso l'argomento \param{cmd} determina i diversi
-effetti della funzione; i possibili valori che esso può assumere, ed il
-corrispondente comportamento della funzione, sono i seguenti:
+effetti della funzione. Nello standard POSIX.1-2001 i valori che esso può
+assumere, ed il corrispondente comportamento della funzione, sono i seguenti:
 
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria
   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
-  eseguito solo da un processo con user-ID effettivo corrispondente o al
+  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 \ids{UID} 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
   del segmento.  Per modificare i valori di \var{shm\_perm.mode},
   \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 \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 \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
-gli insiemi di semafori, gli ultimi due sono delle estensioni specifiche
-previste da Linux, che permettono di abilitare e disabilitare il meccanismo
-della \index{memoria~virtuale} memoria virtuale per il segmento.
+
+Oltre ai precedenti su Linux sono definiti anche degli ulteriori comandi, che
+consentono di estendere le funzionalità, ovviamente non devono essere usati se
+si ha a cuore la portabilità. Questi comandi aggiuntivi sono:
+
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SHM\_LOCK}] Abilita il \textit{memory locking} sul segmento di
+  memoria condivisa, impedendo che la memoria usata per il segmento venga
+  salvata su disco dal meccanismo della memoria virtuale. Come illustrato in
+  sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore
+  poteva utilizzare questa capacità,\footnote{che richiedeva la
+    \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel
+  2.6.10 anche gli utenti normali possono farlo fino al limite massimo
+  determinato da \const{RLIMIT\_MEMLOCK} (vedi
+  sez.~\ref{sec:sys_resource_limit}).
+\item[\constd{SHM\_UNLOCK}] Disabilita il \textit{memory locking} sul segmento
+  di memoria condivisa.  Fino al kernel 2.6.9 solo l'amministratore poteva
+  utilizzare questo comando in corrispondenza di un segmento da lui bloccato.
+\end{basedescript}
+
+A questi due, come per \func{msgctl} e \func{semctl}, si aggiungono tre
+ulteriori valori, \const{IPC\_INFO}, \constd{SHM\_STAT} e \constd{SHM\_INFO},
+introdotti ad uso del programma \cmd{ipcs} per ottenere le informazioni
+generali relative alle risorse usate dai segmenti di memoria condivisa. Dato
+che potranno essere modificati o rimossi in favore dell'uso di \texttt{/proc},
+non devono essere usati e non li tratteremo.
 
 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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/shm.h}
-  
-  \funcdecl{void *shmat(int shmid, const void *shmaddr, int shmflg)}
-  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
-    valori:
-    \begin{errlist}
+il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/types.h} 
+\fhead{sys/shm.h}
+\fdecl{void *shmat(int shmid, const void *shmaddr, int shmflg)}
+
+\fdesc{Aggancia un segmento di memoria condivisa al processo chiamante.}
+}
+
+{La funzione ritorna l'indirizzo del segmento in caso di successo e $-1$ (in
+  un cast a \ctyp{void *}) per un errore, nel qual caso \var{errno} assumerà
+  uno dei 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
+      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}
-    ed inoltre \errval{ENOMEM}.}
-\end{functions}
+      per \param{shmaddr} o il valore \val{NULL} indicando \const{SHM\_REMAP}.
+  \end{errlist}
+  ed inoltre \errval{ENOMEM} nel suo significato generico.
+}  
+\end{funcproto}
 
 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_alloc}) non viene influenzato.
-Si tenga presente infine che la funzione ha successo anche se il segmento è
+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 è
+\begin{figure}[!htb]
+  \centering \includegraphics[height=10cm]{img/sh_memory_layout}
+  \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
-  \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
-  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).
-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}. 
-
-Si tenga presente però che quando si usa \val{NULL} come valore di
-\param{shmaddr}, l'indirizzo restituito da \func{shmat} può cambiare da
+  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 alla \acr{glibc} il tipo di
+  \param{shmaddr} è divenuto un \ctyp{const void *} e quello del valore di
+  ritorno un \ctyp{void *} seguendo POSIX.1-2001.} 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).  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}.
+
+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).
 
 L'argomento \param{shmflg} permette di cambiare il comportamento della
-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
+funzione; esso va specificato come maschera binaria, i bit utilizzati al
+momento sono sono tre e sono identificati dalle costanti \const{SHM\_RND},
+\const{SHM\_RDONLY} e \const{SHM\_REMAP} che vanno combinate con un OR
+aritmetico.  
+
+Specificando \constd{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
 costante sta infatti per \textit{rounded}, e serve per specificare un
-indirizzo come arrotondamento, in Linux è equivalente a \const{PAGE\_SIZE}).
+indirizzo come arrotondamento.
 
-L'uso di \const{SHM\_RDONLY} permette di agganciare il segmento in sola
+L'uso di \constd{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
-\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}:
+caso un tentativo di scrivere sul segmento comporterà una violazione di
+accesso con l'emissione di un segnale di \signal{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.
+
+Infine \constd{SHM\_REMAP} è una estensione specifica di Linux (quindi non
+portabile) che indica che la mappatura del segmento deve rimpiazzare ogni
+precedente mappatura esistente nell'intervallo iniziante
+all'indirizzo \param{shmaddr} e di dimensione pari alla lunghezza del
+segmento. In condizioni normali questo tipo di richiesta fallirebbe con un
+errore di \errval{EINVAL}. Ovviamente usando \const{SHM\_REMAP}
+l'argomento \param{shmaddr} non può essere nullo.
+
+In caso di successo la funzione \func{shmat} aggiorna anche i seguenti campi
+della struttura \struct{shmid\_ds}:
 \begin{itemize*}
 \item il tempo \var{shm\_atime} dell'ultima operazione di aggancio viene
   impostato al tempo corrente.
-\item il \acr{pid} \var{shm\_lpid} dell'ultimo processo che ha operato sul
+\item il \ids{PID} \var{shm\_lpid} dell'ultimo processo che ha operato sul
   segmento viene impostato a quello del processo corrente.
 \item il numero \var{shm\_nattch} di processi agganciati al segmento viene
   aumentato di uno.
-\end{itemize*} 
+\end{itemize*}
 
 Come accennato in sez.~\ref{sec:proc_fork} un segmento di memoria condivisa
 agganciato ad un processo viene ereditato da un figlio attraverso una
@@ -2633,21 +2917,24 @@ 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 è:
-\begin{functions}
-  \headdecl{sys/types.h} 
-  \headdecl{sys/shm.h}
+dell'interfaccia, \funcd{shmdt}, il cui prototipo è:
 
-  \funcdecl{int shmdt(const void *shmaddr)}
-  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
-    all'indirizzo \param{shmaddr}, con \var{errno} che assume il valore
-    \errval{EINVAL}.}
-\end{functions}
+\begin{funcproto}{
+\fhead{sys/types.h} 
+\fhead{sys/shm.h}
+\fdecl{int shmdt(const void *shmaddr)}
+
+\fdesc{Sgancia dal processo un segmento di memoria condivisa.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un 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{funcproto}
 
 La funzione sgancia dallo spazio degli indirizzi del processo un segmento di
 memoria condivisa; questo viene identificato con l'indirizzo \param{shmaddr}
@@ -2659,7 +2946,7 @@ In caso di successo la funzione aggiorna anche i seguenti campi di
 \begin{itemize*}
 \item il tempo \var{shm\_dtime} dell'ultima operazione di sganciamento viene
   impostato al tempo corrente.
-\item il \acr{pid} \var{shm\_lpid} dell'ultimo processo che ha operato sul
+\item il \ids{PID} \var{shm\_lpid} dell'ultimo processo che ha operato sul
   segmento viene impostato a quello del processo corrente.
 \item il numero \var{shm\_nattch} di processi agganciati al segmento viene
   decrementato di uno.
@@ -2667,9 +2954,9 @@ In caso di successo la funzione aggiorna anche i seguenti campi di
 inoltre la regione di indirizzi usata per il segmento di memoria condivisa
 viene tolta dallo spazio di indirizzi del processo.
 
-\begin{figure}[!bht]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/SharedMem.c}
   \end{minipage} 
   \normalsize 
@@ -2680,59 +2967,59 @@ 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 1-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
 qualora non esista, ed assegnandogli i privilegi specificati dall'argomento
 \var{perm} e la dimensione specificata dall'argomento \var{shm\_size}.  In
-caso di errore (\texttt{\small 7--9}) si ritorna immediatamente un puntatore
+caso di errore (\texttt{\small 7-9}) si ritorna immediatamente un puntatore
 nullo, altrimenti (\texttt{\small 10}) si prosegue agganciando il segmento di
 memoria condivisa al processo con \func{shmat}. In caso di errore
-(\texttt{\small 11--13}) si restituisce di nuovo un puntatore nullo, infine
+(\texttt{\small 11-13}) si restituisce di nuovo un puntatore nullo, infine
 (\texttt{\small 14}) si inizializza con \func{memset} il contenuto del
 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
+\func{shmget}, ritornando (\texttt{\small 23-25}) un puntatore nullo in caso
 di errore. Poi si prosegue (\texttt{\small 26}) agganciando il segmento al
-processo con \func{shmat}, restituendo (\texttt{\small 27--29}) di nuovo un
+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 ottenere l'identificatore
+(\texttt{\small 38-39}) un valore -1 in caso di errore. Il passo successivo
+(\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
+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 è
-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 è
-sequenziale\footnote{come accennato in sez.~\ref{sec:ipc_sysv_mq} per la
+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 \textit{pipe}, le \textit{fifo} o i
+socket, che non necessitano di sincronizzazione esplicita, sono da
+preferire. Essa diventa 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
@@ -2741,22 +3028,22 @@ 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
 video; al solito il codice completo si trova con i sorgenti allegati nel file
 \file{DirMonitor.c}.
 
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/DirMonitor.c}
   \end{minipage} 
   \normalsize 
@@ -2764,125 +3051,128 @@ video; al solito il codice completo si trova con i sorgenti allegati nel file
   \label{fig:ipc_dirmonitor_main}
 \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 è
+Il programma usa delle variabili globali (\texttt{\small 2-14}) per mantenere
+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'argomento 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.
 
 Poi, per verificare che l'argomento specifichi effettivamente una directory,
-si esegue (\texttt{\small 24--26}) su di esso una \func{chdir}, uscendo
+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,
-  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
-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
+controllo, in vista del successivo uso della funzione \func{daemon}. 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 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
 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
+  di GaPiL siano stati installati direttamente in essa; qualora si effettui
+  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
-  32--35}) qualora la creazione ed il successivo agganciamento al processo non
-abbia successo. Con l'indirizzo \var{shmptr} così ottenuto potremo poi
+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
 accedere alla memoria condivisa, che, per come abbiamo lo abbiamo definito,
-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,
+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,
 che utilizzeremo per regolare l'accesso alla memoria condivisa.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
-    \includecodesample{listati/ComputeValues.c}
-  \end{minipage} 
-  \normalsize 
-  \caption{Codice delle funzioni ausiliarie usate da \file{DirMonitor.c}.}
-  \label{fig:ipc_dirmonitor_sub}
-\end{figure}
-
 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
-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
-  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
-  46}) si sblocca il mutex con \func{MutexUnlock}, e si attende
-(\texttt{\small 47}) per il periodo di tempo specificato a riga di comando con
-l'opzione \code{-p} con una \func{sleep}.
+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 all'interno di un ciclo infinito
+(\texttt{\small 42-48}).
+
+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 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 \myfunc{dir\_scan}; infine (\texttt{\small 46}) si
+sblocca il mutex con \func{MutexUnlock}, e si attende (\texttt{\small 47}) per
+il periodo di tempo specificato a riga di comando con l'opzione \code{-p}
+usando 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 \myfunc{dir\_scan}, 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
-a chiamare (\texttt{\small 5}) la funzione \func{stat} sul file indicato da
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \includecodesample{listati/ComputeValues.c}
+  \end{minipage} 
+  \normalsize 
+  \caption{Codice delle funzioni ausiliarie usate da \file{DirMonitor.c}.}
+  \label{fig:ipc_dirmonitor_sub}
+\end{figure}
+
+
+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
-condivisa usando \var{shmptr} per riempire i campi della struttura
-\struct{DirProp}; così prima (\texttt{\small 6--7}) si sommano le dimensioni
+Dato che la funzione è chiamata da \myfunc{dir\_scan}, 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
 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
+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
-(\texttt{\small 17--23}) del gestore dei segnali di terminazione, usato per
+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
 memoria condivisa usando \func{ShmRemove}.  Infine (\texttt{\small 21})
 rimuove il mutex con \func{MutexRemove} ed esce (\texttt{\small 22}).
 
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6 cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \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,27 +3180,28 @@ rigenera (\texttt{\small 7}) con \func{ftok} la stessa chiave usata dal server
 per identificare il segmento di memoria condivisa ed il mutex, poi
 (\texttt{\small 8}) richiede con \func{ShmFind} l'indirizzo della memoria
 condivisa agganciando al contempo il segmento al processo, Infine
-(\texttt{\small 17--20}) con \func{MutexFind} si richiede l'identificatore del
+(\texttt{\small 17-20}) con \func{MutexFind} si richiede l'identificatore del
 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})
+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}
-[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
+\code{LD\_LIBRARY\_PATH}; poi si potrà lanciare il server con:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./dirmonitor ./}
+\end{Console}
+%$
+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}
-[piccardi@gont sources]$ ./readmon 
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./readmon} 
 Ci sono 68 file dati
 Ci sono 3 directory
 Ci sono 0 link
@@ -2919,13 +3210,14 @@ 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{Console}
+%$
 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}
-[piccardi@gont sources]$ ipcs
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
 0xffffffff 54067205   piccardi  666        4096       1                       
@@ -2936,13 +3228,14 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{verbatim}%$
+\end{Console}
+%$
 
 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}
-[piccardi@gont sources]$ ./readmon 
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./readmon} 
 Ci sono 69 file dati
 Ci sono 3 directory
 Ci sono 0 link
@@ -2951,19 +3244,21 @@ 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{Console}
+%$
 
 A questo punto possiamo far uscire il server inviandogli un segnale di
-\const{SIGTERM} con il comando \code{killall dirmonitor}, a questo punto
+\signal{SIGTERM} con il comando \code{killall dirmonitor}, a questo punto
 ripetendo la lettura, otterremo un errore:
-\begin{verbatim}
-[piccardi@gont sources]$ ./readmon 
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./readmon} 
 Cannot find shared memory: No such file or directory
-\end{verbatim}%$
+\end{Console}
+%$
 e inoltre potremo anche verificare che anche gli oggetti di intercomunicazione
 visti in precedenza sono stati regolarmente  cancellati:
-\begin{verbatim}
-[piccardi@gont sources]$ ipcs
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
 
@@ -2972,16 +3267,16 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{verbatim}%$
-
+\end{Console}
+%$
 
 
 %% 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]
+%% \begin{figure}[!htb]
 %%   \centering
 %%   \includegraphics[width=10cm]{img/shmstruct}
 %%    \caption{Schema dell'implementazione dei segmenti di memoria condivisa in
@@ -2996,10 +3291,10 @@ key        msqid      owner      perms      used-bytes   messages
 \label{sec:ipc_alternatives}
 
 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}
+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.
 
 
@@ -3007,61 +3302,68 @@ alternative, che vogliamo riprendere in questa sezione.
 \label{sec:ipc_mq_alternative}
  
 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
-incorrere nelle complicazioni introdotte dal \textit{SysV IPC}.
-
-In realtà, grazie alla presenza del campo \var{mtype}, le code di messaggi
+\textit{SysV-IPC}; esse infatti nacquero principalmente come meccanismo di
+comunicazione bidirezionale quando ancora le \textit{pipe} erano
+unidirezionali; con la disponibilità di \func{socketpair} (vedi
+sez.~\ref{sec:ipc_socketpair}) o utilizzando una coppia di \textit{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
 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 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 \textit{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.
+
+% TODO: trattare qui, se non si trova posto migliore, copy_from_process e
+% copy_to_process, introdotte con il kernel 3.2. Vedi
+% http://lwn.net/Articles/405346/ e
+% http://ozlabs.org/~cyeoh/cma/process_vm_readv.txt 
+
 
 \subsection{I \textsl{file di lock}}
 \label{sec:ipc_file_lock}
 
-\index{file!di lock|(}
+\index{file!di~lock|(}
 
-Come illustrato in sez.~\ref{sec:ipc_sysv_sem} i semafori del \textit{SysV IPC}
+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
-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
-  tecnica possa non funzionare; in particolare per Linux, nel caso di NFS, si
-  è 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
+La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
+dei \textsl{file di lock} (per i quali è stata anche riservata una opportuna
+directory, \file{/var/lock}, nella standardizzazione del \textit{Filesystem
+  Hierarchy Standard}). Per questo si usa la caratteristica della funzione
+\func{open} (illustrata in sez.~\ref{sec:file_open_close}) 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}.} 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
 guida) che permettono rispettivamente di creare e rimuovere un \textsl{file di
-  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
+  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
 cancella con \func{unlink}.
 
-\begin{figure}[!htb]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/LockFile.c}
   \end{minipage} 
   \normalsize 
@@ -3070,150 +3372,148 @@ 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_close}, 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
+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
+difetto è che è quello di poterla usare solo se si opera all'interno di uno
 stesso filesystem.
 
 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 \itindex{polling}
-\textit{polling}, ed è quindi molto inefficiente.
+sempre cancellata esplicitamente.  Inoltre il controllo della disponibilità
+può essere eseguito solo con una tecnica di \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.
+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|)}
+\index{file!di~lock|)}
 
 
 \subsection{La sincronizzazione con il \textit{file locking}}
 \label{sec:ipc_lock_file}
 
-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 \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.
+Dato che i file di lock presentano gli inconvenienti illustrati in precedenza,
+la tecnica alternativa di sincronizzazione più comune è quella di fare ricorso
+al \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}
+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]
+\begin{figure}[!htbp]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/MutexLocking.c}
   \end{minipage} 
   \normalsize 
-  \caption{Il codice delle funzioni che permettono per la gestione dei 
-    \textit{mutex} con il \index{file!locking} \textit{file locking}.}
+  \caption{Il codice delle funzioni che permettono per la gestione dei
+    \textit{mutex} con il \textit{file locking}.}
   \label{fig:ipc_flock_mutex}
 \end{figure}
 
 Il codice delle varie funzioni usate per implementare un mutex utilizzando il
-\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
+\textit{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 \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
+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 \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à.
+aprire il file da usare per il \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
+(\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
+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
-caso si inizializza (\texttt{\small 28--31}) la struttura \var{lock} per il
+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 \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.
+chiamata a \func{fcntl}. Avendo usato il \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
-leggere lo stato del mutex. In questo caso si prepara (\texttt{\small 46--49})
+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.
 
 
 \subsection{Il \textit{memory mapping} anonimo}
 \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ò
+\itindbeg{memory~mapping} 
+
+Abbiamo già visto che quando i processi sono \textsl{correlati}, se cioè hanno
+almeno un progenitore comune, l'uso delle \textit{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.
 
@@ -3221,32 +3521,45 @@ 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
-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.
+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.
 
 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
+% TODO: fare esempio di mmap anonima
+
+% TODO: con il kernel 3.2 è stata introdotta un nuovo meccanismo di
+% intercomunicazione veloce chiamato Cross Memory Attach, da capire se e come
+% trattarlo qui, vedi http://lwn.net/Articles/405346/
+% https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=fcf634098c00dd9cd247447368495f0b79be12d1
+
+% TODO: con il kernel 3.17 è stata introdotta una fuunzionalità di
+% sigillatura dei file mappati in memoria e la system call memfd
+% (capire se va messo qui o altrove) vedi: http://lwn.net/Articles/593918/
+
 
-\section{Il sistema di comunicazione fra processi di POSIX}
+\section{L'intercomunicazione fra processi di POSIX}
 \label{sec:ipc_posix}
 
-Per superare i numerosi problemi del \textit{SysV IPC}, evidenziati per i suoi
+Per superare i numerosi problemi del \textit{SysV-IPC}, evidenziati per i suoi
 aspetti generali in coda a sez.~\ref{sec:ipc_sysv_generic} e per i singoli
 oggetti nei paragrafi successivi, lo standard POSIX.1b ha introdotto dei nuovi
 meccanismi di comunicazione, che vanno sotto il nome di POSIX IPC, definendo
@@ -3257,153 +3570,162 @@ una interfaccia completamente nuova, che tratteremo in questa sezione.
 \label{sec:ipc_posix_generic}
 
 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
-degli identificatori e delle chiavi visti nel SysV IPC, per passare ai
+ma a lungo non è stato così; la memoria condivisa è presente a partire dal
+kernel 2.4.x, i semafori sono forniti dalla \acr{glibc} nella sezione che
+implementa i \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
+degli identificatori e delle chiavi visti nel \textit{SysV-IPC}, per passare ai
 \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}
+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
-  \const{PATH\_MAX} byte e terminati da un carattere nullo.
+  \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}
-
-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 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
+\end{itemize*}
+
+Data la assoluta genericità delle specifiche, il comportamento delle funzioni
+è subordinato in maniera quasi completa alla relativa implementazione, 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 ed i semafori,
+che per 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}).  I nomi
+specificati nelle relative funzioni devono essere nella forma di un
+\textit{pathname} assoluto (devono cioè iniziare con ``\texttt{/}'') e
+corrisponderanno ad altrettanti file creati all'interno di queste directory;
+per questo motivo detti nomi non possono contenere altre ``\texttt{/}'' oltre
+quella iniziale.
+
+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 è 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.
+comandi di accesso ai file, che funzionano come su dei file normali. Questo
+però è 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 il comando \cmd{strace}, sia per la memoria
+condivisa che per le code di messaggi varie \textit{system call} utilizzate da
+Linux corrispondono in realtà a quelle ordinarie dei file, essendo detti
+oggetti realizzati come tali usando degli specifici filesystem.
 
 In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai
 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}) che viene usata per gli oggetti del
-SysV IPC.  Per quanto riguarda l'attribuzione dell'utente e del gruppo
+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
+secondo la semantica SysV: corrispondono cioè a \ids{UID} e \ids{GID} effettivi
 del processo che esegue la creazione.
 
 
-\subsection{Code di messaggi}
+\subsection{Code di messaggi Posix}
 \label{sec:ipc_posix_mq}
 
 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, 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.
+2.6.6 del kernel. In generale, come le corrispettive del \textit{SysV-IPC}, le
+code di messaggi sono poco 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.}
+superiore al 2.6.6 occorre utilizzare la libreria \file{librt} che contiene le
+funzioni dell'interfaccia POSIX ed i programmi che usano le code di messaggi
+devono essere compilati aggiungendo l'opzione \code{-lrt} al comando
+\cmd{gcc}. In corrispondenza all'inclusione del supporto nel kernel ufficiale
+le funzioni di libreria sono state inserite nella \acr{glibc}, e sono
+disponibili a partire dalla versione 2.3.4 delle medesime.
 
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
-\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
-aggiungendo ad \conffile{/etc/fstab} una riga come:
-\begin{verbatim}
+\texttt{mqueue} montato sulla directory \file{/dev/mqueue}; questo può essere
+fatto aggiungendo ad \conffile{/etc/fstab} una riga come:
+\begin{FileExample}[label=/etc/fstab]
 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
+\end{FileExample}
+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 è:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{mqd\_t mq\_open(const char *name, int oflag)}
-  
-  \funcdecl{mqd\_t mq\_open(const char *name, int oflag, unsigned long mode,
+La funzione di sistema che permette di aprire (e crearla se non esiste ancora)
+una coda di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fhead{sys/stat.h}
+\fhead{mqueue.h}
+\fdecl{mqd\_t mq\_open(const char *name, int oflag)}
+\fdecl{mqd\_t mq\_open(const char *name, int oflag, unsigned long mode,
     struct mq\_attr *attr)}
-  
-  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
-    valori:
-    \begin{errlist}
-    \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 è
-      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
-      non esiste.
-    \end{errlist}
-    ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
-    \errval{EMFILE} ed \errval{ENFILE}.}
-\end{functions}
+
+\fdesc{Apre una coda di messaggi POSIX impostandone le caratteristiche.}
+}
+
+{La funzione ritorna il descrittore associato alla coda in caso di successo e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] il processo non ha i privilegi per accedere alla
+    coda secondo quanto specificato da \param{oflag} oppure \const{name}
+    contiene più di una ``\texttt{/}''.
+  \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 dei campi \var{mq\_maxmsg} e \var{mq\_msgsize}; questi valori
+    devono essere positivi ed inferiori ai limiti di sistema se il processo
+    non ha privilegi amministrativi, inoltre \var{mq\_maxmsg} non può comunque
+    superare \const{HARD\_MAX}.
+  \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda non
+    esiste o si è usato il nome ``\texttt{/}''.
+  \item[\errcode{ENOSPC}] lo spazio è insufficiente, probabilmente per aver
+    superato il limite di \texttt{queues\_max}.
+  \end{errlist}
+  ed inoltre \errval{EMFILE}, \errval{ENAMETOOLONG}, \errval{ENFILE},
+  \errval{ENOMEM} ed nel loro significato generico.  }
+\end{funcproto}
 
 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
+\typed{mqd\_t}. 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 il nome indicato fa riferimento ad una coda di messaggi già esistente, il
+descrittore ottenuto farà riferimento allo stesso oggetto, pertanto tutti i
+processi che hanno usato \func{mq\_open} su quel nome otterranno un
+riferimento alla stessa coda. Diventa così immediato costruire un canale di
+comunicazione fra detti processi.
+
+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
-seguenti:
-\begin{basedescript}{\desclabelwidth{2cm}\desclabelstyle{\nextlinelabel}}
+sez.~\ref{sec:file_open_close} (per questo occorre includere \texttt{fcntl.h})
+dei quali però \func{mq\_open} riconosce solo i seguenti:
+\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. 
@@ -3411,32 +3733,35 @@ 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} (per questo occorre includere \texttt{sys/stat.h}), 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
-  \begin{minipage}[c]{15cm}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
@@ -3446,293 +3771,372 @@ fig.~\ref{fig:ipc_mq_attr}.
 \end{figure}
 
 Per la 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 è:
-\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
-  \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
-automaticamente. Inoltre se il processo aveva agganciato una richiesta di
-notifica sul descrittore che viene chiuso, questa sarà rilasciata e potrà
-essere richiesta da qualche altro processo.
+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 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.
+
+I suddetti limiti di sistema sono impostati attraverso altrettanti file in
+\texttt{/proc/sys/fs/mqueue}, in particolare i file che controllano i valori
+dei limiti sono:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\sysctlfiled{fs/mqueue/msg\_max}] Indica il valore massimo del numero di
+  messaggi in una coda e agisce come limite superiore per il valore di
+  \var{attr->mq\_maxmsg} in \func{mq\_open}. Il suo valore di default è 10. Il
+  valore massimo è \constd{HARD\_MAX} che vale \code{(131072/sizeof(void *))},
+  ed il valore minimo 1 (ma era 10 per i kernel precedenti il 2.6.28). Questo
+  limite viene ignorato per i processi con privilegi amministrativi (più
+  precisamente con la \textit{capability} \const{CAP\_SYS\_RESOURCE}) ma
+  \const{HARD\_MAX} resta comunque non superabile.
+
+\item[\sysctlfiled{fs/mqueue/msgsize\_max}] Indica il valore massimo della
+  dimensione in byte di un messaggio sulla coda ed agisce come limite
+  superiore per il valore di \var{attr->mq\_msgsize} in \func{mq\_open}. Il
+  suo valore di default è 8192.  Il valore massimo è 1048576 ed il valore
+  minimo 128 (ma per i kernel precedenti il 2.6.28 detti limiti erano
+  rispettivamente \const{INT\_MAX} e 8192). Questo limite viene ignorato dai
+  processi con privilegi amministrativi (con la \textit{capability}
+  \const{CAP\_SYS\_RESOURCE}).
+
+\item[\sysctlfiled{fs/mqueue/queues\_max}] Indica il numero massimo di code di
+  messaggi creabili in totale sul sistema, il valore di default è 256 ma si
+  può usare un valore qualunque fra $0$ e \const{INT\_MAX}. Il limite non
+  viene applicato ai processi con privilegi amministrativi (cioè con la
+  \textit{capability} \const{CAP\_SYS\_RESOURCE}).
+
+\end{basedescript}
+
+Infine sulle code di messaggi si applica il limite imposto sulla risorsa
+\const{RLIMIT\_MSGQUEUE} (vedi sez.~\ref{sec:sys_resource_limit}) che indica
+lo spazio massimo (in byte) occupabile dall'insieme di tutte le code di
+messaggi appartenenti ai processi di uno stesso utente, che viene identificato
+in base al \textit{real user ID} degli stessi.
 
+Quando l'accesso alla coda non è più necessario si può chiudere il relativo
+descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_close(mqd\_t mqdes)}
+
+\fdesc{Chiude una coda di messaggi.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori \errval{EBADF} o \errval{EINTR} nel
+  loro significato generico.
+}  
+\end{funcproto}
+
+La funzione è analoga a \func{close},\footnote{su Linux, dove le code sono
+  implementate come file su un filesystem dedicato, è esattamente la stessa
+  funzione, per cui non esiste una \textit{system call} autonoma e la funzione
+  viene rimappata su \func{close} dalle \acr{glibc}.}  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à 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 è:
-\begin{prototype}{mqueue.h}
-{int mq\_unlink(const char *name)}
+funzione di sistema \funcd{mq\_unlink}, il cui prototipo è:
 
-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
-  \func{unlink}.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_unlink(const char *name)}
 
-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 rimuove la coda \param{name}, così
-che una successiva chiamata a \func{mq\_open} fallisce o crea una coda
-diversa. 
+\fdesc{Rimuove una coda di messaggi.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà gli uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EACCES}] non si hanno i permessi per cancellare la coda.
+    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+    \item[\errcode{ENOENT}] non esiste una coda con il nome indicato.
+  \end{errlist}
+}  
+\end{funcproto}
+
+Anche in questo caso il comportamento della funzione è analogo a quello di
+\func{unlink} per i file, la funzione rimuove la coda \param{name} (ed il
+relativo file sotto \texttt{/dev/mqueue}), così che una successiva chiamata a
+\func{mq\_open} fallisce o crea una coda diversa.
+
+% TODO, verificare se mq_unlink è davvero una system call indipendente.
 
 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:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{int mq\_getattr(mqd\_t mqdes, struct mq\_attr *mqstat)}
-  Legge gli attributi di una coda di messaggi POSIX.
-  
-  \funcdecl{int mq\_setattr(mqd\_t mqdes, const struct mq\_attr *mqstat,
+all'interno del sistema anche quando quest'ultima non è aperta da nessun
+processo (questa è una delle differenze più rilevanti nei confronti di
+\textit{pipe} e \textit{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{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_getattr(mqd\_t mqdes, struct mq\_attr *mqstat)}
+\fdesc{Legge gli attributi di una coda di messaggi POSIX.}
+\fdecl{int mq\_setattr(mqd\_t mqdes, const struct mq\_attr *mqstat,
     struct mq\_attr *omqstat)}
-  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}
-    o \errval{EINVAL}.}
-\end{functions}
+\fdesc{Modifica gli attributi di una coda di messaggi POSIX.}
+}
+{
+Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà i valori \errval{EBADF}
+    o \errval{EINVAL} nel loro significato generico.
+}  
+\end{funcproto}
 
 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
-messaggi da essa contenuti, gli altri indicano le caratteristiche generali
-della stessa.
+coda \param{mqdes} nella struttura \struct{mq\_attr} puntata
+da \param{mqstat}; di questi l'unico relativo 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 impostate in fase di
+apertura.
 
 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
-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
-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.
-
-Per inserire messaggi su di una coda sono previste due funzioni,
-\funcd{mq\_send} e \funcd{mq\_timedsend}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
-    unsigned int msg\_prio)} 
-  Esegue l'inserimento di un messaggio su una coda.
-  
-  \funcdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
-    msg\_len, unsigned msg\_prio, const struct timespec *abs\_timeout)}   
-  Esegue l'inserimento di un messaggio su una coda entro il tempo
-  \param{abs\_timeout}.
+coda (indicata da \param{mqdes}) tramite i valori contenuti nella struttura
+\struct{mq\_attr} puntata da \param{mqstat}, ma può essere modificato solo il
+campo \var{mq\_flags}, gli altri campi vengono comunque 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 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.
+
+Per inserire messaggi su di una coda sono previste due funzioni di sistema,
+\funcd{mq\_send} e \funcd{mq\_timedsend}. In realtà su Linux la \textit{system
+  call} è soltanto \func{mq\_timedsend}, mentre \func{mq\_send} viene
+implementata come funzione di libreria che si appoggia alla
+precedente. Inoltre \func{mq\_timedsend} richiede che sia definita la macro
+\macro{\_XOPEN\_SOURCE} ad un valore pari ad almeno \texttt{600} o la macro
+\macro{\_POSIX\_C\_SOURCE} ad un valore uguale o maggiore di \texttt{200112L}.
+I rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
+    unsigned int msg\_prio)}
+\fdesc{Esegue l'inserimento di un messaggio su una coda.}
+\fhead{mqueue.h}
+\fhead{time.h}
+\fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
+    msg\_len, \\ 
+\phantom{int mq\_timedsend(}unsigned int msg\_prio, const struct timespec
+*abs\_timeout)} 
+\fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo
+  specificato}
+}
 
-  
-  \bodydesc{Le funzioni restituiscono 0 in caso 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 è 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
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
+      coda è piena.
+    \item[\errcode{EBADF}] si specificato un file descriptor non valido.
+    \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
-      effettuato entro il tempo stabilito.
-    \end{errlist}    
-    ed inoltre \errval{EBADF} ed \errval{EINTR}.}
-\end{functions}
-
-Entrambe le funzioni richiedono un puntatore al testo del messaggio
-nell'argomento \param{msg\_ptr} e la relativa lunghezza in \param{msg\_len}.
+    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
+      eccede il limite impostato per la coda.
+    \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
+      effettuato entro il tempo stabilito (solo \func{mq\_timedsend}).
+  \end{errlist}
+  ed inoltre \errval{EBADF} e \errval{EINTR} nel loro significato generico.
+}
+\end{funcproto}
+
+Entrambe le funzioni richiedono un puntatore ad un buffer in memoria
+contenente il testo del messaggio da inserire nella coda \param{mqdes}
+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, che, essendo
+definito come \ctyp{unsigned int}, è sempre un intero positivo. 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 che hanno la stessa priorità
+che quindi saranno letti con la politica di una \textit{fifo}. Il valore della
+priorità non può eccedere il limite di sistema \constd{MQ\_PRIO\_MAX}, che al
+momento è 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,\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_timeval_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.
+sia stata selezionata in fase di apertura della stessa la modalità non
+bloccante o non si sia impostato il flag \const{O\_NONBLOCK} sul file
+descriptor della coda, nel qual caso entrambe ritornano con un codice di
+errore di \errcode{EAGAIN}.
+
+La sola differenza fra le due funzioni è che \func{mq\_timedsend}, passato il
+tempo massimo impostato con l'argomento \param{abs\_timeout}, ritorna con un
+errore di \errcode{ETIMEDOUT}, se invece il tempo è già scaduto al momento
+della chiamata e la coda è piena la funzione ritorna immediatamente. Il valore
+di \param{abs\_timeout} deve essere specificato come 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.
 
 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
-prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{ssize\_t mq\_receive(mqd\_t mqdes, char *msg\_ptr, size\_t
-    msg\_len, unsigned int *msg\_prio)}   
-  Effettua la ricezione di un messaggio da una coda.
-  
-  \funcdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
-    msg\_len, unsigned int *msg\_prio, const struct timespec *abs\_timeout)}
-  Effettua la ricezione di un messaggio da una coda entro il tempo
-  \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
-    valori:
-    \begin{errlist}
-    \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
-      coda è vuota.
+previste due funzioni di sistema, \funcd{mq\_receive} e
+\funcd{mq\_timedreceive}. Anche in questo caso su Linux soltanto
+\func{mq\_timedreceive} è effettivamente, una \textit{system call} e per
+usarla devono essere definite le opportune macro come per
+\func{mq\_timedsend}. I rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{mqueue.h} 
+\fdecl{ssize\_t mq\_receive(mqd\_t mqdes, char *msg\_ptr, size\_t
+    msg\_len, unsigned int *msg\_prio)} 
+\fdesc{Effettua la ricezione di un messaggio da una coda.}
+\fhead{mqueue.h} 
+\fhead{time.h} 
+\fdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
+    msg\_len,\\ 
+\phantom{ssize\_t  mq\_timedreceive(}unsigned int *msg\_prio, const struct timespec
+*abs\_timeout)} 
+\fdesc{Riceve un messaggio da una coda entro un limite di tempo.}
+}
+{Entrambe le funzioni ritornano il numero di byte del messaggio in caso di
+  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+  valori:
+  \begin{errlist}
+    \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
+      coda è vuota.
+    \item[\errcode{EINVAL}] si è specificato un valore nullo per
+      \param{msg\_ptr}, o un valore non valido per \param{abs\_timeout}.
     \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
-      \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
-viene tolto dalla coda e la sua dimensione viene restituita come valore di
-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
+  \end{errlist}
+  ed inoltre \errval{EBADF} o \errval{EINTR} nel loro significato generico.  }
+\end{funcproto}
+
+La funzione estrae dalla coda \param{mqdes} 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; si tenga presente che 0 è una dimensione valida e che la
+condizione di errore è indicata soltanto da un valore di
+$-1$.\footnote{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
 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
-\func{mq\_getaddr} prima di eseguire una ricezione, in modo da ottenere la
+il messaggio.  È pertanto opportuno eseguire sempre una chiamata a
+\func{mq\_getattr} 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}. 
 
-% 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 è:
-\begin{prototype}{mqueue.h}
-{int mq\_notify(mqd\_t mqdes, const struct sigevent *notification)}
+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 è:
 
-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: 
-    \begin{errlist}
-    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_notify(mqd\_t mqdes, const struct sigevent *notification)}
+
+\fdesc{Attiva il meccanismo di notifica per una coda.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EBADF}] il descrittore non fa riferimento ad una coda di
       messaggi.
-    \end{errlist}}
-\end{prototype}
+    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+    \item[\errcode{EINVAL}] si è richiesto un meccanismo di notifica invalido
+      o specificato nella notifica con i segnali il valore di un segnale non
+      esistente.
+  \end{errlist}
+  ed inoltre \errval{ENOMEM} nel suo significato generico.
+}  
+\end{funcproto}
 
 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
-bloccarsi nell'attesa. Per far questo un processo deve registrarsi con la
-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 \itindex{thread} \textit{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 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}.
+processo la presenza di dati sulla coda indicata da \param{mqdes}, 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 processo alla volta per ciascuna coda.
+
+Il comportamento di \func{mq\_notify} dipende dai valori passati con
+l'argomento \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
+su di essa si può rivedere 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}; fra questi la pagina di
+manuale riporta soltanto i primi tre, ed 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} (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
+  \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. 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
@@ -3744,9 +4148,9 @@ 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
-  \ref{sec:sig_semantics}.} questa caratteristica non configura una
-race-condition perché l'invio di un segnale avviene solo se la coda è vuota;
+i segnali non affidabili (l'argomento è stato affrontato in
+\ref{sec:sig_semantics}) questa caratteristica non configura una \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
@@ -3755,80 +4159,88 @@ 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
 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
-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
-  proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.}
-
+valore del \ids{PID} del processo che ha emesso il segnale, \var{si\_uid}
+all'\textsl{user-ID} 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 sul processo che ha inserito un messaggio usando un gestore
+per il segnale in forma estesa, di nuovo si faccia riferimento a quanto detto
+al proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.
 
 
 \subsection{Memoria condivisa}
 \label{sec:ipc_posix_shm}
 
-La memoria condivisa è stato il primo degli oggetti di IPC POSIX inserito nel
-kernel ufficiale; il supporto a questo tipo di oggetti è realizzato attraverso
+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,\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
+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 è
-necessario che in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs};
-questo di norma viene fatto aggiungendo una riga del tipo di:
-\begin{verbatim}
+Per potere utilizzare l'interfaccia POSIX per la memoria condivisa la
+\acr{glibc} (le funzioni sono state introdotte con la versione 2.2) richiede
+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 fatto aggiungendo una riga del tipo di:
+\begin{FileExample}[label=/etc/fstab]
 tmpfs   /dev/shm        tmpfs   defaults        0      0
-\end{verbatim}
-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}
+\end{FileExample}
+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{Example}
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
-\end{verbatim}
+\end{Example}
 
 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 \constd{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{funcproto}{
+\fhead{sys/mman.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fdecl{int shm\_open(const char *name, int oflag, mode\_t mode)}
+
+\fdesc{Apre un segmento di memoria condivisa.}
+}
+
+{La funzione ritorna un file descriptor in caso di successo e $-1$ per un
+  errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] non si hanno i permessi di aprire il segmento nella
+    modalità scelta o si richiesto \const{O\_TRUNC} per un segmento su cui non
+    si ha il permesso di scrittura.
+  \item[\errcode{EINVAL}] si è utilizzato un nome non valido.
+  \end{errlist}
+  ed inoltre \errval{EEXIST}, \errval{EMFILE}, \errval{ENAMETOOLONG},
+  \errval{ENFILE} e \errval{ENOENT} nello stesso significato che hanno per
+  \func{open}.
+}  
+\end{funcproto}
 
-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}
 
 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 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
+\param{name}. Come già spiegato in sez.~\ref{sec:ipc_posix_generic} questo
+nome può essere specificato in forma standard solo facendolo iniziare per
+``\texttt{/}'' e senza ulteriori ``\texttt{/}''. 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
+sez.~\ref{sec:file_open_close} 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
@@ -3838,60 +4250,89 @@ 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
-  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
-\index{inode} inode).  In questo modo è possibile effettuare una chiamata ad
+segmento di memoria condiviso con le stesse modalità di \func{open} viste in
+sez.~\ref{sec:file_open_close}. Inoltre sul file descriptor viene sempre
+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 ordinari, 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à,
-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
-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}
-{int shm\_unlink(const char *name)}
+Quando il nome non esiste si può creare un nuovo segmento specificando
+\const{O\_CREAT}; in tal caso il segmento avrà (così come i nuovi file)
+lunghezza nulla. Il nuovo segmento verrà creato con i permessi indicati
+da \param{mode} (di cui vengono usati solo i 9 bit meno significativi, non si
+applicano pertanto i permessi speciali di sez.~\ref{sec:file_special_perm})
+filtrati dal valore dell'\textit{umask} del processo. Come gruppo ed utente
+proprietario del segmento saranno presi quelli facenti parte del gruppo
+\textit{effective} del processo chiamante.
+
+Dato che un segmento di lunghezza nulla è di scarsa utilità, una vola che lo
+si è creato per impostarne la dimensione si dovrà poi 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 descriptor ad esso associato (semplicemente con
+\func{close}), senza che la mappatura ne risenta, e che questa può essere
+rimossa usando \func{munmap}.
+
+Come per i file, quando si vuole rimuovere completamente un segmento di
+memoria condivisa occorre usare la funzione \funcd{shm\_unlink}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{sys/mman.h}
+\fdecl{int shm\_unlink(const char *name)}
+
+\fdesc{Rimuove un segmento di memoria condivisa.}
+}
 
-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
-  \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 ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] non si è proprietari del segmento.
+  \end{errlist}
+  ed inoltre \errval{ENAMETOOLONG} e \errval{ENOENT}, nel loro significato
+  generico.
+}  
+\end{funcproto}
+
+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.
 
+Dato che i segmenti di memoria condivisa sono trattati come file del
+filesystem \texttt{tmpfs}, si possono usare su di essi, con lo stesso
+significato che assumono sui file ordinari, anche funzioni come quelle delle
+famiglie \func{fstat}, \func{fchown} e \func{fchmod}. Inoltre a partire dal
+kernel 2.6.19 per i permessi sono supportate anche le ACL illustrate in
+sez.~\ref{sec:file_ACL}.
+
+Come esempio dell'uso delle funzioni attinenti ai segmenti di memoria
+condivisa POSIX, 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 completo, di cui si sono riportate
+le parti essenziali in fig.~\ref{fig:ipc_posix_shmmem}, è contenuto nel file
+\file{SharedMem.c} dei sorgenti allegati.
+
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{15.6cm}
+  \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/MemShared.c}
   \end{minipage} 
   \normalsize 
@@ -3900,45 +4341,39 @@ 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
-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
-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})
 chiamata a \func{shm\_open}, che apre il segmento in lettura e scrittura
 (creandolo se non esiste, ed uscendo in caso contrario) assegnandogli sul
-filesystem i permessi specificati dall'argomento \var{perm}. In caso di errore
-(\texttt{\small 10--12}) si restituisce un puntatore nullo, altrimenti si
-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
-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
-questo caso si apre (\texttt{\small 31}) il segmento con \func{shm\_open}
-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
+filesystem i permessi specificati dall'argomento \var{perm}. 
+
+In caso di errore (\texttt{\small 10-12}) si restituisce un puntatore nullo,
+altrimenti si 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 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 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 (\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
 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},
+avveniva con i segmenti del \textit{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},
 restituendo al chiamante il valore di ritorno.
 
 
@@ -3948,411 +4383,644 @@ restituendo al chiamante il valore di ritorno.
 \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
+dei semafori POSIX che li realizzava solo a livello di \textit{thread} e non
+di processi,\footnote{questo significava che i semafori erano visibili solo
+  all'interno dei \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}
+della \acr{glibc} (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 \textit{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.
+A partire dal kernel 2.5.7 è stato introdotto un meccanismo di
+sincronizzazione completamente nuovo, basato sui cosiddetti \textit{futex} (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 della \acr{glibc} che usano questa
+nuova infrastruttura per quella che viene 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
+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}. 
+occorrerà compilare i programmi con l'opzione \texttt{-lrt} o con
+\texttt{-lpthread} se si usano questi ultimi. 
 
 La funzione che permette di creare un nuovo semaforo POSIX, creando il
-relativo file, o di accedere ad uno esistente, è \funcd{sem\_open}, questa
+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,
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fhead{sys/stat.h}
+\fhead{fcntl.h}
+\fdecl{sem\_t *sem\_open(const char *name, int oflag)}
+\fdecl{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
+\fdesc{Crea un semaforo o ne apre uno esistente.}
+}
+{La funzione ritorna l'indirizzo del semaforo in caso di successo e
+  \constd{SEM\_FAILED} per un errore, nel qual caso \var{errno} assumerà uno
+  dei valori:
+  \begin{errlist}
+    \item[\errcode{EACCES}] 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
+      \constd{SEM\_VALUE\_MAX} o il nome è solo ``\texttt{/}''.
+    \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}
+  \end{errlist}
+  ed inoltre \errval{EMFILE}, \errval{ENFILE} ed \errval{ENOMEM} nel loro
+  significato generico.
+
+}
+\end{funcproto}
 
 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
+utilizzare, ed è quello che permette a processi diversi di accedere allo
+stesso semaforo. Questo deve essere specificato nella stessa forma utilizzata
+per i segmenti di memoria condivisa, con un nome che inizia con ``\texttt{/}''
+e senza ulteriori ``\texttt{/}'', vale a dire nella forma
+\texttt{/nome-semaforo}.
+
+Con Linux i file associati ai semafori sono mantenuti nel filesystem virtuale
+\texttt{/dev/shm}, e gli viene assegnato automaticamente un nome nella forma
+\texttt{sem.nome-semaforo}, si ha cioè una corrispondenza per cui
+\texttt{/nome-semaforo} viene rimappato, nella creazione tramite
+\func{sem\_open}, su \texttt{/dev/shm/sem.nome-semaforo}. Per questo motivo la
+dimensione massima per il nome di un semaforo, a differenza di quanto avviene
+per i segmenti di memoria condivisa, è pari a \const{NAME\_MAX}$ - 4$.
+
+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
+valori visti in sez.~\ref{sec:file_open_close} 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
+\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
+\param{mode}; se il semaforo esiste già questi saranno semplicemente
 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.
+semaforo non esista, ed usandolo insieme ad \const{O\_CREAT} la funzione
+fallisce qualora un semaforo con lo stesso nome sia già presente.
+
+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'\ids{UID} ed il \ids{GID} effettivo del processo chiamante, e che i permessi
+indicati con \param{mode} vengono filtrati dal valore della \textit{umask} del
+processo.  Inoltre per poter aprire un semaforo è necessario avere su di esso
+sia il permesso di lettura che quello di scrittura.
 
 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
+semaforo con un valore di tipo \ctyp{sem\_t *}, è questo valore che dovrà
+essere passato alle altre funzioni per operare sul semaforo stesso, e non sarà
+più necessario fare riferimento al nome, che potrebbe anche essere rimosso con
+\func{sem\_unlink}.
+
+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}    
+liberando il semaforo. La prima operazione è effettuata dalla funzione
+\funcd{sem\_wait}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_wait(sem\_t *sem)}
+
+\fdesc{Blocca un semaforo.}
 }
-\end{functions}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei 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{funcproto}
 
 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.
+la risorsa è disponibile, la funzione ha successo, il valore del semaforo
+viene diminuito di 1 ed essa ritorna immediatamente consentendo la
+prosecuzione del processo.
+
+Se invece il valore è nullo la funzione si blocca (fermando l'esecuzione del
+processo) fintanto che il valore del semaforo non ritorna positivo (cosa che a
+questo punto può avvenire solo per opera di altro processo che rilascia il
+semaforo con una chiamata a \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 \errval{EINTR}; inoltre questo avverrà
+comunque, anche qualora si fosse richiesta la gestione con la semantica BSD,
+installando il gestore del suddetto segnale con l'opzione \const{SA\_RESTART}
+(vedi sez.~\ref{sec:sig_sigaction}) per riavviare le \textit{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
+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{funcproto}{
+\fhead{semaphore.h} 
+\fdecl{int sem\_trywait(sem\_t *sem)}
+
+\fdesc{Tenta di bloccare un semaforo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei 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}    
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+  \end{errlist}
 }
-\end{functions}
+\end{funcproto}
 
-La funzione è identica a \func{sem\_wait} ed se la risorsa è libera ha lo
+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
+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ò
+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
+ad un valore di almeno 600 o la macro \macro{\_POSIX\_C\_SOURCE} ad un valore
+uguale o maggiore di \texttt{200112L} prima di includere
+\headfiled{semaphore.h}, la funzione è \funcd{sem\_timedwait}, ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{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}    
+
+\fdesc{Blocca un semaforo.}
 }
-\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}    
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+    \item[\errcode{ETIMEDOUT}] è scaduto il tempo massimo di attesa. 
+  \end{errlist}
+}  
+\end{funcproto}
+
+Anche in questo caso il comportamento della funzione è identico a quello di
+\func{sem\_wait}, ma è possibile impostare un tempo limite per l'attesa
+tramite la struttura \struct{timespec} (vedi
+fig.~\ref{fig:sys_timespec_struct}) puntata
+dall'argomento \param{abs\_timeout}, indicato in secondi e nanosecondi a
+partire dalla cosiddetta \textit{Epoch} (00:00:00, 1 January 1970
+UTC). Scaduto il limite la funzione ritorna anche se non è possibile acquisire
+il semaforo fallendo con un errore di \errval{ETIMEDOUT}.
+
+La seconda funzione principale utilizzata per l'uso dei semafori è quella 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 (si
+ricordi che in generale un semaforo viene usato come indicatore di un numero
+di risorse disponibili). Detta funzione è \funcd{sem\_post} ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_post(sem\_t *sem)}
+
+\fdesc{Rilascia un semaforo.}
 }
-\end{functions}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+    \item[\errcode{EOVERFLOW}] si superato il massimo valore di un semaforo.
+  \end{errlist}
+}  
+\end{funcproto}
 
 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}    
+dall'argomento \param{sem}, se questo era nullo la relativa risorsa risulterà
+sbloccata, cosicché un altro processo (o \textit{thread}) eventualmente
+bloccato in una \func{sem\_wait} sul semaforo possa essere svegliato e rimesso
+in esecuzione.  Si tenga presente che la funzione è sicura 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 volesse semplicemente leggere il
+valore, si potrà usare la funzione \funcd{sem\_getvalue}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_getvalue(sem\_t *sem, int *sval)}
+
+\fdesc{Richiede il valore di un semaforo.}
 }
-\end{functions}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+  \end{errlist}
+}  
+\end{funcproto}
 
 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
+\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
+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.
+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}    
+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{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_close(sem\_t *sem)}
+
+\fdesc{Chiude un semaforo.}
 }
-\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
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+  \end{errlist}
+}  
+\end{funcproto}
+
+La funzione chiude il semaforo indicato dall'argomento \param{sem}, che non
+potrà più essere utilizzato nelle altre funzioni. La chiusura comporta anche
+che tutte le risorse che il sistema poteva avere assegnato al processo
+nell'uso del semaforo vengono immediatamente rilasciate. Questo significa che
+un eventuale altro processo bloccato sul semaforo a causa della acquisizione
+dello stesso da parte del processo che chiama \func{sem\_close} potrà essere
+immediatamente riavviato.
+
+Si tenga presente poi che come avviene per i file, all'uscita di un processo
+anche 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 infine 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
+lo si cancelli esplicitamente. Per far questo si può utilizzare la funzione
+\funcd{sem\_unlink}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_unlink(const char *name)}
+
+\fdesc{Rimuove un semaforo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EACCES}] non si hanno i permessi necessari a cancellare il
       semaforo.
-    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
     \item[\errcode{ENOENT}] il semaforo \param{name} non esiste.
-    \end{errlist}    
-}
-\end{functions}
+  \end{errlist}
+}  
+\end{funcproto}
 
 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
+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}.
+sez.~\ref{sec:link_symlink_rename}.
 
-Una delle caratteristiche peculiari dei semafori POSIX è che questi possono
-anche essere utilizzati anche in forma anonima, senza necessità di fare
+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
+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)}
+consente di inizializzare un semaforo anonimo è \funcd{sem\_init}, il cui
+prototipo è:
 
-  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}
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_init(sem\_t *sem, int pshared, unsigned int value)}
+\fdesc{Inizializza un semaforo anonimo.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei 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
+    \item[\errcode{ENOSYS}] il valore di \param{pshared} non è nullo ed il
       sistema non supporta i semafori per i processi.
-    \end{errlist}
-}
-\end{functions}
+  \end{errlist}
+}  
+\end{funcproto}
 
 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} heap.
-
-Qualora il semaforo debba essere condiviso fra più processi (nel qual caso si
+il semaforo deve essere utilizzato dai \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 \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
+\textit{thread}, si dovrà usare cioè una variabile globale o una variabile
+allocata dinamicamente nello \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
+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.
+sez.~\ref{sec:file_memory_map}) a cui essi poi potranno accedere (si ricordi
+che i tratti di memoria condivisa vengono mantenuti nei processi figli
+attraverso la funzione \func{fork}).
 
-Una volta inizializzato il semaforo anonimo con \func{sem\_init} lo si potrà
+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. 
+\func{sem\_post}. Si tenga presente però che inizializzare due volte lo stesso
+semaforo può dar luogo ad un comportamento indefinito. 
 
+Qualora 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 è:
 
-Una volta che non si intenda più utilizzare un semaforo anonimo questo può
-essere eliminato da 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}
+\begin{funcproto}{
+\fhead{semaphore.h}
+\fdecl{int sem\_destroy(sem\_t *sem)}
+\fdesc{Elimina un semaforo anonimo.}
 }
-\end{functions}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+    \item[\errcode{EINVAL}] l'argomento \param{sem} non indica un semaforo
+      valido.
+  \end{errlist}
+}  
+\end{funcproto}
 
 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.
+semaforo su cui sono presenti processi (o \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
+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}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \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 12-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 22}) 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 \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 24-27}) 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}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \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 30-33}) 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 fermarlo con una
+interruzione da tastiera (\texttt{C-c}), che corrisponde all'invio del segnale
+\signal{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}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\codesamplewidth}
+    \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 \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{Console}
+piccardi@hain:~/gapil/sources$  \textbf{./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{Console}
+%$
+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{Console}
+piccardi@hain:~/gapil/sources$ \textbf{./message_setter -t 3 ciao}
+Sleeping for 3 seconds
+\end{Console}
+%$
+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{Console}
+...
+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{Console}
+%$
+
+E si noterà come nel momento in cui si lancia \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
@@ -4367,7 +5035,7 @@ seconda volta con \func{sem\_init}.
 % 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:  EOPNOTSUPP SOCK Process Comunication ipc perm key exec pipefd SZ
 % 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
@@ -4389,22 +5057,31 @@ seconda volta con \func{sem\_init}.
 % 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:  ShmRemove DirMonitor DirProp chdir GaPiL shmptr ipcs NFS SETPIPE
 % 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
+% 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
+% LocalWords:  CreateShm RemoveShm LIBRARY Library libmqueue FAILED has fclose
 % LocalWords:  ENAMETOOLONG qualchenome RESTART trywait XOPEN SOURCE timedwait
-% LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy
+% 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 fs
+% LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
+% LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds ECHILD
+% LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
+% LocalWords:  scan HUGETLB huge page NORESERVE copy RLIMIT MEMLOCK REMAP UTC
+% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE effective fstat
+% LocalWords:  fchown fchmod Epoch January
 
 
 %%% Local Variables: