From: Simone Piccardi Date: Sun, 25 Aug 2002 17:02:34 +0000 (+0000) Subject: Aggiunte msgsnd e msgrcv X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=3da158e64e344c344c497a98468371a2f01b3c25;p=gapil.git Aggiunte msgsnd e msgrcv --- diff --git a/ipc.tex b/ipc.tex index b5e7981..a607aa1 100644 --- 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}