Aggiornamento note di copyright e correzioni minime.
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 87c35f8c0a8c81a1b0bc159862a5e68290fad41f..ff6e69cb673cfb8729adec98abc31087cc444065 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2014 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",
@@ -269,7 +269,7 @@ formattare l'uscita alla maniera dei CGI, aggiungendo l'opportuno
 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
+  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
@@ -355,7 +355,7 @@ chiama \funcd{popen} ed il suo prototipo è:
 \end{funcproto}
 
 La funzione crea una \textit{pipe}, esegue una \func{fork} creando un nuovo
-processe nel quale invoca il programma \param{command} attraverso la shell (in
+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
@@ -641,25 +641,25 @@ 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 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 \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 end-of-file).
+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 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}.
+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
@@ -690,9 +690,9 @@ 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ù.
+  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
@@ -714,7 +714,7 @@ principale del programma e le definizioni delle variabili. Il codice completo
 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
+(\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
@@ -722,7 +722,7 @@ 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}).
+  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
@@ -1020,7 +1020,7 @@ 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 se ne
 sconsiglia assolutamente l'uso nei nuovi programmi, considerato che è ormai
-disponibile una revisione completa dei meccamismi di IPC fatta secondo quanto
+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}.
 
@@ -1161,7 +1161,7 @@ numero di tutti gli oggetti presenti nel \textit{SysV-IPC}, ed il cui default
 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 ICP (specificato con
+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
@@ -1171,11 +1171,11 @@ 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
+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. 
+prossime sezioni.
 
 Quello che ci interessa infatti è verificare l'allocazione degli
 identificativi associati agli oggetti; lanciando il comando si otterrà
@@ -1325,12 +1325,12 @@ Una coda di messaggi è costituita da una \itindex{linked~list} \textit{linked
   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.\footnote{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, ma abbiamo
-  mantenuto lo schema precedente dato che illustra in maniera più che adeguata
-  i principi di funzionamento delle code di messaggi.}
+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 \struct{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.
 
 \begin{figure}[!htb]
   \centering \includegraphics[width=13cm]{img/mqstruct}
@@ -1340,22 +1340,27 @@ kernel.\footnote{lo schema illustrato è in realtà una semplificazione di
 
 
 A ciascuna coda è associata una struttura \struct{msqid\_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, 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 significativi definiti in
-\headfile{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.
+definizione è riportata in fig.~\ref{fig:ipc_msqid_ds} ed a cui si accede
+includendo  \headfile{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]{\textwidth}
+  \begin{minipage}[c]{.90\textwidth}
     \includestruct{listati/msqid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1365,9 +1370,11 @@ Unix98.
 \end{figure}
 
 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.
@@ -1377,16 +1384,18 @@ gli altri campi invece:
 \item i campi \var{msg\_stime} e \var{msg\_rtime}, che esprimono
   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
@@ -1413,20 +1422,20 @@ file; il suo prototipo è:
     \var{msg\_qbytes} oltre il limite \const{MSGMNB} senza essere
     amministratore.
   \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}  nel loro significato
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
   generico.}
 \end{funcproto}
 
-
-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}}
+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[\const{IPC\_STAT}] Legge le informazioni riguardo la coda nella
-  struttura indicata da \param{buf}. Occorre avere il permesso di lettura
-  sulla coda.
+  struttura \struct{msqid\_ds} indicata da \param{buf}. Occorre avere il
+  permesso di lettura sulla coda.
 \item[\const{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
@@ -1437,41 +1446,50 @@ eseguire; i valori possibili sono:
 \item[\const{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à
+  \itindex{capability} \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 (\const{IPC\_INFO}, \const{MSG\_STAT} e
+\const{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 è:
 
-  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:
+\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.}
+}
+
+{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}.
+    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}, \errval{EINTR} 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
@@ -1481,6 +1499,17 @@ 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}.
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{0.8\textwidth}
+    \includestruct{listati/msgbuf.h}
+  \end{minipage} 
+  \normalsize 
+  \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
+    argomento per inviare/ricevere messaggi.}
+  \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
@@ -1504,17 +1533,6 @@ cioè \var{message} è una propria struttura che si passa alla funzione,
 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]{\textwidth}
-    \includestruct{listati/msgbuf.h}
-  \end{minipage} 
-  \normalsize 
-  \caption{Schema della struttura \structd{msgbuf}, da utilizzare come
-    argomento per inviare/ricevere messaggi.}
-  \label{fig:ipc_msbuf}
-\end{figure}
-
 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
@@ -1529,14 +1547,13 @@ 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
+\const{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
 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}).
@@ -1551,41 +1568,39 @@ vengono modificati:
 \item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
 \end{itemize*}
 
-La funzione che viene utilizzata per estrarre un messaggio da una coda è
-\funcd{msgrcv}; il suo prototipo è:
-\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{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{EACCES}] non si hanno i privilegi di accesso sulla coda.
+  \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
     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
+\const{LENGTH} nell'esempio di fig.~\ref{fig:ipc_msbuf}).
 
 Se il testo del messaggio ha lunghezza inferiore a \param{msgsz} esso viene
 rimosso dalla coda; in caso contrario, se \param{msgflg} è impostato a
@@ -1599,7 +1614,7 @@ 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}
+\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
@@ -1608,7 +1623,7 @@ coda, è quello meno recente); in particolare:
 \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ù
@@ -1619,13 +1634,13 @@ di leggere il primo messaggio nella coda con tipo diverso da \param{msgtyp}, e
 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
@@ -1638,15 +1653,15 @@ vengono modificati:
 \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 \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
+\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 è non facendo uso di file descriptor le tecniche di
+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
@@ -1684,18 +1699,17 @@ 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.
+\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
-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
-\textit{fifo}.
+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
@@ -1709,8 +1723,8 @@ 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
   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
+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
@@ -1761,31 +1775,32 @@ 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)
 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 \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 (\texttt{\small 16}) rileggere dalla coda la
-risposta 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.
+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
 messaggi:
-\begin{verbatim}
-[piccardi@gont sources]$ ipcs
+\begin{Console}
+[piccardi@gont sources]$ \textbf{ipcs}
 
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
@@ -1796,19 +1811,21 @@ 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
+[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.
+  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
@@ -1817,43 +1834,42 @@ 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
-\itindex{inode} 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.
-
+\itindex{inode} \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{Semafori}
+\subsection{I semafori}
 \label{sec:ipc_sysv_sem}
 
-I semafori non sono meccanismi di intercomunicazione diretta come quelli
-(\textit{pipe}, \textit{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}
+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 \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.
+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 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).
+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,
@@ -1865,37 +1881,35 @@ 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}
+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 è
@@ -1908,26 +1922,30 @@ 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.
+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
 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.
+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]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/semid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -1937,39 +1955,27 @@ semaforo all'uscita del processo.
 \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
+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
 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]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sem.h}
   \end{minipage} 
   \normalsize 
@@ -1978,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 \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
@@ -2015,42 +2038,39 @@ 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 \sysctlfile{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.
+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.}
+}
+
+{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 ha privilegi sufficienti ad eseguire l'operazione.
+      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}.
-}
-\end{functions}
+   \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
@@ -2059,7 +2079,7 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
@@ -2071,33 +2091,41 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 
 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}.
+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}.
+
+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 \macro{\_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'\ids{UID} 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'\ids{UID} effettivo del processo deve
-  corrispondere o al creatore o al proprietario dell'insieme, o
-  all'amministratore.  L'argomento \param{semnum} viene ignorato.
+  \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[\const{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.
@@ -2105,32 +2133,37 @@ seguenti:
 \item[\const{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
   \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
   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
   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.
+  \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,
   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.
+  privilegi di scrittura.  L'argomento \param{semnum} viene ignorato.
 \item[\const{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},
+\const{SEM\_STAT} e \const{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
@@ -2164,52 +2197,92 @@ 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}.
+    \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}
-
-
-%TODO manca semtimedop, trattare qui, referenziata in
-%sez.~\ref{sec:sig_gen_beha}.
+  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]{\textwidth}
+  \begin{minipage}[c]{.80\textwidth}
     \includestruct{listati/sembuf.h}
   \end{minipage} 
   \normalsize 
@@ -2218,65 +2291,73 @@ effettivamente eseguite se e soltanto se è possibile effettuarle tutte quante.
   \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
 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.
+\const{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
+\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
+  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:
+  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
@@ -2284,42 +2365,49 @@ 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)
   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 \ids{PID} del processo chiamante;
-inoltre vengono pure aggiornati al tempo corrente i campi \var{sem\_otime} e
-\var{sem\_ctime}.
+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} 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).
+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
+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.}
+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=13cm]{img/semtruct}
+  \centering \includegraphics[width=12cm]{img/semtruct}
   \caption{Schema della struttura di un insieme di semafori.}
   \label{fig:ipc_sem_schema}
 \end{figure}
@@ -2328,16 +2416,15 @@ 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
 possono avere successo; se una di esse comporta il blocco del processo il
-kernel crea una struttura \kstruct{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
+\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} \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
@@ -2353,21 +2440,18 @@ 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.
 
-%TODO verificare queste strutture \kstruct{sem\_queue} e \kstruct{sem\_undo}
-
-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
-  \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 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.
+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 è
@@ -2463,20 +2547,20 @@ problemi, usando il \itindex{file~locking} \textit{file locking}.
 \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}
+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
@@ -2486,18 +2570,45 @@ ed il suo prototipo è:
       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}
+    \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}, è 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}.
 
-% TODO aggiungere l'uso di SHM_HUGETLB introdotto con il kernel 2.6.0
+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 è \const{SHM\_HUGETLB} che consente di richiedere la
+creazione del segmento usando una \itindex{huge~page} \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
+\itindex{capability} \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, è
+\const{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}
+\itindex{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
@@ -2519,7 +2630,7 @@ norma, significa insieme a dei semafori.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -2536,7 +2647,7 @@ 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
@@ -2550,7 +2661,7 @@ invece:
   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
@@ -2591,7 +2702,9 @@ che permettono di cambiarne il valore.
                                             pagina di memoria).\\
     \const{SHMSEG}&   ---   &     ---     & Numero massimo di segmenti di
                                             memoria condivisa per ciascun
-                                            processo.\\
+                                            processo (l'implementazione non
+                                            prevede l'esistenza di questo
+                                            limite).\\
 
 
     \hline
@@ -2602,39 +2715,43 @@ 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}
+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{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
@@ -2650,20 +2767,35 @@ corrispondente comportamento della funzione, sono i seguenti:
   \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o
   il creatore del segmento, oppure l'amministratore. Compiuta l'operazione
   aggiorna anche il valore del campo \var{shm\_ctime}.
+\end{basedescript}
+
+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[\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.
+    locking} sul segmento di memoria condivisa, impedendo che la memoria usata
+  per il segmento venga salvata su disco dal meccanismo della
+  \index{memoria~virtuale} 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[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
-  \textit{memory locking} sul segmento di memoria condivisa.  Solo
-  l'amministratore può utilizzare questo comando.
+  \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}
-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.
+
+A questi due, come per \func{msgctl} e \func{semctl}, si aggiungono tre
+ulteriori valori, \const{IPC\_INFO}, \const{MSG\_STAT} e \const{MSG\_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
@@ -2676,25 +2808,28 @@ 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}
+
+\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 \type{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
       \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
@@ -2718,13 +2853,14 @@ L'argomento \param{shmaddr} specifica a quale indirizzo\footnote{lo standard
   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 *}.} 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}. 
+  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
@@ -2733,15 +2869,17 @@ 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 \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
 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
 lettura (si ricordi che anche le pagine di memoria hanno dei permessi), in tal
@@ -2752,8 +2890,16 @@ 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}:
+Infine \const{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.
@@ -2761,7 +2907,7 @@ In caso di successo la funzione aggiorna anche i seguenti campi di
   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
@@ -2775,18 +2921,21 @@ attraverso una \func{exit}.
 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}
 
-  \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}
@@ -2922,13 +3071,14 @@ 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 \index{directory~di~lavoro} 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.
+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
@@ -2964,16 +3114,18 @@ 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
 \index{directory~di~lavoro} 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
-\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} con una \func{sleep}.
+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 \myfunc{dir\_scan}, già utilizzata (e
@@ -3042,15 +3194,15 @@ 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}
+\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
@@ -3059,14 +3211,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
 \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                       
@@ -3077,14 +3229,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
@@ -3093,21 +3245,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
 \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      
 
@@ -3116,7 +3268,7 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{Verbatim}
+\end{Console}
 %$
 
 
@@ -3167,7 +3319,7 @@ 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 ssis trova posto migliore, copy_from_process e
+% 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 
@@ -3187,19 +3339,19 @@ 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_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 \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}.
+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 \itindex{race~condition} \textit{race condition}.} che
+essa ritorni un errore quando usata con i flag di \const{O\_CREAT} e
+\const{O\_EXCL}. In tal modo la creazione di un \textsl{file di lock} può
+essere eseguita atomicamente, il processo che crea il file con successo si può
+considerare come titolare del lock (e della risorsa ad esso associata) mentre
+il rilascio si può eseguire con una chiamata ad \func{unlink}.
 
 Un esempio dell'uso di questa funzione è mostrato dalle funzioni
 \func{LockFile} ed \func{UnlockFile} riportate in fig.~\ref{fig:ipc_file_lock}
@@ -3362,22 +3514,24 @@ nessun inconveniente.
 \label{sec:ipc_mmap_anonymous}
 
 \itindbeg{memory~mapping} Abbiamo già visto che quando i processi sono
-\textsl{correlati}\footnote{se cioè hanno almeno un progenitore comune.} l'uso
-delle \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.
+\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.
 
 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.
+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
@@ -3438,70 +3592,67 @@ richiesto è che:
 \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.
+è 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 uno \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 in appositi 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 \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
-  \url{http://www.geocities.com/wronski12/posix_ipc/index.html}.} 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.
+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 nella \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{Example}
 mqueue   /dev/mqueue       mqueue    defaults        0      0
-\end{verbatim}
+\end{Example}
 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
@@ -3509,54 +3660,63 @@ 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 per un errore; nel quel caso \var{errno} assumerà i
-    valori:
-    \begin{errlist}
-    \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
-      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{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}, \errval{EINTR} ed \errval{ENFILE}.
+
+\fdesc{Apre una coda di messaggi POSIX impostandone le caratteristiche.}
 }
-\end{functions}
+
+{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{nel caso di Linux si tratta in effetti proprio di un
-  normale file descriptor; pertanto, anche se questo comportamento non è
-  portabile, lo si può tenere sotto osservazione con le funzioni dell'I/O
-  multiplexing (vedi sez.~\ref{sec:file_multiplexing}) come possibile
-  alternativa all'uso dell'interfaccia di notifica di \func{mq\_notify} (che
-  vedremo a breve).} Se la coda esiste già il descrittore farà riferimento
-allo stesso oggetto, consentendo così la comunicazione fra due processi
-diversi.
+\type{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
-sez.~\ref{sec:file_open_close} dei quali però \func{mq\_open} riconosce solo i
-seguenti:
+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
@@ -3588,15 +3748,17 @@ Se la coda non esiste e la si vuole creare si deve specificare
 creazione con l'argomento \param{mode};\footnote{fino al 2.6.14 per un bug i
   valori della \textit{umask} del processo non venivano applicati a questi
   permessi.} i valori di quest'ultimo sono identici a quelli usati per
-\func{open}, anche se per le code di messaggi han senso solo i permessi di
-lettura e scrittura. Oltre ai permessi di creazione possono essere specificati
-anche gli attributi specifici della coda tramite l'argomento \param{attr};
-quest'ultimo è un puntatore ad una apposita struttura \struct{mq\_attr}, la
-cui definizione è riportata in fig.~\ref{fig:ipc_mq_attr}.
+\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]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
@@ -3609,51 +3771,96 @@ Per la creazione della coda i campi della struttura che devono essere
 specificati sono \var{mq\_maxmsg} e \var{mq\_msgsize}, che indicano
 rispettivamente il numero massimo di messaggi che può contenere e la
 dimensione massima di un messaggio. Il valore dovrà essere positivo e minore
-dei rispettivi limiti di sistema \const{MQ\_MAXMSG} e \const{MQ\_MSGSIZE},
-altrimenti la funzione fallirà con un errore di \errcode{EINVAL}.
-Se \param{attr} è un puntatore nullo gli attributi della coda saranno
-impostati ai valori predefiniti.
+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[\sysctlfile{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 è \const{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 \itindex{capability} \textit{capability}
+  \const{CAP\_SYS\_RESOURCE}) ma \const{HARD\_MAX} resta comunque non
+  superabile.
+
+\item[\sysctlfile{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 valore viene ignorato dai
+  processi con privilegi amministrativi (la \itindex{capability}
+  \textit{capability} \const{CAP\_SYS\_RESOURCE}).
+
+\item[\sysctlfile{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
+  \itindex{capability} \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 da tutte le code di messaggi
+appartenenti ai processi di uno stesso utente, identificato dal loro
+\textit{real user ID}.
 
 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 per un errore;
-  nel quel caso \var{errno} assumerà i valori \errval{EBADF} o
-  \errval{EINTR}.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_close(mqd\_t mqdes)}
 
-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.
+\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)}
+
+\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 stessi valori riportati da \func{unlink}.
+}  
+\end{funcproto}
 
 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. 
+\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
@@ -3670,20 +3877,21 @@ riavvio del sistema.
 Come accennato ad ogni coda di messaggi è associata una struttura
 \struct{mq\_attr}, che può essere letta e modificata attraverso le due
 funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \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,
+
+\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
@@ -3705,22 +3913,21 @@ 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}.
 
-  
-  \bodydesc{Le funzioni restituiscono 0 in caso di successo e $-1$ per un
-    errore; nel quel caso \var{errno} assumerà i valori:
-    \begin{errlist}
+\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.}
+\fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
+    msg\_len, unsigned msg\_prio, const struct timespec *abs\_timeout)}
+\fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo
+  specificato}
+}
+
+{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{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
@@ -3730,9 +3937,11 @@ Per inserire messaggi su di una coda sono previste due funzioni,
       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}, \errval{ENOMEM} ed \errval{EINTR}.}
-\end{functions}
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{ENOMEM} ed \errval{EINTR} nel loro
+  significato generico.
+}
+\end{funcproto}
 
 Entrambe le funzioni richiedono un puntatore al testo del messaggio
 nell'argomento \param{msg\_ptr} e la relativa lunghezza in \param{msg\_len}.
@@ -3818,8 +4027,6 @@ 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
 immediatamente con l'errore \errcode{EAGAIN}. Anche in questo caso la sola
@@ -4121,8 +4328,8 @@ 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 della
-\acr{glibc} che usano questa nuova infrastruttura per quella che viene quella
-che viene chiamata \textit{New Posix Thread Library}, sono state implementate
+\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
@@ -4241,7 +4448,7 @@ 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.
+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
@@ -4730,7 +4937,7 @@ testo alla terminazione di quest'ultimo.
 % 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 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
@@ -4752,7 +4959,7 @@ testo alla terminazione di quest'ultimo.
 % 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 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
@@ -4765,17 +4972,20 @@ testo alla terminazione di quest'ultimo.
 % 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 has
+% 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 it
 % LocalWords:  xffffffff Arrays owner perms Queues used bytes messages device
 % LocalWords:  Cannot find such Segments getter Signal MSGMAXSIZE been stable
-% LocalWords:  for now it's break Berlin sources Let's an accidental feature
+% LocalWords:  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
+% 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
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE