Aggiunte msgsnd e msgrcv
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 25 Aug 2002 17:02:34 +0000 (17:02 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 25 Aug 2002 17:02:34 +0000 (17:02 +0000)
ipc.tex

diff --git a/ipc.tex b/ipc.tex
index b5e7981f69c17cfbb835dccc66e431d374ec811c..a607aa1f682c800083de6c28a7c96ce2b1f7ed00 100644 (file)
--- a/ipc.tex
+++ b/ipc.tex
@@ -1275,21 +1275,19 @@ struct msqid_ds {
     time_t msg_stime;             /* time of last msgsnd command */
     time_t msg_rtime;             /* time of last msgrcv command */
     time_t msg_ctime;             /* time of last change */
-    unsigned long int msg_cbytes; /* current number of bytes on queue */
     msgqnum_t msg_qnum;           /* number of messages currently on queue */
     msglen_t msg_qbytes;          /* max number of bytes allowed on queue */
     pid_t msg_lspid;              /* pid of last msgsnd() */
     pid_t msg_lrpid;              /* pid of last msgrcv() */
     struct msg *msg_first;        /* first message on queue, unused  */
     struct msg *msg_last;         /* last message in queue, unused */
+    unsigned long int msg_cbytes; /* current number of bytes on queue */
 };
     \end{lstlisting}
   \end{minipage} 
   \normalsize 
   \caption{La struttura \var{msgid\_ds}, associata a ciascuna coda di
-    messaggi. Si sono riportati i campi significativi definiti in
-    \file{sys/msg.h}, aggiungendo anche due campi interni, non visibili in
-    user space.}
+    messaggi.}
   \label{fig:ipc_msgid_sd}
 \end{figure}
 
@@ -1298,18 +1296,20 @@ A ciascuna coda 
 riportato nella figura. In questa struttura il kernel\footnote{come accennato
   questo vale fino ai kernel della serie 2.2.x, essa viene usata nei kernel
   della serie 2.4.x solo per compatibilità in quanto è quella restituita dalle
-  funzioni dell'interfaccia.}  mantiene le principali informazioni riguardo lo
-stato corrente della coda. Quando si crea una nuova coda con \func{msgget}
-questa struttura viene inizializzata, in particolare il campo \var{msg\_perm}
-viene inizializzato come illustrato in \secref{sec:ipc_sysv_access_control},
-per quanto riguarda gli altri campi invece:
+  funzioni dell'interfaccia.  In \figref{fig:ipc_msgid_sd} sono elencati i
+  campi significativi definiti in \file{sys/msg.h}, a cui si sono agguinti gli
+  ultimi tre campi che sono previsti dalla implementazione originale di System
+  V, ma non dallo standard Unix98.}  mantiene le principali informazioni
+riguardo lo stato corrente della coda.  Quando si crea una nuova coda con
+\func{msgget} questa struttura viene inizializzata, in particolare il campo
+\var{msg\_perm} viene inizializzato come illustrato in
+\secref{sec:ipc_sysv_access_control}, per quanto riguarda gli altri campi
+invece:
 \begin{itemize}
 \item i campi \var{msg\_qnum}, \var{msg\_lspid}, \var{msg\_lrpid},
   \var{msg\_stime}, \var{msg\_rtime} sono inizializzati a 0
 \item il campo \var{msg\_ctime} viene settato al tempo corrente
 \item il campo \var{msg\_qbytes} al limite di sistema.
-\item i campi \var{msg\_first} e  \var{msg\_last} (che non vengono visti in
-  user space) sono inizializzati a \macro{NULL} essendo la coda vuota.
 \end{itemize}
 
 Una volta creata una coda di messaggi le operazioni di controllo vengono
@@ -1356,10 +1356,164 @@ eseguire; i valori possibili sono:
   il medesimo errore. Questo comando può essere eseguito solo da un processo
   con userid effettivo corrispondente al creatore a o al proprietario della
   coda, o all'amministratore.
-\item[\macro{IPC\_SET}]
+\item[\macro{IPC\_SET}] Permette di modificare i permessi ed il proprietario
+  della coda, ed il limite massimo sulle dimensioni del totale dei messaggi in
+  essa contenuti (\var{msg\_qbytes}). I valori devono essere passati in una
+  struttura \var{msqid\_ds} puntata da \param{buf}.  Per modificare i valori
+  di \var{msg\_perm.mode}, \var{msg\_perm.uid} e \var{msg\_perm.gid} occorre
+  essere il proprietario o il creatore della coda, oppure l'amministratore; lo
+  stesso vale per \var{msg\_qbytes}, con la restrizione che solo
+  l'amministratore può incrementarne il valore a limiti superiori a
+  \macro{MSGMNB}.
 \end{basedescript}
 
 
+Una volta che si abbia a disposizione l'identificatore, per inviare un
+messaggio su una coda si utilizza la funzione \func{msgsnd}; il suo prototipo
+è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/ipc.h} 
+  \headdecl{sys/msg.h} 
+  
+  \funcdecl{int msgsnd(int msqid, struct msgbuf *msgp, size\_t msgsz, int
+    msgflg)} 
+
+  Invia un messaggio sulla coda \param{msqid}.
+  
+  \bodydesc{La funzione restituisce 0, e -1 in caso di errore, nel qual caso
+    \var{errno} viene settata a:
+  \begin{errlist}
+  \item[\macro{EACCES}] Non si hanno i privilegi di accesso sulla coda.
+  \item[\macro{EIDRM}] La coda è stata cancellata.
+  \item[\macro{EAGAIN}] Il messaggio non può essere inviato perché si è
+  superato il limite \var{msg\_qbytes} sul numero massimo di byte presenti
+  sulla coda, e si è richiesto \macro{IPC\_NOWAIT} in \param{flag}.
+  \item[\macro{EINTR}] La funzione è stata interrotta da un segnale.
+  \item[\macro{EINVAL}] Si è specificato un \param{msgid} invalido, o un
+    valore non positivo per \param{mtype}, o un valore di \param{msgsz}
+    maggiore di \macro{MSGMAX}.
+  \end{errlist}
+  ed inoltre \macro{EFAULT} ed \macro{ENOMEM}.
+}
+\end{functions}
+
+La funzione inserisce il messaggio sulla coda specificata da \param{msqid}; il
+messaggio ha lunghezza specificata da \param{msgsz} ed è passato attraverso
+l'argomento \param{msgp}.  Quest'ultimo deve venire passato sempre in una
+forma che corrisponda alla struttura \var{msgbuf} riportata in
+\figref{fig:ipc_msbug}.  La struttura è solo un modello, la sola cosa che
+conta è abbia come primo membro un campo \var{mtype}, come nell'esempio; esso
+infatti serve ad identificare il tipo di messaggio e deve essere sempre
+specificato come intero positivo.  Il campo \var{mtext} invece può essere di
+qualsiasi tipo e dimensione, e deve contenere il testo del messaggio.
+
+In generale pertanto occorrerà ridefinire una struttura analoga a quella di
+\figref{fig:ipc_msbug}, adattando alle proprie esigenze il campo \var{mtype},
+e avendo cura di mantenere come primo campo un valore di tipo \ctyp{long}. Il
+resto della struttura andrà a costituire il corpo del messaggio, la cui
+dimensione deve essere specificata sempre attraverso \param{msgsz}. Si tenga
+presente che la lunghezza che deve essere indicata in questo argomento è solo
+quella del messaggio, non di tutta la struttura, se cioè \var{message} è la
+struttura che si passa alla funzione, \param{msgsz} dovrà essere uguale a
+\code{sizeof(message)-sizeof(long)}.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}
+    struct msgbuf {
+         long mtype;     /* message type, must be > 0 */
+         char mtext[1];  /* message data */
+    };
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{Schema della struttura \var{msgbug}, da utilizzare come argomento
+    per inviare/ricevere messaggi.}
+  \label{fig:ipc_msbug}
+\end{figure}
+
+Per capire meglio il funzionamento della funzione riprendiamo in
+considerazione la struttura della coda illustrata in
+\secref{fig:ipc_mq_schema}. Alla chiamata di \func{msgsnd} il nuovo messaggio
+sarà aggiunto in fondo alla lista inserendo una nuova struttura \var{msg}, il
+puntatore \var{msg\_last} di \var{msqid\_ds} verrà aggiornato, come pure il
+puntatore al messaggio successivo per quello che era il precedente ultimo
+messaggio; il valore di \var{mtype} verrà mantenuto in \var{msg\_type} ed il
+valore di \param{msgsz} in \var{msg\_ts}; il testo del messaggio sarà copiato
+all'indirizzo specificato da \var{msg\_spot}.
+
+Il valore dell'argomento \param{flag} permette di specificare il comportamento
+della funzione. Di norma, quando si specifica un valore nullo, la funzione
+ritorna immediatamente a meno che si sia ecceduto il valore di
+\var{msg\_qbytes}, o il limite di sistema sul numero di messaggi, nel qual
+caso si blocca mandando il processo in stato di \textit{sleep}.  Se si
+specifica per \param{flag} il valore \macro{IPC\_NOWAIT} la funzione opera in
+modalità non bloccante, ed in questi casi ritorna immediatamente con un errore
+di \macro{EAGAIN}.
+
+Se non si specifica \macro{IPC\_NOWAIT} la funzione resterà bloccata fintanto
+che non si liberano risorse sufficienti per poter inserire nella coda il
+messaggio, nel qual caso ritornerà normalmente. La funzione può ritornare, con
+una condizione di errore anche in due altri casi: quando la coda viene rimossa
+(nel qual caso si ha un errore di \macro{EIDRM}) o quando la funzione viene
+interrotta da un segnale (nel qual caso si ha un errore di \macro{EINTR}).
+
+Una volta completato con successo l'invio del messaggio sulla coda, la
+funzione aggiorna i dati mantenuti in \var{msqid\_ds}, in particolare vengono
+modificati:
+\begin{itemize*}
+\item Il valore di \var{msg\_lspid}, che viene importato al \acr{pid} del
+  processo chiamante.
+\item Il valore di \var{msg\_qnum}, che viene incrementato di uno.
+\item Il valore \var{msg\_stime}, che viene impostato al tempo corrente.
+\end{itemize*}
+
+
+La funzione che permette di estrarre da una coda un messaggio (che sarà
+rimosso dalla stessa) è \func{msgrcv}; il suo prototipo è:
+\begin{functions}
+  \headdecl{sys/types.h} 
+  \headdecl{sys/ipc.h} 
+  \headdecl{sys/msg.h} 
+
+  \funcdecl{ssize\_t msgrcv(int msqid, struct msgbuf *msgp, size\_t msgsz,
+    long msgtyp, int msgflg)}
+  
+  Legge un messaggio dalla coda \param{msqid}.
+  
+  \bodydesc{La funzione restituisce il numero di byte letti in caso di
+    successo, e -1 in caso di errore, nel qual caso \var{errno} viene settata
+    a:
+  \begin{errlist}
+  \item[\macro{EACCES}] Non si hanno i privilegi di accesso sulla coda.
+  \item[\macro{EIDRM}] La coda è stata cancellata.
+  \item[\macro{E2BIG}] Il testo del messaggio è più lungo di \param{msgsz} e
+  non si è specificato \macro{MSG\_NOERROR} in \param{msgflg}.
+  \item[\macro{EINTR}] La funzione è stata interrotta da un segnale mentre era
+  in attesa di ricevere un messaggio.
+  \item[\macro{EINVAL}] Si è specificato un \param{msgid} invalido o un valore
+    di \param{msgsz} negativo.
+  \end{errlist}
+  ed inoltre \macro{EFAULT}.
+}
+\end{functions}
+
+La funzione è analoga alla precedente \func{msgsnd} ed gli argomenti sono
+analoghi, con l'eccezione di \param{type}, questo permette di restringere la
+ricerca ad alcuni messaggi; in particolare:
+\begin{itemize}
+\item se \param{type} è 0 viene estratto il messaggio in cima alla coda (cioè
+  quello fra i presenti che è stato inserito inserito per primo). 
+\item se \param{type} è positivo viene estratto il primo messaggio il cui tipo
+  (il valore del campo \var{mtype}) corrisponde a quanto specificato.
+\item se \param{type} è negativo viene estratto il primo messaggio il valore
+  di tipo più basso inferiore al valore assoluto di quanto specificato.
+\end{itemize}
+
+
+
 \subsection{Semafori}
 \label{sec:ipc_sysv_sem}