Materuale vario, correzioni e aggiornamenti sulla code di messaggi
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index a5955eae676deecabacf7dfee5346591b7b9d980..48cc7b89ae2b35f627671433bce6fc2ff4b0027c 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
 %% 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",
 %% 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",
@@ -200,9 +200,9 @@ Un programma che deve essere eseguito come \textit{CGI} deve rispondere a
 delle caratteristiche specifiche, esso infatti non viene lanciato da una
 shell, ma dallo stesso web server, alla richiesta di una specifica URL, che di
 solito ha la forma:
 delle caratteristiche specifiche, esso infatti non viene lanciato da una
 shell, ma dallo stesso web server, alla richiesta di una specifica URL, che di
 solito ha la forma:
-\begin{Verbatim}
+\begin{Example}
 http://www.sito.it/cgi-bin/programma?argomento
 http://www.sito.it/cgi-bin/programma?argomento
-\end{Verbatim}
+\end{Example}
 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
 che ne descrive il \textit{mime-type}) sullo \textit{standard output}, in modo
 che il server web possa reinviarlo al browser che ha effettuato la richiesta,
 ed il risultato dell'elaborazione deve essere presentato (con una intestazione
 che ne descrive il \textit{mime-type}) sullo \textit{standard output}, in modo
 che il server web possa reinviarlo al browser che ha effettuato la richiesta,
@@ -3610,13 +3610,13 @@ 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
 
 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, che funzionano come su dei file normali; questo
+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
 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.
+può facilmente verificare con il comando \cmd{strace}, sia per la memoria
+condivisa che per le code di messaggi varie \textit{system call} utilizzate da
+Linux corrispondono in realtà a quelle ordinarie dei file, essendo detti
+oggetti realizzati come tali 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
@@ -3650,9 +3650,9 @@ disponibili a partire dalla versione 2.3.4 delle medesime.
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
 \texttt{mqueue} montato sulla directory \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 sulla directory \file{/dev/mqueue}; questo può essere
 fatto aggiungendo ad \conffile{/etc/fstab} una riga come:
-\begin{Example}
+\begin{FileExample}[label=/etc/fstab]
 mqueue   /dev/mqueue       mqueue    defaults        0      0
 mqueue   /dev/mqueue       mqueue    defaults        0      0
-\end{Example}
+\end{FileExample}
 ed esso sarà utilizzato come radice sulla quale vengono risolti i nomi delle
 code di messaggi che iniziano con una ``\texttt{/}''. Le opzioni di mount
 accettate sono \texttt{uid}, \texttt{gid} e \texttt{mode} che permettono
 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
@@ -3794,8 +3794,8 @@ dei limiti sono:
   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
   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}
+  rispettivamente \const{INT\_MAX} e 8192). Questo limite viene ignorato dai
+  processi con privilegi amministrativi (con la \itindex{capability}
   \textit{capability} \const{CAP\_SYS\_RESOURCE}).
 
 \item[\sysctlfile{fs/mqueue/queues\_max}] Indica il numero massimo di code di
   \textit{capability} \const{CAP\_SYS\_RESOURCE}).
 
 \item[\sysctlfile{fs/mqueue/queues\_max}] Indica il numero massimo di code di
@@ -3808,9 +3808,9 @@ dei limiti sono:
 
 Infine sulle code di messaggi si applica il limite imposto sulla risorsa
 \const{RLIMIT\_MSGQUEUE} (vedi sez.~\ref{sec:sys_resource_limit}) che indica
 
 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}.
+lo spazio massimo (in byte) occupabile dall'insieme di tutte le code di
+messaggi appartenenti ai processi di uno stesso utente, che viene identificato
+in base al \textit{real user ID} degli stessi.
 
 Quando l'accesso alla coda non è più necessario si può chiudere il relativo
 descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
 
 Quando l'accesso alla coda non è più necessario si può chiudere il relativo
 descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
@@ -3851,7 +3851,12 @@ funzione di sistema \funcd{mq\_unlink}, il cui prototipo è:
 }
 
 {La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
 }
 
 {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}.
+  caso \var{errno} assumerà gli uno dei valori:
+    \begin{errlist}
+    \item[\errcode{EACCES}] non si hanno i permessi per cancellare la coda.
+    \item[\errcode{ENAMETOOLONG}] il nome indicato è troppo lungo.
+    \item[\errcode{ENOENT}] non esiste una coda con il nome indicato.
+  \end{errlist}
 }  
 \end{funcproto}
 
 }  
 \end{funcproto}
 
@@ -3870,7 +3875,7 @@ di essa.  Allo stesso modo una coda ed i suoi contenuti resteranno disponibili
 all'interno del sistema anche quando quest'ultima non è aperta da nessun
 processo (questa è una delle differenze più rilevanti nei confronti di
 \textit{pipe} e \textit{fifo}).  La sola differenza fra code di messaggi POSIX
 all'interno del sistema anche quando quest'ultima non è aperta da nessun
 processo (questa è una delle differenze più rilevanti nei confronti di
 \textit{pipe} e \textit{fifo}).  La sola differenza fra code di messaggi POSIX
-e file normali è che, essendo il filesystem delle code di messaggi virtuale e
+e file normali è che, essendo il filesystem delle code di messaggi virtuale, e
 basato su oggetti interni al kernel, il suo contenuto viene perduto con il
 riavvio del sistema.
 
 basato su oggetti interni al kernel, il suo contenuto viene perduto con il
 riavvio del sistema.
 
@@ -3894,33 +3899,44 @@ funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
 \end{funcproto}
 
 La funzione \func{mq\_getattr} legge i valori correnti degli attributi della
 \end{funcproto}
 
 La funzione \func{mq\_getattr} legge i valori correnti degli attributi della
-coda nella struttura puntata da \param{mqstat}; di questi l'unico relativo
-allo stato corrente della coda è \var{mq\_curmsgs} che indica il numero di
-messaggi da essa contenuti, gli altri indicano le caratteristiche generali
-della stessa.
+coda \param{mqdes} nella struttura \struct{mq\_attr} puntata
+da \param{mqstat}; di questi l'unico relativo allo stato corrente della coda è
+\var{mq\_curmsgs} che indica il numero di messaggi da essa contenuti, gli
+altri indicano le caratteristiche generali della stessa impostate in fase di
+apertura.
 
 La funzione \func{mq\_setattr} permette di modificare gli attributi di una
 
 La funzione \func{mq\_setattr} permette di modificare gli attributi di una
-coda tramite i valori contenuti nella struttura puntata da \param{mqstat}, ma
-può essere modificato solo il campo \var{mq\_flags}, gli altri campi vengono
-ignorati. In particolare i valori di \var{mq\_maxmsg} e \var{mq\_msgsize}
-possono essere specificati solo in fase ci creazione della coda.  Inoltre i
-soli valori possibili per \var{mq\_flags} sono 0 e \const{O\_NONBLOCK}, per
-cui alla fine la funzione può essere utilizzata solo per abilitare o
-disabilitare la modalità non bloccante. L'argomento \param{omqstat} viene
-usato, quando diverso da \val{NULL}, per specificare l'indirizzo di una
-struttura su cui salvare i valori degli attributi precedenti alla chiamata
-della funzione.
-
-Per inserire messaggi su di una coda sono previste due funzioni,
-\funcd{mq\_send} e \funcd{mq\_timedsend}, i cui prototipi sono:
+coda (indicata da \param{mqdes}) tramite i valori contenuti nella struttura
+\struct{mq\_attr} puntata da \param{mqstat}, ma può essere modificato solo il
+campo \var{mq\_flags}, gli altri campi vengono comunque ignorati.
+
+In particolare i valori di \var{mq\_maxmsg} e \var{mq\_msgsize} possono essere
+specificati solo in fase ci creazione della coda.  Inoltre i soli valori
+possibili per \var{mq\_flags} sono 0 e \const{O\_NONBLOCK}, per cui alla fine
+la funzione può essere utilizzata solo per abilitare o disabilitare la
+modalità non bloccante. L'argomento \param{omqstat} viene usato, quando
+diverso da \val{NULL}, per specificare l'indirizzo di una struttura su cui
+salvare i valori degli attributi precedenti alla chiamata della funzione.
+
+Per inserire messaggi su di una coda sono previste due funzioni di sistema,
+\funcd{mq\_send} e \funcd{mq\_timedsend}. In realtà su Linux la \textit{system
+  call} è soltanto \func{mq\_timedsend}, mentre \func{mq\_send} viene
+implementata come funzione di libreria che si appoggia alla
+precedente. Inoltre \func{mq\_timedsend} richiede che sia definita la macro
+\macro{\_XOPEN\_SOURCE} ad un valore pari ad almeno \texttt{600} o la macro
+\macro{\_POSIX\_C\_SOURCE} ad un valore uguale o maggiore di \texttt{200112L}.
+I rispettivi prototipi sono:
 
 \begin{funcproto}{
 \fhead{mqueue.h}
 \fdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
     unsigned int msg\_prio)}
 \fdesc{Esegue l'inserimento di un messaggio su una coda.}
 
 \begin{funcproto}{
 \fhead{mqueue.h}
 \fdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
     unsigned int msg\_prio)}
 \fdesc{Esegue l'inserimento di un messaggio su una coda.}
+\fhead{mqueue.h}
+\fhead{time.h}
 \fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
 \fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
-    msg\_len, unsigned msg\_prio, const struct timespec *abs\_timeout)}
+    msg\_len, unsigned int msg\_prio,\\ 
+\phantom{int mq\_timedsend(}const struct timespec *abs\_timeout)}
 \fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo
   specificato}
 }
 \fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo
   specificato}
 }
@@ -3930,83 +3946,92 @@ Per inserire messaggi su di una coda sono previste due funzioni,
   \begin{errlist}
     \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
       coda è piena.
   \begin{errlist}
     \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
       coda è piena.
-    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
-      eccede il limite impostato per la coda.
+    \item[\errcode{EBADF}] si specificato un file descriptor non valido.
     \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_len}, o un valore di \param{msg\_prio} fuori dai limiti, o
       un valore non valido per \param{abs\_timeout}.
     \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_len}, o un valore di \param{msg\_prio} fuori dai limiti, o
       un valore non valido per \param{abs\_timeout}.
+    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
+      eccede il limite impostato per la coda.
     \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
     \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
-      effettuato entro il tempo stabilito.
+      effettuato entro il tempo stabilito (solo \func{mq\_timedsend}).
   \end{errlist}
   \end{errlist}
-  ed inoltre \errval{EBADF}, \errval{ENOMEM} ed \errval{EINTR} nel loro
-  significato generico.
-}
+  ed inoltre \errval{EBADF}, \errval{EINTR} nel suo significato generico.  }
 \end{funcproto}
 
 \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 ad un buffer in memoria
+contenente il testo del messaggio da inserire nella coda \param{mqdes}
+nell'argomento \param{msg\_ptr}, e la relativa lunghezza in \param{msg\_len}.
 Se quest'ultima eccede la dimensione massima specificata da \var{mq\_msgsize}
 le funzioni ritornano immediatamente con un errore di \errcode{EMSGSIZE}.
 
 Se quest'ultima eccede la dimensione massima specificata da \var{mq\_msgsize}
 le funzioni ritornano immediatamente con un errore di \errcode{EMSGSIZE}.
 
-L'argomento \param{msg\_prio} indica la priorità dell'argomento; i messaggi di
-priorità maggiore vengono inseriti davanti a quelli di priorità inferiore (e
-quindi saranno riletti per primi). A parità del valore della priorità il
-messaggio sarà inserito in coda a tutti quelli con la stessa priorità. Il
-valore della priorità non può eccedere il limite di sistema
-\const{MQ\_PRIO\_MAX}, che nel caso è pari a 32768.
+L'argomento \param{msg\_prio} indica la priorità dell'argomento, che, essendo
+definito come \ctyp{unsigned int}, è sempre un intero positivo. I messaggi di
+priorità maggiore vengono inseriti davanti a quelli di priorità inferiore, e
+quindi saranno riletti per primi. A parità del valore della priorità il
+messaggio sarà inserito in coda a tutti quelli che hanno la stessa priorità
+che quindi saranno letti con la politica di una \textit{fifo}. Il valore della
+priorità non può eccedere il limite di sistema \const{MQ\_PRIO\_MAX}, che al
+momento è pari a 32768.
 
 Qualora la coda sia piena, entrambe le funzioni si bloccano, a meno che non
 
 Qualora la coda sia piena, entrambe le funzioni si bloccano, a meno che non
-sia stata selezionata in fase di apertura la modalità non
-bloccante,\footnote{o si sia impostato il flag \const{O\_NONBLOCK} sul file
-  descriptor della coda.} nel qual caso entrambe ritornano \errcode{EAGAIN}.
-La sola differenza fra le due funzioni è che la seconda, passato il tempo
-massimo impostato con l'argomento \param{abs\_timeout},\footnote{deve essere
-  specificato un tempo assoluto tramite una struttura \struct{timespec} (vedi
-  fig.~\ref{fig:sys_timespec_struct}) indicato in numero di secondi e
-  nanosecondi a partire dal 1 gennaio 1970.} ritorna comunque con un errore di
-\errcode{ETIMEDOUT}, se invece il tempo è già scaduto al momento della
-chiamata e la coda è vuota la funzione ritorna immediatamente.
+sia stata selezionata in fase di apertura della stessa la modalità non
+bloccante o non si sia impostato il flag \const{O\_NONBLOCK} sul file
+descriptor della coda, nel qual caso entrambe ritornano con un codice di
+errore di \errcode{EAGAIN}.
+
+La sola differenza fra le due funzioni è che \func{mq\_timedsend}, passato il
+tempo massimo impostato con l'argomento \param{abs\_timeout}, ritorna comunque
+con un errore di \errcode{ETIMEDOUT}, se invece il tempo è già scaduto al
+momento della chiamata e la coda è piena la funzione ritorna
+immediatamente. Il valore di \param{abs\_timeout} deve essere specificato come
+tempo assoluto tramite una struttura \struct{timespec} (vedi
+fig.~\ref{fig:sys_timespec_struct}) indicato in numero di secondi e
+nanosecondi a partire dal 1 gennaio 1970.
 
 Come per l'inserimento, anche per l'estrazione dei messaggi da una coda sono
 
 Come per l'inserimento, anche per l'estrazione dei messaggi da una coda sono
-previste due funzioni, \funcd{mq\_receive} e \funcd{mq\_timedreceive}, i cui
-prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{ssize\_t mq\_receive(mqd\_t mqdes, char *msg\_ptr, size\_t
-    msg\_len, unsigned int *msg\_prio)}   
-  Effettua la ricezione di un messaggio da una coda.
-  
-  \funcdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
-    msg\_len, unsigned int *msg\_prio, const struct timespec *abs\_timeout)}
-  Effettua la ricezione di un messaggio da una coda entro il tempo
-  \param{abs\_timeout}.
-  
-  \bodydesc{Le funzioni restituiscono il numero di byte del messaggio in caso
-    di successo e -1 in caso di errore; nel quel caso \var{errno} assumerà i
-    valori:
-    \begin{errlist}
+previste due funzioni di sistema, \funcd{mq\_receive} e
+\funcd{mq\_timedreceive}. Anche in questo caso su Linux soltanto
+\func{mq\_timedreceive} è effettivamente, una \textit{system call} e per
+usarla devono essere definite le opportune macro come per
+\func{mq\_timedsend}. I rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{mqueue.h} 
+\fdecl{ssize\_t mq\_receive(mqd\_t mqdes, char *msg\_ptr, size\_t
+    msg\_len, unsigned int *msg\_prio)} 
+\fdesc{Effettua la ricezione di un messaggio da una coda.}
+\fhead{mqueue.h} 
+\fhead{time.h} 
+\fdecl{ssize\_t mq\_timedreceive(mqd\_t mqdes, char *msg\_ptr, size\_t
+    msg\_len,\\ 
+\phantom{ssize\_t  mq\_timedreceive(}unsigned int *msg\_prio, const struct timespec
+*abs\_timeout)} 
+\fdesc{Riceve un messaggio da una coda entro un limite di tempo.}
+}
+{Entrambe le funzioni ritornano il numero di byte del messaggio in caso di
+  successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei
+  valori:
+  \begin{errlist}
     \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
       coda è vuota.
     \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
       coda è vuota.
-    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio sulla coda eccede il
-      valore \param{msg\_len} specificato per la ricezione.
     \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_ptr}, o un valore non valido per \param{abs\_timeout}.
     \item[\errcode{EINVAL}] si è specificato un valore nullo per
       \param{msg\_ptr}, o un valore non valido per \param{abs\_timeout}.
+    \item[\errcode{EMSGSIZE}] la lunghezza del messaggio sulla coda eccede il
+      valore \param{msg\_len} specificato per la ricezione.
     \item[\errcode{ETIMEDOUT}] la ricezione del messaggio non è stata
       effettuata entro il tempo stabilito.
     \item[\errcode{ETIMEDOUT}] la ricezione del messaggio non è stata
       effettuata entro il tempo stabilito.
-    \end{errlist}    
-    ed inoltre \errval{EBADF}, \errval{EINTR}, \errval{ENOMEM}, o
-    \errval{EINVAL}.}
-\end{functions}
+  \end{errlist}
+  ed inoltre \errval{EBADF} o \errval{EINTR} nel loro significato generico.  }
+\end{funcproto}
 
 
-La funzione estrae dalla coda il messaggio a priorità più alta, o il più
-vecchio fra quelli della stessa priorità. Una volta ricevuto il messaggio
-viene tolto dalla coda e la sua dimensione viene restituita come valore di
-ritorno.\footnote{si tenga presente che 0 è una dimensione valida e che la
-  condizione di errore è restituita dal valore -1; Stevens in \cite{UNP2} fa
-  notare che questo è uno dei casi in cui vale ciò che lo standard
-  \textsl{non} dice, una dimensione nulla infatti, pur non essendo citata, non
-  viene proibita.}
+La funzione estrae dalla coda \param{mqdes} il messaggio a priorità più alta,
+o il più vecchio fra quelli della stessa priorità. Una volta ricevuto il
+messaggio viene tolto dalla coda e la sua dimensione viene restituita come
+valore di ritorno; si tenga presente che 0 è una dimensione valida e che la
+condizione di errore è indicata soltanto da un valore di
+$-1$.\footnote{Stevens in \cite{UNP2} fa notare che questo è uno dei casi in
+  cui vale ciò che lo standard \textsl{non} dice, una dimensione nulla
+  infatti, pur non essendo citata, non viene proibita.}
 
 Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere
 il messaggio, entrambe le funzioni, al contrario di quanto avveniva nelle code
 
 Se la dimensione specificata da \param{msg\_len} non è sufficiente a contenere
 il messaggio, entrambe le funzioni, al contrario di quanto avveniva nelle code
@@ -4046,39 +4071,48 @@ superare in parte questo problema.
 Una caratteristica specifica delle code di messaggi POSIX è la possibilità di
 usufruire di un meccanismo di notifica asincrono; questo può essere attivato
 usando la funzione \funcd{mq\_notify}, il cui prototipo è:
 Una caratteristica specifica delle code di messaggi POSIX è la possibilità di
 usufruire di un meccanismo di notifica asincrono; questo può essere attivato
 usando la funzione \funcd{mq\_notify}, il cui prototipo è:
-\begin{prototype}{mqueue.h}
-{int mq\_notify(mqd\_t mqdes, const struct sigevent *notification)}
 
 
-Attiva il meccanismo di notifica per la coda \param{mqdes}.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà i valori: 
-    \begin{errlist}
-    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_notify(mqd\_t mqdes, const struct sigevent *notification)}
+
+\fdesc{Attiva il meccanismo di notifica per una coda.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EBADF}] il descrittore non fa riferimento ad una coda di
       messaggi.
     \item[\errcode{EBADF}] il descrittore non fa riferimento ad una coda di
       messaggi.
-    \end{errlist}}
-\end{prototype}
+    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+    \item[\errcode{EINVAL}] si è richiesto un meccanismo di notifica invalido
+      o specificato nella notifica con i segnali il valore di un segnale non
+      esistente.
+  \end{errlist}
+  ed inoltre \errval{ENOMEM} nel suo significato generico.
+  
+}  
+\end{funcproto}
 
 Il meccanismo di notifica permette di segnalare in maniera asincrona ad un
 
 Il meccanismo di notifica permette di segnalare in maniera asincrona ad un
-processo la presenza di dati sulla coda, in modo da evitare la necessità di
-bloccarsi nell'attesa. Per far questo un processo deve registrarsi con la
-funzione \func{mq\_notify}, ed il meccanismo è disponibile per un solo
-processo alla volta per ciascuna coda.
+processo la presenza di dati sulla coda indicata da \param{mqdes}, in modo da
+evitare la necessità di bloccarsi nell'attesa. Per far questo un processo deve
+registrarsi con la funzione \func{mq\_notify}, ed il meccanismo è disponibile
+per un solo processo alla volta per ciascuna coda.
 
 
-Il comportamento di \func{mq\_notify} dipende dal valore dell'argomento
-\param{notification}, che è un puntatore ad una apposita struttura
+Il comportamento di \func{mq\_notify} dipende dai valori passati con
+l'argomento \param{notification}, che è un puntatore ad una apposita struttura
 \struct{sigevent}, (definita in fig.~\ref{fig:struct_sigevent}) introdotta
 dallo standard POSIX.1b per gestire la notifica di eventi; per altri dettagli
 \struct{sigevent}, (definita in fig.~\ref{fig:struct_sigevent}) introdotta
 dallo standard POSIX.1b per gestire la notifica di eventi; per altri dettagli
-si può vedere quanto detto in sez.~\ref{sec:sig_timer_adv} a proposito
-dell'uso della stessa struttura per la notifica delle scadenze dei
+su di essa si può rivedere quanto detto in sez.~\ref{sec:sig_timer_adv} a
+proposito dell'uso della stessa struttura per la notifica delle scadenze dei
 \textit{timer}.
 
 Attraverso questa struttura si possono impostare le modalità con cui viene
 effettuata la notifica nel campo \var{sigev\_notify}, che può assumere i
 \textit{timer}.
 
 Attraverso questa struttura si possono impostare le modalità con cui viene
 effettuata la notifica nel campo \var{sigev\_notify}, che può assumere i
-valori di tab.~\ref{tab:sigevent_sigev_notify}.\footnote{la pagina di manuale
-  riporta soltanto i primi tre (inizialmente era possibile solo
-  \const{SIGEV\_SIGNAL}).} Il metodo consigliato è quello di usare
+valori di tab.~\ref{tab:sigevent_sigev_notify}; fra questi la pagina di
+manuale riporta soltanto i primi tre, ed inizialmente era possibile solo
+\const{SIGEV\_SIGNAL}. Il metodo consigliato è quello di usare
 \const{SIGEV\_SIGNAL} usando il campo \var{sigev\_signo} per indicare il quale
 segnale deve essere inviato al processo. Inoltre il campo \var{sigev\_value} è
 un puntatore ad una struttura \struct{sigval} (definita in
 \const{SIGEV\_SIGNAL} usando il campo \var{sigev\_signo} per indicare il quale
 segnale deve essere inviato al processo. Inoltre il campo \var{sigev\_value} è
 un puntatore ad una struttura \struct{sigval} (definita in
@@ -4092,12 +4126,12 @@ La funzione registra il processo chiamante per la notifica se
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
 inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
 che un solo processo alla volta può essere registrato, la funzione fallisce
 \param{notification} punta ad una struttura \struct{sigevent} opportunamente
 inizializzata, o cancella una precedente registrazione se è \val{NULL}. Dato
 che un solo processo alla volta può essere registrato, la funzione fallisce
-con \errcode{EBUSY} se c'è un altro processo già registrato.\footnote{questo
-  significa anche che se si registra una notifica con \const{SIGEV\_NONE} il
-  processo non la riceverà, ma impedirà anche che altri possano registrarsi
-  per poterlo fare.}  Si tenga presente inoltre che alla chiusura del
-descrittore associato alla coda (e quindi anche all'uscita del processo) ogni
-eventuale registrazione di notifica presente viene cancellata.
+con \errcode{EBUSY} se c'è un altro processo già registrato. Questo significa
+anche che se si registra una notifica con \const{SIGEV\_NONE} il processo non
+la riceverà, ma impedirà anche che altri possano registrarsi per poterlo fare.
+Si tenga presente inoltre che alla chiusura del descrittore associato alla
+coda (e quindi anche all'uscita del processo) ogni eventuale registrazione di
+notifica presente viene cancellata.
 
 La notifica del segnale avviene all'arrivo di un messaggio in una coda vuota
 (cioè solo se sulla coda non ci sono messaggi) e se non c'è nessun processo
 
 La notifica del segnale avviene all'arrivo di un messaggio in una coda vuota
 (cioè solo se sulla coda non ci sono messaggi) e se non c'è nessun processo
@@ -4112,8 +4146,8 @@ la coda diventa disponibile per una ulteriore registrazione.  Questo comporta
 che se si vuole mantenere il meccanismo di notifica occorre ripetere la
 registrazione chiamando nuovamente \func{mq\_notify} all'interno del gestore
 del segnale di notifica. A differenza della situazione simile che si aveva con
 che se si vuole mantenere il meccanismo di notifica occorre ripetere la
 registrazione chiamando nuovamente \func{mq\_notify} all'interno del gestore
 del segnale di notifica. A differenza della situazione simile che si aveva con
-i segnali non affidabili,\footnote{l'argomento è stato affrontato in
-  \ref{sec:sig_semantics}.} questa caratteristica non configura una
+i segnali non affidabili (l'argomento è stato affrontato in
+\ref{sec:sig_semantics}) questa caratteristica non configura una
 \itindex{race~condition} \textit{race condition} perché l'invio di un segnale
 avviene solo se la coda è vuota; pertanto se si vuole evitare di correre il
 rischio di perdere eventuali ulteriori segnali inviati nel lasso di tempo che
 \itindex{race~condition} \textit{race condition} perché l'invio di un segnale
 avviene solo se la coda è vuota; pertanto se si vuole evitare di correre il
 rischio di perdere eventuali ulteriori segnali inviati nel lasso di tempo che
@@ -4124,13 +4158,12 @@ L'invio del segnale di notifica avvalora alcuni campi di informazione
 restituiti al gestore attraverso la struttura \struct{siginfo\_t} (definita in
 fig.~\ref{fig:sig_siginfo_t}). In particolare \var{si\_pid} viene impostato al
 valore del \ids{PID} del processo che ha emesso il segnale, \var{si\_uid}
 restituiti al gestore attraverso la struttura \struct{siginfo\_t} (definita in
 fig.~\ref{fig:sig_siginfo_t}). In particolare \var{si\_pid} viene impostato al
 valore del \ids{PID} del processo che ha emesso il segnale, \var{si\_uid}
-all'userid effettivo, \var{si\_code} a \const{SI\_MESGQ}, e \var{si\_errno} a
-0. Questo ci dice che, se si effettua la ricezione dei messaggi usando
-esclusivamente il meccanismo di notifica, è possibile ottenere le informazioni
-sul processo che ha inserito un messaggio usando un gestore per il segnale in
-forma estesa.\footnote{di nuovo si faccia riferimento a quanto detto al
-  proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.}
-
+all'\textsl{user-ID} effettivo, \var{si\_code} a \const{SI\_MESGQ}, e
+\var{si\_errno} a 0. Questo ci dice che, se si effettua la ricezione dei
+messaggi usando esclusivamente il meccanismo di notifica, è possibile ottenere
+le informazioni sul processo che ha inserito un messaggio usando un gestore
+per il segnale in forma estesa, di nuovo si faccia riferimento a quanto detto
+al proposito in sez.~\ref{sec:sig_sigaction} e sez.~\ref{sec:sig_real_time}.
 
 
 \subsection{Memoria condivisa}
 
 
 \subsection{Memoria condivisa}
@@ -4143,18 +4176,19 @@ suoi contenuti in memoria, che viene attivato abilitando l'opzione
 \texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
 
 Per potere utilizzare l'interfaccia POSIX per la memoria condivisa la
 \texttt{CONFIG\_TMPFS} in fase di compilazione del kernel.
 
 Per potere utilizzare l'interfaccia POSIX per la memoria condivisa la
-\acr{glibc}\footnote{le funzioni sono state introdotte con la versione 2.2.}
-richiede di compilare i programmi con l'opzione \code{-lrt}; inoltre è
-necessario che in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs};
-questo di norma viene fatto aggiungendo una riga del tipo di:
-\begin{verbatim}
+\acr{glibc} (le funzioni sono state introdotte con la versione 2.2) richiede
+di compilare i programmi con l'opzione \code{-lrt}; inoltre è necessario che
+in \file{/dev/shm} sia montato un filesystem \texttt{tmpfs}; questo di norma
+viene fatto aggiungendo una riga del tipo di:
+\begin{FileExample}[label=/etc/fstab]
 tmpfs   /dev/shm        tmpfs   defaults        0      0
 tmpfs   /dev/shm        tmpfs   defaults        0      0
-\end{verbatim}
-ad \conffile{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
-dove si vuole, per usarlo come RAM disk, con un comando del tipo:
-\begin{verbatim}
+\end{FileExample}
+ad \conffile{/etc/fstab}. In realtà si può montare un filesystem
+\texttt{tmpfs} dove si vuole, per usarlo come RAM disk, con un comando del
+tipo:
+\begin{Example}
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
-\end{verbatim}
+\end{Example}
 
 Il filesystem riconosce, oltre quelle mostrate, le opzioni \texttt{uid} e
 \texttt{gid} che identificano rispettivamente utente e gruppo cui assegnarne
 
 Il filesystem riconosce, oltre quelle mostrate, le opzioni \texttt{uid} e
 \texttt{gid} che identificano rispettivamente utente e gruppo cui assegnarne
@@ -4982,10 +5016,10 @@ testo alla terminazione di quest'ultimo.
 % 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
 % 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
+% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
-% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE