Aggiornamento note di copyright e correzioni minime.
[gapil.git] / ipc.tex
diff --git a/ipc.tex b/ipc.tex
index 520793d20023a7457032fe6a94bf03e261c7f1b1..ff6e69cb673cfb8729adec98abc31087cc444065 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1,6 +1,6 @@
 %% ipc.tex
 %%
-%% Copyright (C) 2000-2013 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2014 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -690,9 +690,9 @@ stringa di richiesta dalla \textit{fifo} nota (che a questo punto si bloccherà
 tutte le volte che non ci sono richieste). Dopo di che, una volta terminata la
 stringa (\texttt{\small 40}) e selezionato (\texttt{\small 41}) un numero
 casuale per ricavare la frase da inviare, si procederà (\texttt{\small
-  42--46}) all'apertura della \textit{fifo} per la risposta, che poi
-\texttt{\small 47--48}) vi sarà scritta. Infine (\texttt{\small 49}) si chiude
-la \textit{fifo} di risposta che non serve più.
+  42--46}) all'apertura della \textit{fifo} per la risposta, che poi 
+(\texttt{\small 47--48}) vi sarà scritta. Infine (\texttt{\small 49}) si
+chiude la \textit{fifo} di risposta che non serve più.
 
 Il codice del client è invece riportato in fig.~\ref{fig:ipc_fifo_client},
 anche in questo caso si è omessa la gestione delle opzioni e la funzione che
@@ -1422,7 +1422,7 @@ file; il suo prototipo è:
     \var{msg\_qbytes} oltre il limite \const{MSGMNB} senza essere
     amministratore.
   \end{errlist}
-  ed inoltre \errval{EFAULT} ed \errval{EINVAL}  nel loro significato
+  ed inoltre \errval{EFAULT} ed \errval{EINVAL} nel loro significato
   generico.}
 \end{funcproto}
 
@@ -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.
 
 
-
 \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*}
 
-
 \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}. 
 
-
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{.80\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \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:
-\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
@@ -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]
-  \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}
@@ -2605,8 +2602,6 @@ delle pagine di swap ad uso del meccanismo del \textit{copy on write}
 significa che caso di scrittura sul segmento quando non c'è più memoria
 disponibile, si avrà l'emissione di un \signal{SIGSEGV}.
 
-% TODO verificare i privilegi necessari per SHM_HUGETLB
-
 Infine l'argomento \param{size} specifica la dimensione del segmento di
 memoria condivisa; il valore deve essere specificato in byte, ma verrà
 comunque arrotondato al multiplo superiore di \const{PAGE\_SIZE}. Il valore
@@ -2635,7 +2630,7 @@ norma, significa insieme a dei semafori.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.80\textwidth}
     \includestruct{listati/shmid_ds.h}
   \end{minipage} 
   \normalsize 
@@ -2652,7 +2647,7 @@ campo \var{shm\_perm} viene inizializzato come illustrato in
 sez.~\ref{sec:ipc_sysv_access_control}, e valgono le considerazioni ivi fatte
 relativamente ai permessi di accesso; per quanto riguarda gli altri campi
 invece:
-\begin{itemize}
+\begin{itemize*}
 \item il campo \var{shm\_segsz}, che esprime la dimensione del segmento, viene
   inizializzato al valore di \param{size}.
 \item il campo \var{shm\_ctime}, che esprime il tempo di creazione del
@@ -2666,7 +2661,7 @@ invece:
   creato il segmento, viene inizializzato al \ids{PID} del processo chiamante.
 \item il campo \var{shm\_nattac}, che esprime il numero di processi agganciati
   al segmento viene inizializzato a zero.
-\end{itemize}
+\end{itemize*}
 
 Come per le code di messaggi e gli insiemi di semafori, anche per i segmenti
 di memoria condivisa esistono una serie di limiti imposti dal sistema.  Alcuni
@@ -2786,7 +2781,7 @@ si ha a cuore la portabilità. Questi comandi aggiuntivi sono:
   sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore
   poteva utilizzare questa capacità,\footnote{che richiedeva la
     \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel
-  2.6.10 anche gli utenti normali possono farlo fina al limite massimo
+  2.6.10 anche gli utenti normali possono farlo fino al limite massimo
   determinato da \const{RLIMIT\_MEMLOCK} (vedi
   sez.~\ref{sec:sys_resource_limit}).
 \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking}
@@ -2833,7 +2828,6 @@ il suo prototipo è:
       per \param{shmaddr} o il valore \val{NULL} indicando \const{SHM\_REMAP}.
   \end{errlist}
   ed inoltre \errval{ENOMEM} nel suo significato generico.
-  
 }  
 \end{funcproto}
 
@@ -2906,14 +2900,14 @@ 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}
+\begin{itemize*}
 \item il tempo \var{shm\_atime} dell'ultima operazione di aggancio viene
   impostato al tempo corrente.
 \item il \ids{PID} \var{shm\_lpid} dell'ultimo processo che ha operato sul
   segmento viene impostato a quello del processo corrente.
 \item il numero \var{shm\_nattch} di processi agganciati al segmento viene
   aumentato di uno.
-\end{itemize
+\end{itemize*}
 
 Come accennato in sez.~\ref{sec:proc_fork} un segmento di memoria condivisa
 agganciato ad un processo viene ereditato da un figlio attraverso una
@@ -3347,7 +3341,7 @@ alternativi.
 La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare
 dei \textsl{file di lock} (per i quali è stata anche riservata una opportuna
 directory, \file{/var/lock}, nella standardizzazione del \textit{Filesystem
-  Hyerarchy Standard}). Per questo si usa la caratteristica della funzione
+  Hierarchy Standard}). Per questo si usa la caratteristica della funzione
 \func{open} (illustrata in sez.~\ref{sec:file_open_close}) che
 prevede\footnote{questo è quanto dettato dallo standard POSIX.1, ciò non
   toglie che in alcune implementazioni questa tecnica possa non funzionare; in
@@ -3530,12 +3524,14 @@ 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
@@ -3599,14 +3595,18 @@ Data la assoluta genericità delle specifiche, il comportamento delle funzioni
 è subordinato in maniera quasi completa alla relativa implementazione, tanto
 che Stevens in \cite{UNP2} cita questo caso come un esempio della maniera
 standard usata dallo standard POSIX per consentire implementazioni non
-standardizzabili. Nel caso di Linux, sia per quanto riguarda la memoria
-condivisa ed i semafori, che per 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.
+standardizzabili. 
+
+Nel caso di Linux, sia per quanto riguarda la memoria condivisa ed i semafori,
+che per le code di messaggi, tutto viene creato usando come radici delle
+opportune directory (rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per
+i dettagli si faccia riferimento a sez.~\ref{sec:ipc_posix_shm},
+sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}).  I nomi
+specificati nelle relative funzioni devono essere nella forma di un
+\textit{pathname} assoluto (devono cioè iniziare con ``\texttt{/}'') e
+corrisponderanno ad altrettanti file creati all'interno di queste directory;
+per questo motivo detti nomi non possono contenere altre ``\texttt{/}'' oltre
+quella iniziale.
 
 Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti
 nell'albero dei file, e possono essere maneggiati con le usuali funzioni e
@@ -3614,51 +3614,45 @@ 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.
+che per le code di messaggi varie \textit{system call} utilizzate da Linux
+corrispondono in realtà a quelle ordinarie dei file, essendo detti oggetti
+realizzati come tali in appositi filesystem.
 
 In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai
 permessi dei file, ed il controllo di accesso segue esattamente la stessa
 semantica (quella illustrata in sez.~\ref{sec:file_access_control}), e non
 quella particolare (si ricordi quanto visto in
 sez.~\ref{sec:ipc_sysv_access_control}) che viene usata per gli oggetti del
-SysV-IPC.  Per quanto riguarda l'attribuzione dell'utente e del gruppo
+SysV-IPC. Per quanto riguarda l'attribuzione dell'utente e del gruppo
 proprietari dell'oggetto alla creazione di quest'ultimo essa viene effettuata
 secondo la semantica SysV: corrispondono cioè a \ids{UID} e \ids{GID} effettivi
 del processo che esegue la creazione.
 
 
-\subsection{Code di messaggi}
+\subsection{Code di messaggi Posix}
 \label{sec:ipc_posix_mq}
 
 Le code di messaggi POSIX sono supportate da Linux a partire dalla versione
-2.6.6-rc1 del kernel,\footnote{l'implementazione è dovuta a Michal Wronski e
-  Krzysztof Benedyczak, e le relative informazioni si possono trovare su
-  \url{http://www.geocities.com/wronski12/posix_ipc/index.html}.} In generale,
-come le corrispettive del \textit{SysV-IPC}, le code di messaggi sono poco
-usate, dato che i socket, nei casi in cui sono sufficienti, sono più comodi, e
-che in casi più complessi la comunicazione può essere gestita direttamente con
-mutex (o semafori) e memoria condivisa con tutta la flessibilità che occorre.
+2.6.6 del kernel. In generale, come le corrispettive del \textit{SysV-IPC}, le
+code di messaggi sono poco usate, dato che i socket, nei casi in cui sono
+sufficienti, sono più comodi, e che in casi più complessi la comunicazione può
+essere gestita direttamente con mutex (o semafori) e memoria condivisa con
+tutta la flessibilità che occorre.
 
 Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel
-superiore al 2.6.6 (o precedente, se sono stati opportunamente applicati i
-relativi patch) occorre utilizzare la libreria \file{libmqueue}\footnote{i
-  programmi che usano le code di messaggi cioè devono essere compilati
-  aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}; in
-  corrispondenza all'inclusione del supporto nel kernel ufficiale anche
-  \file{libmqueue} è stata inserita nella \acr{glibc}, a partire dalla
-  versione 2.3.4 delle medesime.} che contiene le funzioni dell'interfaccia
-POSIX.\footnote{in realtà l'implementazione è realizzata tramite delle
-  opportune chiamate ad \func{ioctl} sui file del filesystem speciale su cui
-  vengono mantenuti questi oggetti di IPC.}
+superiore al 2.6.6 occorre utilizzare la libreria \file{librt} che contiene le
+funzioni dell'interfaccia POSIX ed i programmi che usano le code di messaggi
+devono essere compilati aggiungendo l'opzione \code{-lrt} al comando
+\cmd{gcc}. In corrispondenza all'inclusione del supporto nel kernel ufficiale
+le funzioni di libreria sono state inserite nella \acr{glibc}, e sono
+disponibili a partire dalla versione 2.3.4 delle medesime.
 
 La libreria inoltre richiede la presenza dell'apposito filesystem di tipo
-\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto
-aggiungendo ad \conffile{/etc/fstab} una riga come:
-\begin{verbatim}
+\texttt{mqueue} montato sulla directory \file{/dev/mqueue}; questo può essere
+fatto aggiungendo ad \conffile{/etc/fstab} una riga come:
+\begin{Example}
 mqueue   /dev/mqueue       mqueue    defaults        0      0
-\end{verbatim}
+\end{Example}
 ed esso sarà utilizzato come radice sulla quale vengono risolti i nomi delle
 code di messaggi che iniziano con una ``\texttt{/}''. Le opzioni di mount
 accettate sono \texttt{uid}, \texttt{gid} e \texttt{mode} che permettono
@@ -3666,54 +3660,63 @@ rispettivamente di impostare l'utente, il gruppo ed i permessi associati al
 filesystem.
 
 
-La funzione che permette di aprire (e crearla se non esiste ancora) una coda
-di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{mqd\_t mq\_open(const char *name, int oflag)}
-  
-  \funcdecl{mqd\_t mq\_open(const char *name, int oflag, unsigned long mode,
+La funzione di sistema che permette di aprire (e crearla se non esiste ancora)
+una coda di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{fcntl.h}
+\fhead{sys/stat.h}
+\fhead{mqueue.h}
+\fdecl{mqd\_t mq\_open(const char *name, int oflag)}
+\fdecl{mqd\_t mq\_open(const char *name, int oflag, unsigned long mode,
     struct mq\_attr *attr)}
-  
-  Apre una coda di messaggi POSIX impostandone le caratteristiche.
-  
-  \bodydesc{La funzione restituisce il descrittore associato alla coda in caso
-    di successo e -1 per un errore; nel quel caso \var{errno} assumerà i
-    valori:
-    \begin{errlist}
-    \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al
-      alla memoria secondo quanto specificato da \param{oflag}.
-    \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e
-      \const{O\_EXCL} ma la coda già esiste.
-    \item[\errcode{EINVAL}] il file non supporta la funzione, o si è
-      specificato \const{O\_CREAT} con una valore non nullo di \param{attr} e
-      valori non validi di \var{mq\_maxmsg} e \var{mq\_msgsize}.
-    \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda
-      non esiste.
-    \end{errlist}
-    ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
-    \errval{EMFILE}, \errval{EINTR} ed \errval{ENFILE}.
+
+\fdesc{Apre una coda di messaggi POSIX impostandone le caratteristiche.}
 }
-\end{functions}
+
+{La funzione ritorna il descrittore associato alla coda in caso di successo e
+  $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EACCES}] il processo non ha i privilegi per accedere alla
+    coda secondo quanto specificato da \param{oflag} oppure \const{name}
+    contiene più di una ``\texttt{/}''.
+  \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e \const{O\_EXCL}
+    ma la coda già esiste.
+  \item[\errcode{EINVAL}] il file non supporta la funzione, o si è specificato
+    \const{O\_CREAT} con una valore non nullo di \param{attr} e valori non
+    validi dei campi \var{mq\_maxmsg} e \var{mq\_msgsize}; questi valori
+    devono essere positivi ed inferiori ai limiti di sistema se il processo
+    non ha privilegi amministrativi, inoltre \var{mq\_maxmsg} non può comunque
+    superare \const{HARD\_MAX}.
+  \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda non
+    esiste o si è usato il nome ``\texttt{/}''.
+  \item[\errcode{ENOSPC}] lo spazio è insufficiente, probabilmente per aver
+    superato il limite di \texttt{queues\_max}.
+  \end{errlist}
+  ed inoltre \errval{EMFILE}, \errval{ENAMETOOLONG}, \errval{ENFILE},
+  \errval{ENOMEM} ed nel loro significato generico.  }
+\end{funcproto}
 
 La funzione apre la coda di messaggi identificata dall'argomento \param{name}
 restituendo il descrittore ad essa associato, del tutto analogo ad un file
 descriptor, con l'unica differenza che lo standard prevede un apposito tipo
-\type{mqd\_t}.\footnote{nel caso di Linux si tratta in effetti proprio di un
-  normale file descriptor; pertanto, anche se questo comportamento non è
-  portabile, lo si può tenere sotto osservazione con le funzioni dell'I/O
-  multiplexing (vedi sez.~\ref{sec:file_multiplexing}) come possibile
-  alternativa all'uso dell'interfaccia di notifica di \func{mq\_notify} (che
-  vedremo a breve).} Se la coda esiste già il descrittore farà riferimento
-allo stesso oggetto, consentendo così la comunicazione fra due processi
-diversi.
+\type{mqd\_t}. Nel caso di Linux si tratta in effetti proprio di un normale
+file descriptor; pertanto, anche se questo comportamento non è portabile, lo
+si può tenere sotto osservazione con le funzioni dell'I/O multiplexing (vedi
+sez.~\ref{sec:file_multiplexing}) come possibile alternativa all'uso
+dell'interfaccia di notifica di \func{mq\_notify} (che vedremo a breve).
+
+Se il nome indicato fa riferimento ad una coda di messaggi già esistente, il
+descrittore ottenuto farà riferimento allo stesso oggetto, pertanto tutti i
+processi che hanno usato \func{mq\_open} su quel nome otterranno un
+riferimento alla stessa coda. Diventa così immediato costruire un canale di
+comunicazione fra detti processi.
 
 La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che
 possono essere specificati per \param{oflag}, che deve essere specificato come
 maschera binaria; i valori possibili per i vari bit sono quelli visti in
-sez.~\ref{sec:file_open_close} dei quali però \func{mq\_open} riconosce solo i
-seguenti:
+sez.~\ref{sec:file_open_close} (per questo occorre includere \texttt{fcntl.h})
+dei quali però \func{mq\_open} riconosce solo i seguenti:
 \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
 \item[\const{O\_RDONLY}] Apre la coda solo per la ricezione di messaggi. Il
   processo potrà usare il descrittore con \func{mq\_receive} ma non con
@@ -3745,15 +3748,17 @@ Se la coda non esiste e la si vuole creare si deve specificare
 creazione con l'argomento \param{mode};\footnote{fino al 2.6.14 per un bug i
   valori della \textit{umask} del processo non venivano applicati a questi
   permessi.} i valori di quest'ultimo sono identici a quelli usati per
-\func{open}, anche se per le code di messaggi han senso solo i permessi di
-lettura e scrittura. Oltre ai permessi di creazione possono essere specificati
-anche gli attributi specifici della coda tramite l'argomento \param{attr};
-quest'ultimo è un puntatore ad una apposita struttura \struct{mq\_attr}, la
-cui definizione è riportata in fig.~\ref{fig:ipc_mq_attr}.
+\func{open} (per questo occorre includere \texttt{sys/stat.h}), anche se per
+le code di messaggi han senso solo i permessi di lettura e scrittura.
+
+Oltre ai permessi di creazione possono essere specificati anche gli attributi
+specifici della coda tramite l'argomento \param{attr}; quest'ultimo è un
+puntatore ad una apposita struttura \struct{mq\_attr}, la cui definizione è
+riportata in fig.~\ref{fig:ipc_mq_attr}.
 
 \begin{figure}[!htb]
   \footnotesize \centering
-  \begin{minipage}[c]{\textwidth}
+  \begin{minipage}[c]{0.90\textwidth}
     \includestruct{listati/mq_attr.h}
   \end{minipage} 
   \normalsize
@@ -3766,51 +3771,96 @@ Per la creazione della coda i campi della struttura che devono essere
 specificati sono \var{mq\_maxmsg} e \var{mq\_msgsize}, che indicano
 rispettivamente il numero massimo di messaggi che può contenere e la
 dimensione massima di un messaggio. Il valore dovrà essere positivo e minore
-dei rispettivi limiti di sistema \const{MQ\_MAXMSG} e \const{MQ\_MSGSIZE},
-altrimenti la funzione fallirà con un errore di \errcode{EINVAL}.
-Se \param{attr} è un puntatore nullo gli attributi della coda saranno
-impostati ai valori predefiniti.
+dei rispettivi limiti di sistema altrimenti la funzione fallirà con un errore
+di \errcode{EINVAL}.  Se \param{attr} è un puntatore nullo gli attributi della
+coda saranno impostati ai valori predefiniti.
+
+I suddetti limiti di sistema sono impostati attraverso altrettanti file in
+\texttt{/proc/sys/fs/mqueue}, in particolare i file che controllano i valori
+dei limiti sono:
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
+\item[\sysctlfile{fs/mqueue/msg\_max}] Indica il valore massimo del numero di
+  messaggi in una coda e agisce come limite superiore per il valore di
+  \var{attr->mq\_maxmsg} in \func{mq\_open}. Il suo valore di default è 10. Il
+  valore massimo è \const{HARD\_MAX} che vale \code{(131072/sizeof(void *))},
+  ed il valore minimo 1 (ma era 10 per i kernel precedenti il 2.6.28). Questo
+  limite viene ignorato per i processi con privilegi amministrativi (più
+  precisamente con la \itindex{capability} \textit{capability}
+  \const{CAP\_SYS\_RESOURCE}) ma \const{HARD\_MAX} resta comunque non
+  superabile.
+
+\item[\sysctlfile{fs/mqueue/msgsize\_max}] Indica il valore massimo della
+  dimensione in byte di un messaggio sulla coda ed agisce come limite
+  superiore per il valore di \var{attr->mq\_msgsize} in \func{mq\_open}. Il
+  suo valore di default è 8192.  Il valore massimo è 1048576 ed il valore
+  minimo 128 (ma per i kernel precedenti il 2.6.28 detti limiti erano
+  rispettivamente \const{INT\_MAX} e 8192). Questo valore viene ignorato dai
+  processi con privilegi amministrativi (la \itindex{capability}
+  \textit{capability} \const{CAP\_SYS\_RESOURCE}).
+
+\item[\sysctlfile{fs/mqueue/queues\_max}] Indica il numero massimo di code di
+  messaggi creabili in totale sul sistema, il valore di default è 256 ma si
+  può usare un valore qualunque fra $0$ e \const{INT\_MAX}. Il limite non
+  viene applicato ai processi con privilegi amministrativi (cioè con la
+  \itindex{capability} \textit{capability} \const{CAP\_SYS\_RESOURCE}).
+
+\end{basedescript}
+
+Infine sulle code di messaggi si applica il limite imposto sulla risorsa
+\const{RLIMIT\_MSGQUEUE} (vedi sez.~\ref{sec:sys_resource_limit}) che indica
+lo spazio massimo (in byte) occupabile da tutte le code di messaggi
+appartenenti ai processi di uno stesso utente, identificato dal loro
+\textit{real user ID}.
 
 Quando l'accesso alla coda non è più necessario si può chiudere il relativo
 descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
-\begin{prototype}{mqueue.h}
-{int mq\_close(mqd\_t mqdes)}
 
-Chiude la coda \param{mqdes}.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore;
-  nel quel caso \var{errno} assumerà i valori \errval{EBADF} o
-  \errval{EINTR}.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_close(mqd\_t mqdes)}
 
-La funzione è analoga a \func{close},\footnote{in Linux, dove le code sono
-  implementate come file su un filesystem dedicato, è esattamente la stessa
-  funzione.} dopo la sua esecuzione il processo non sarà più in grado di usare
-il descrittore della coda, ma quest'ultima continuerà ad esistere nel sistema
-e potrà essere acceduta con un'altra chiamata a \func{mq\_open}. All'uscita di
-un processo tutte le code aperte, così come i file, vengono chiuse
-automaticamente. Inoltre se il processo aveva agganciato una richiesta di
-notifica sul descrittore che viene chiuso, questa sarà rilasciata e potrà
-essere richiesta da qualche altro processo.
+\fdesc{Chiude una coda di messaggi.}
+}
 
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà uno dei valori \errval{EBADF} o \errval{EINTR} nel
+  loro significato generico.
+}  
+\end{funcproto}
+
+La funzione è analoga a \func{close},\footnote{su Linux, dove le code sono
+  implementate come file su un filesystem dedicato, è esattamente la stessa
+  funzione, per cui non esiste una \textit{system call} autonoma e la funzione
+  viene rimappata su \func{close} dalle \acr{glibc}.}  dopo la sua esecuzione
+il processo non sarà più in grado di usare il descrittore della coda, ma
+quest'ultima continuerà ad esistere nel sistema e potrà essere acceduta con
+un'altra chiamata a \func{mq\_open}. All'uscita di un processo tutte le code
+aperte, così come i file, vengono chiuse automaticamente. Inoltre se il
+processo aveva agganciato una richiesta di notifica sul descrittore che viene
+chiuso, questa sarà rilasciata e potrà essere richiesta da qualche altro
+processo.
 
 Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la
-funzione \funcd{mq\_unlink}, il cui prototipo è:
-\begin{prototype}{mqueue.h}
-{int mq\_unlink(const char *name)}
+funzione di sistema \funcd{mq\_unlink}, il cui prototipo è:
 
-Rimuove una coda di messaggi.
-  
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
-  errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
-  \func{unlink}.}
-\end{prototype}
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_unlink(const char *name)}
+
+\fdesc{Rimuove una coda di messaggi.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+  caso \var{errno} assumerà gli stessi valori riportati da \func{unlink}.
+}  
+\end{funcproto}
 
 Anche in questo caso il comportamento della funzione è analogo a quello di
-\func{unlink} per i file,\footnote{di nuovo l'implementazione di Linux usa
-  direttamente \func{unlink}.} la funzione rimuove la coda \param{name}, così
-che una successiva chiamata a \func{mq\_open} fallisce o crea una coda
-diversa. 
+\func{unlink} per i file, la funzione rimuove la coda \param{name} (ed il
+relativo file sotto \texttt{/dev/mqueue}), così che una successiva chiamata a
+\func{mq\_open} fallisce o crea una coda diversa.
+
+% TODO, verificare se mq_unlink è davvero una system call indipendente.
 
 Come per i file ogni coda di messaggi ha un contatore di riferimenti, per cui
 la coda non viene effettivamente rimossa dal sistema fin quando questo non si
@@ -3827,20 +3877,21 @@ riavvio del sistema.
 Come accennato ad ogni coda di messaggi è associata una struttura
 \struct{mq\_attr}, che può essere letta e modificata attraverso le due
 funzioni \funcd{mq\_getattr} e \funcd{mq\_setattr}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{int mq\_getattr(mqd\_t mqdes, struct mq\_attr *mqstat)}
-  Legge gli attributi di una coda di messaggi POSIX.
-  
-  \funcdecl{int mq\_setattr(mqd\_t mqdes, const struct mq\_attr *mqstat,
+
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_getattr(mqd\_t mqdes, struct mq\_attr *mqstat)}
+\fdesc{Legge gli attributi di una coda di messaggi POSIX.}
+\fdecl{int mq\_setattr(mqd\_t mqdes, const struct mq\_attr *mqstat,
     struct mq\_attr *omqstat)}
-  Modifica gli attributi di una coda di messaggi POSIX.
-  
-  \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in
-    caso di errore; nel quel caso \var{errno} assumerà i valori \errval{EBADF}
-    o \errval{EINVAL}.}
-\end{functions}
+\fdesc{Modifica gli attributi di una coda di messaggi POSIX.}
+}
+
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà i valori \errval{EBADF}
+    o \errval{EINVAL} nel loro significato generico.
+}  
+\end{funcproto}
 
 La funzione \func{mq\_getattr} legge i valori correnti degli attributi della
 coda nella struttura puntata da \param{mqstat}; di questi l'unico relativo
@@ -3862,22 +3913,21 @@ della funzione.
 
 Per inserire messaggi su di una coda sono previste due funzioni,
 \funcd{mq\_send} e \funcd{mq\_timedsend}, i cui prototipi sono:
-\begin{functions}
-  \headdecl{mqueue.h} 
-  
-  \funcdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
-    unsigned int msg\_prio)} 
-  Esegue l'inserimento di un messaggio su una coda.
-  
-  \funcdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
-    msg\_len, unsigned msg\_prio, const struct timespec *abs\_timeout)}   
-  Esegue l'inserimento di un messaggio su una coda entro il tempo
-  \param{abs\_timeout}.
 
-  
-  \bodydesc{Le funzioni restituiscono 0 in caso di successo e $-1$ per un
-    errore; nel quel caso \var{errno} assumerà i valori:
-    \begin{errlist}
+\begin{funcproto}{
+\fhead{mqueue.h}
+\fdecl{int mq\_send(mqd\_t mqdes, const char *msg\_ptr, size\_t msg\_len,
+    unsigned int msg\_prio)}
+\fdesc{Esegue l'inserimento di un messaggio su una coda.}
+\fdecl{int mq\_timedsend(mqd\_t mqdes, const char *msg\_ptr, size\_t
+    msg\_len, unsigned msg\_prio, const struct timespec *abs\_timeout)}
+\fdesc{Esegue l'inserimento di un messaggio su una coda entro un tempo
+  specificato}
+}
+
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ per un errore,
+  nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
     \item[\errcode{EAGAIN}] si è aperta la coda con \const{O\_NONBLOCK}, e la
       coda è piena.
     \item[\errcode{EMSGSIZE}] la lunghezza del messaggio \param{msg\_len}
@@ -3887,9 +3937,11 @@ Per inserire messaggi su di una coda sono previste due funzioni,
       un valore non valido per \param{abs\_timeout}.
     \item[\errcode{ETIMEDOUT}] l'inserimento del messaggio non è stato
       effettuato entro il tempo stabilito.
-    \end{errlist}    
-    ed inoltre \errval{EBADF}, \errval{ENOMEM} ed \errval{EINTR}.}
-\end{functions}
+  \end{errlist}
+  ed inoltre \errval{EBADF}, \errval{ENOMEM} ed \errval{EINTR} nel loro
+  significato generico.
+}
+\end{funcproto}
 
 Entrambe le funzioni richiedono un puntatore al testo del messaggio
 nell'argomento \param{msg\_ptr} e la relativa lunghezza in \param{msg\_len}.
@@ -3975,8 +4027,6 @@ selezionare quale messaggio estrarre con delle condizioni sulla priorità, a
 differenza di quanto avveniva con le code di messaggi di SysV che permettono
 invece la selezione in base al valore del campo \var{mtype}. 
 
-% TODO inserire i dati di /proc/sys/fs/mqueue 
-
 Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si
 sia selezionata la modalità non bloccante; in tal caso entrambe ritornano
 immediatamente con l'errore \errcode{EAGAIN}. Anche in questo caso la sola
@@ -4398,7 +4448,7 @@ Si tenga presente che la funzione può sempre essere interrotta da un segnale
 (nel qual caso si avrà un errore di \const{EINTR}) e che questo avverrà
 comunque, anche se si è richiesta la semantica BSD installando il relativo
 gestore con \const{SA\_RESTART} (vedi sez.~\ref{sec:sig_sigaction}) per
-riavviare le system call interrotte.
+riavviare le \textit{system call} interrotte.
 
 Della funzione \func{sem\_wait} esistono due varianti che consentono di
 gestire diversamente le modalità di attesa in caso di risorsa occupata, la
@@ -4927,14 +4977,15 @@ testo alla terminazione di quest'ultimo.
 % LocalWords:  process getvalue sval execve pshared ENOSYS heap PAGE destroy it
 % LocalWords:  xffffffff Arrays owner perms Queues used bytes messages device
 % LocalWords:  Cannot find such Segments getter Signal MSGMAXSIZE been stable
-% LocalWords:  for now it's break Berlin sources Let's an accidental feature
+% LocalWords:  for now it's break Berlin sources Let's an accidental feature fs
 % LocalWords:  Larry Wall Escape the Hell William ipctestid Identifier segment
 % LocalWords:  violation dell'I SIGINT setter Fri Dec Sleeping seconds ECHILD
 % LocalWords:  SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop
-% LocalWords:  scan
+% LocalWords:  scan HUGETLB huge page NORESERVE copy RLIMIT MEMLOCK REMAP
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  readmon Hierarchy defaults queues MSGQUEUE