Revisione
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 69c67608adf68d9d8cca93f5c97194bc6060fd5f..978e3b19e399cad38e84949e380ac68b63530fb9 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,4 +1,4 @@
-<%% ipc.tex
+%% ipc.tex
 %%
 %% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %%
 %% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
@@ -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
 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
 
 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
@@ -1422,7 +1422,7 @@ file; il suo prototipo è:
     \var{msg\_qbytes} oltre il limite \const{MSGMNB} senza essere
     amministratore.
   \end{errlist}
     \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}
 
   generico.}
 \end{funcproto}
 
@@ -1839,7 +1839,6 @@ dei \ids{PID} da parte dei processi, un client eseguito in un momento
 successivo potrebbe ricevere un messaggio non indirizzato a lui.
 
 
 successivo potrebbe ricevere un messaggio non indirizzato a lui.
 
 
-
 \subsection{I semafori}
 \label{sec:ipc_sysv_sem}
 
 \subsection{I semafori}
 \label{sec:ipc_sysv_sem}
 
@@ -1974,7 +1973,6 @@ quanto riguarda gli altri campi invece:
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
   effettuata, viene inizializzato a zero.
 \end{itemize*}
 
-
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{.80\textwidth}
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{.80\textwidth}
@@ -2079,10 +2077,9 @@ specificata con \param{cmd}, ed opera o sull'intero insieme specificato da
 \param{semid} o sul singolo semaforo di un insieme, specificato da
 \param{semnum}. 
 
 \param{semid} o sul singolo semaforo di un insieme, specificato da
 \param{semnum}. 
 
-
 \begin{figure}[!htb]
   \footnotesize \centering
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{.80\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/semun.h}
   \end{minipage} 
   \normalsize 
@@ -2318,7 +2315,7 @@ 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:
 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{2.0cm}}
+\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
 \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
@@ -2410,7 +2407,7 @@ a queste strutture restano per compatibilità (in particolare con le vecchie
 versioni delle librerie del C, come le \acr{libc5}).
 
 \begin{figure}[!htb]
 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}
   \caption{Schema della struttura di un insieme di semafori.}
   \label{fig:ipc_sem_schema}
 \end{figure}
@@ -2635,7 +2632,7 @@ norma, significa insieme a dei semafori.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
     \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -2652,7 +2649,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:
 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
 \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
@@ -2666,7 +2663,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.
   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
 
 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
@@ -2791,13 +2788,16 @@ si ha a cuore la portabilità. Questi comandi aggiuntivi sono:
   sez.~\ref{sec:sys_resource_limit}).
 \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
   \textit{memory locking} sul segmento di memoria condivisa.  Fino al kernel
   sez.~\ref{sec:sys_resource_limit}).
 \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
   \textit{memory locking} sul segmento di memoria condivisa.  Fino al kernel
-  2.6.9 solo l'amministratore poteva utilizzare questo comando. 
+  2.6.9 solo l'amministratore poteva utilizzare questo comando in
+  corrispondenza di un segmento da lui bloccato. 
 \end{basedescript}
 
 \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
 
 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
@@ -2810,25 +2810,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 è:
 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
     \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
 
 La funzione inserisce un segmento di memoria condivisa all'interno dello
 spazio di indirizzi del processo, in modo che questo possa accedervi
@@ -2852,13 +2855,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
   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
 
 Si tenga presente però che quando si usa \val{NULL} come valore di
 \param{shmaddr}, l'indirizzo restituito da \func{shmat} può cambiare da
@@ -2867,15 +2871,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
 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
 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
 
 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
@@ -2886,8 +2892,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.
 
 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.
 \begin{itemize*}
 \item il tempo \var{shm\_atime} dell'ultima operazione di aggancio viene
   impostato al tempo corrente.
@@ -2895,7 +2909,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.
   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
 
 Come accennato in sez.~\ref{sec:proc_fork} un segmento di memoria condivisa
 agganciato ad un processo viene ereditato da un figlio attraverso una
@@ -2909,18 +2923,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 è:
 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}
 
 La funzione sgancia dallo spazio degli indirizzi del processo un segmento di
 memoria condivisa; questo viene identificato con l'indirizzo \param{shmaddr}
@@ -3056,13 +3073,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
 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
 
 Il passo successivo (\texttt{\small 30--39}) è quello di creare gli oggetti di
 intercomunicazione necessari. Si inizia costruendo (\texttt{\small 30}) la
@@ -3098,16 +3116,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
 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
 
 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
@@ -3176,15 +3196,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:
 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:
 %$
 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
 Ci sono 68 file dati
 Ci sono 3 directory
 Ci sono 0 link
@@ -3193,14 +3213,14 @@ Ci sono 0 socket
 Ci sono 0 device a caratteri
 Ci sono 0 device a blocchi
 Totale  71 file, per 489831 byte
 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:
 %$
 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                       
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
 0xffffffff 54067205   piccardi  666        4096       1                       
@@ -3211,14 +3231,14 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
 
 ------ 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:
 %$
 
 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
 Ci sono 69 file dati
 Ci sono 3 directory
 Ci sono 0 link
@@ -3227,21 +3247,21 @@ Ci sono 0 socket
 Ci sono 0 device a caratteri
 Ci sono 0 device a blocchi
 Totale  72 file, per 489887 byte
 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:
 %$
 
 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
 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:
 %$
 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      
 
 ------ Shared Memory Segments --------
 key        shmid      owner      perms      bytes      nattch     status      
 
@@ -3250,7 +3270,7 @@ key        semid      owner      perms      nsems
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
 
 ------ Message Queues --------
 key        msqid      owner      perms      used-bytes   messages    
-\end{Verbatim}
+\end{Console}
 %$
 
 
 %$
 
 
@@ -3301,7 +3321,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.
 
 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 
 % 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 
@@ -3321,19 +3341,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
 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
+  Hyerarchy 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}
 
 Un esempio dell'uso di questa funzione è mostrato dalle funzioni
 \func{LockFile} ed \func{UnlockFile} riportate in fig.~\ref{fig:ipc_file_lock}
@@ -3496,22 +3516,24 @@ nessun inconveniente.
 \label{sec:ipc_mmap_anonymous}
 
 \itindbeg{memory~mapping} Abbiamo già visto che quando i processi sono
 \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
 
 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
 
 In questo modo diventa possibile creare una memoria condivisa fra processi
 diversi, purché questi abbiano almeno un progenitore comune che ha effettuato
@@ -3560,7 +3582,7 @@ POSIX prendono come primo argomento una stringa che indica uno di questi nomi;
 lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
 possono avere o meno una corrispondenza sul filesystem; tutto quello che è
 richiesto è che:
 lo standard è molto generico riguardo l'implementazione, ed i nomi stessi
 possono avere o meno una corrispondenza sul filesystem; tutto quello che è
 richiesto è che:
-\begin{itemize*}
+\begin{itemize}
 \item i nomi devono essere conformi alle regole che caratterizzano i
   \textit{pathname}, in particolare non essere più lunghi di \const{PATH\_MAX}
   byte e terminati da un carattere nullo.
 \item i nomi devono essere conformi alle regole che caratterizzano i
   \textit{pathname}, in particolare non essere più lunghi di \const{PATH\_MAX}
   byte e terminati da un carattere nullo.
@@ -3569,31 +3591,32 @@ richiesto è che:
   nome dipende dall'implementazione.
 \item l'interpretazione di ulteriori \texttt{/} presenti nel nome dipende
   dall'implementazione.
   nome dipende dall'implementazione.
 \item l'interpretazione di ulteriori \texttt{/} presenti nel nome dipende
   dall'implementazione.
-\end{itemize*}
+\end{itemize}
 
 Data la assoluta genericità delle specifiche, il comportamento delle funzioni
 
 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 quanto riguarda le code di messaggi, tutto viene creato usando come
+radici delle opportune directory (rispettivamente \file{/dev/shm} e
+\file{/dev/mqueue}, per i dettagli si faccia riferimento a
+sez.~\ref{sec:ipc_posix_shm}, sez.~\ref{sec:ipc_posix_sem} e
+sez.~\ref{sec:ipc_posix_mq}) ed i nomi specificati nelle relative funzioni
+sono considerati come un \itindsub{pathname}{assoluto} \textit{pathname}
+assoluto (comprendente eventuali sottodirectory) rispetto a queste radici.
 
 Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti
 nell'albero dei file, e possono essere maneggiati con le usuali funzioni e
 
 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 le system call utilizzate da Linux sono le stesse
+di quelle 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
 
 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
@@ -3626,16 +3649,16 @@ relativi patch) occorre utilizzare la libreria \file{libmqueue}\footnote{i
   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
   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.}
+POSIX (in realtà l'implementazione è realizzata tramite delle opportune
+chiamate ad \func{ioctl} sui file del filesystem speciale su cui vengono
+mantenuti questi oggetti di IPC).
 
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
 \texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
 aggiungendo ad \conffile{/etc/fstab} una riga come:
 
 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}
+\begin{Example}
 mqueue   /dev/mqueue       mqueue    defaults        0      0
 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
 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
@@ -3645,20 +3668,19 @@ 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 è:
 
 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,
+
+\begin{funcproto}{
+\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)}
     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}
+
+\fdesc{Apre una coda di messaggi POSIX impostandone le caratteristiche.}
+}
+
+{La funzione ritorna il descrittore associato alla coda in caso di successo e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
       alla memoria secondo quanto specificato da \param{oflag}.
     \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e
     \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
@@ -3668,23 +3690,23 @@ di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
       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.
       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}.
-}
-\end{functions}
+  \end{errlist}
+  ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
+  \errval{EMFILE}, \errval{EINTR} ed \errval{ENFILE} 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
 
 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 la
+coda esiste già il descrittore farà riferimento allo stesso oggetto,
+consentendo così la comunicazione fra due processi diversi.
 
 La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 
 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
@@ -3730,7 +3752,7 @@ cui definizione è riportata in fig.~\ref{fig:ipc_mq_attr}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
     \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
@@ -3750,44 +3772,49 @@ impostati ai valori predefiniti.
 
 Quando l'accesso alla coda non è più necessario si può chiudere il relativo
 descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
 
 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)}
+
+\fdesc{Chiude una coda di messaggi.}
+}
 
 
-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
+{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} (e 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.
 
 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 è:
 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)}
 
 
-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
 
 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, (e 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.
 
 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
 
 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
@@ -3804,20 +3831,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:
 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)}
     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
 
 La funzione \func{mq\_getattr} legge i valori correnti degli attributi della
 coda nella struttura puntata da \param{mqstat}; di questi l'unico relativo
@@ -3839,22 +3867,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:
 
 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}
     \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}
@@ -3864,9 +3891,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.
       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}.
 
 Entrambe le funzioni richiedono un puntatore al testo del messaggio
 nell'argomento \param{msg\_ptr} e la relativa lunghezza in \param{msg\_len}.