La funzione che permette di aprire (e crearla se non esiste ancora) una coda
-di messaggi POSIX è \func{mq\_open}, ed il suo prototipo è:
+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)}
\end{errlist}
ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT},
\errval{EMFILE} ed \errval{ENFILE}.}
-\end{prototype}
+\end{functions}
La funzione apre la coda di messaggi identificata dall'argomento \param{name}
restituendo il descrittore ad essa associato, del tutto analogo ad un file
\item[\const{O\_NONBLOCK}] Imposta la coda in modalità non bloccante, le
funzioni di ricezione e trasmissione non si bloccano quando non ci sono le
risorse richieste, ma ritornano immediatamente con un errore di
- \errval{EAGAIN}.
+ \errcode{EAGAIN}.
\end{basedescript}
I primi tre bit specificano la modalità di apertura della coda, e sono fra
-loro esclusivi; qualunque sia la modalità in cui si è aperta una coda, questa
-potrà essere riaperta più volte in una modalità diversa, e vi si potrà
-accedere attraverso descrittori diversi, esattamente come si può fare per i
-file normali.
+loro esclusivi. Ma qualunque sia la modalità in cui si è aperta una coda,
+questa potrà essere riaperta più volte in una modalità diversa, e vi si potrà
+sempre accedere attraverso descrittori diversi, esattamente come si può fare
+per i file normali.
-Se la coda non esiste si deve specificare \const{O\_CREAT} per creare una
-nuova, in tal caso come accennato occorre anche specificare i permessi di
+Se la coda non esiste e la si vuole creare si deve specificare
+\const{O\_CREAT}, in tal caso occorre anche specificare i permessi di
creazione con l'argomento \param{mode}; 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 della coda tramite l'argomento
-\param{attr} che è il puntatore ad una struttura \struct{mq\_attr}, la cui
-definizione è riportata in \figref{fig:ipc_mq_attr}.
+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
+\figref{fig:ipc_mq_attr}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:ipc_mq_attr}
\end{figure}
-Quando si crea la coda possono essere specificati solo i campi
-\var{mq\_msgsize} e \var{mq\_maxmsg}, che indicano rispettivamente la
-dimensione massima di un messaggio ed il numero massimo di messaggi che essa
-può contenere; 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 \errval{EINVAL}. Qualora si specifichi per
-\param{attr} un puntatore nullo gli attributi della coda saranno impostati ai
-valori predefiniti.
+Per ls creazione della coda i campi della struttura che devono essere
+specificati sono \var{mq\_msgsize} e \var{mq\_maxmsg}, che indicano
+rispettivamente la dimensione massima di un messaggio ed il numero massimo di
+messaggi che essa può contenere. 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}. Qualora si
+specifichi per \param{attr} un puntatore nullo gli attributi della coda
+saranno impostati ai valori predefiniti.
+
+Quando l'accesso alla coda non è più necessario si può chiudere il relativo
+descrittore con la funzione \funcd{mq\_close}, il cui prototipo è:
+\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 in caso di
+ errore; nel quel caso \var{errno} assumerà i valori \errval{EBADF} o
+ \errval{EINTR}.}
+\end{prototype}
+
+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.
+
+
+Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la
+funzione \funcd{mq\_unlink}, il cui prototipo è:
+\begin{prototype}{mqueue.h}
+{int mq_unlink(const char *name)}
+
+Rimuove una coda di messaggi.
+
+\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
+ errore; nel quel caso \var{errno} assumerà gli stessi valori riportati da
+ \func{unlink}.}
+\end{prototype}
+
+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 rimove la coda \param{name}, così
+che una successiva chiamata a \func{mq\_open} fallisce o crea una coda
+diversa.
+
+Come per i file ogni coda di messaggi ha un contatore di riferimenti, per cui
+la coda non viene effettivamente rimossa dal sistema fin quando questo non si
+annulla. Pertanto anche dopo aver eseguito con successo \func{mq\_unlink} la
+coda resterà accessibile a tutti i processi che hanno un descrittore aperto su
+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 pipe e
+fifo).
+
+La sola differenza fra code di messaggi POSIX 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.
+
+Come accennato in precedenza 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, struct
+ mq\_attr *omqstat)}
+ Modifica gli attributi di una coda di messaggi POSIX.
+
+ \bodydesc{La funzione restituisce il descrittore associato alla coda 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}
+
+La funzione \func{mq\_getattr} legge i valori correnti degli attributi nella
+struttura puntata da \param{mqstat}; di questi l'unico rilevante è
+\var{mq\_curmsgs} che indica il numero di messaggi da essa contenuti.
+
+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\_flags} e \var{mq\_flags} 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.
\subsection{Semafori}