Materuale vario, correzioni e aggiornamenti sulla code di messaggi
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index ff6e69cb673cfb8729adec98abc31087cc444065..48cc7b89ae2b35f627671433bce6fc2ff4b0027c 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -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:
-\begin{Verbatim}
+\begin{Example}
 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,
@@ -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
-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
-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
@@ -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:
-\begin{Example}
+\begin{FileExample}[label=/etc/fstab]
 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
@@ -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
-  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
@@ -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
-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 è:
@@ -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
-  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}
 
@@ -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
-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.
 
@@ -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
-coda nella struttura puntata da \param{mqstat}; di questi l'unico relativo
-allo stato corrente della coda è \var{mq\_curmsgs} che indica il numero di
-messaggi da essa contenuti, gli altri indicano le caratteristiche generali
-della stessa.
+coda \param{mqdes} nella struttura \struct{mq\_attr} puntata
+da \param{mqstat}; di questi l'unico relativo allo stato corrente della coda è
+\var{mq\_curmsgs} che indica il numero di messaggi da essa contenuti, gli
+altri indicano le caratteristiche generali della stessa impostate in fase di
+apertura.
 
 La funzione \func{mq\_setattr} permette di modificare gli attributi di una
-coda tramite i valori contenuti nella struttura puntata da \param{mqstat}, ma
-può essere modificato solo il campo \var{mq\_flags}, gli altri campi vengono
-ignorati. In particolare i valori di \var{mq\_maxmsg} e \var{mq\_msgsize}
-possono essere specificati solo in fase ci creazione della coda.  Inoltre i
-soli valori possibili per \var{mq\_flags} sono 0 e \const{O\_NONBLOCK}, per
-cui alla fine la funzione può essere utilizzata solo per abilitare o
-disabilitare la modalità non bloccante. L'argomento \param{omqstat} viene
-usato, quando diverso da \val{NULL}, per specificare l'indirizzo di una
-struttura su cui salvare i valori degli attributi precedenti alla chiamata
-della funzione.
-
-Per inserire messaggi su di una coda sono previste due funzioni,
-\funcd{mq\_send} e \funcd{mq\_timedsend}, i cui prototipi sono:
+coda (indicata da \param{mqdes}) tramite i valori contenuti nella struttura
+\struct{mq\_attr} puntata da \param{mqstat}, ma può essere modificato solo il
+campo \var{mq\_flags}, gli altri campi vengono comunque ignorati.
+
+In particolare i valori di \var{mq\_maxmsg} e \var{mq\_msgsize} possono essere
+specificati solo in fase ci creazione della coda.  Inoltre i soli valori
+possibili per \var{mq\_flags} sono 0 e \const{O\_NONBLOCK}, per cui alla fine
+la funzione può essere utilizzata solo per abilitare o disabilitare la
+modalità non bloccante. L'argomento \param{omqstat} viene usato, quando
+diverso da \val{NULL}, per specificare l'indirizzo di una struttura su cui
+salvare i valori degli attributi precedenti alla chiamata della funzione.
+
+Per inserire messaggi su di una coda sono previste due funzioni di sistema,
+\funcd{mq\_send} e \funcd{mq\_timedsend}. In realtà su Linux la \textit{system
+  call} è soltanto \func{mq\_timedsend}, mentre \func{mq\_send} viene
+implementata come funzione di libreria che si appoggia alla
+precedente. Inoltre \func{mq\_timedsend} richiede che sia definita la macro
+\macro{\_XOPEN\_SOURCE} ad un valore pari ad almeno \texttt{600} o la macro
+\macro{\_POSIX\_C\_SOURCE} ad un valore uguale o maggiore di \texttt{200112L}.
+I rispettivi prototipi sono:
 
 \begin{funcproto}{
 \fhead{mqueue.h}
 \fdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
     unsigned int msg\_prio)}
 \fdesc{Esegue l'inserimento di un messaggio su una coda.}
+\fhead{mqueue.h}
+\fhead{time.h}
 \fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
-    msg\_len, 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}
 }
@@ -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.
-    \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{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
+      eccede il limite impostato per la coda.
     \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
-      effettuato entro il tempo stabilito.
+      effettuato entro il tempo stabilito (solo \func{mq\_timedsend}).
   \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}
 
-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}.
 
-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
-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
-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{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{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.
-    \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
@@ -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 è:
-\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.
-    \end{errlist}}
-\end{prototype}
+    \item[\errcode{EBUSY}] c'è già un processo registrato per la notifica.
+    \item[\errcode{EINVAL}] si è richiesto un meccanismo di notifica invalido
+      o specificato nella notifica con i segnali il valore di un segnale non
+      esistente.
+  \end{errlist}
+  ed inoltre \errval{ENOMEM} nel suo significato generico.
+  
+}  
+\end{funcproto}
 
 Il meccanismo di notifica permette di segnalare in maniera asincrona ad un
-processo la presenza di dati sulla coda, in modo da evitare la necessità di
-bloccarsi nell'attesa. Per far questo un processo deve registrarsi con la
-funzione \func{mq\_notify}, ed il meccanismo è disponibile per un solo
-processo alla volta per ciascuna coda.
+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
-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
-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
@@ -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
-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
@@ -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
-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
@@ -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}
-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}
@@ -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
-\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
-\end{verbatim}
-ad \conffile{/etc/fstab}. In realtà si può montare un filesystem \texttt{tmpfs}
-dove si vuole, per usarlo come RAM disk, con un comando del tipo:
-\begin{verbatim}
+\end{FileExample}
+ad \conffile{/etc/fstab}. In realtà si può montare un filesystem
+\texttt{tmpfs} dove si vuole, per usarlo come RAM disk, con un comando del
+tipo:
+\begin{Example}
 mount -t tmpfs -o size=128M,nr_inodes=10k,mode=700 tmpfs /mytmpfs
-\end{verbatim}
+\end{Example}
 
 Il filesystem riconosce, oltre quelle mostrate, le opzioni \texttt{uid} e
 \texttt{gid} che identificano rispettivamente utente e gruppo cui assegnarne
@@ -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:  readmon Hierarchy defaults queues MSGQUEUE
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
-% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE