msgrcv

MSGOP(2)                   Manuel du programmeur Linux                  MSGOP(2)



NOM
       msgrcv, msgsnd - Opérations sur les files de messages System V

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);

DESCRIPTION
       The msgsnd()  and msgrcv()  system calls are used to send messages to,
       and receive messages from, a System V message queue.  The calling process
       must have write permission on the message queue in order to send a
       message, and read permission to receive a message.

       L'argument msgp est un pointeur vers une structure définie par l'appelant
       de forme générale suivante :

           struct msgbuf {
               long mtype;       /* type de message, doit être > 0 */
               char mtext[1];    /* contenu du message */
           };

       Le champ mtext est un tableau ou autre structure de taille msgsz, valeur
       entière positive ou nulle. Les message de taille nulle (sans champ mtext)
       sont autorisés. Le membre mtype doit avoir une valeur strictement
       positive qui puisse être utilisée par le processus lecteur pour la
       sélection de messages (voir la description de msgrcv ci‐dessous).

   msgsnd()
       L'appel système msgsnd() insère une copie du message pointé par
       l'argument msgp dans la file dont l'identifiant est indiqué par la valeur
       de l'argument msqid.

       S'il y a assez de place dans la file, msgsnd() réussit immédiatement. La
       capacité de la file est régie par le champ msg_qbytes de la structure
       associée à la file de messages. Durant la création de la file, ce champ
       est initialisé à MSGMNB octets, mais cette limite peut être modifiée avec
       msgctl(2). Une file de message est considérée pleine si une de ces
       conditions est remplie :

       • Après l'ajout d'un message à la file, le nombre total d'octets dans la
         faille aurait dépassé la taille maximale de la file (champ msg_qbytes).

       • Après l'ajout d'un message à la file, le nombre total de messages dans
         la faille aurait dépassé la taille maximale de la file (champ
         msg_qbytes).Cette vérification permet d'éviter qu'un nombre illimité de
         messages de taille nulle soit ajouté à la file. Bien que tels messages
         ne contiennent pas de données, ils consomment néanmoins de la mémoire
         du noyau, sujette à verrou.

       S'il n'y a pas assez de place, alors le comportement par défaut de
       msgsnd() est de bloquer jusqu'à obtenir suffisamment d'espace. En
       indiquant IPC_NOWAIT dans l'argument msgflg, le message ne sera pas
       envoyé et l'appel système échouera en retournant EAGAIN dans errno.

       Un appel à msgsnd() bloqué peut échouer si :

       • la file est supprimée, auquel cas l'appel système échoue avec errno
         valant EIDRM ; ou

       • un signal a été intercepté, auquel cas l'appel système échoue avec
         errno valant EINTR ; consultez signal(7). (msgsnd() n'est jamais
         relancé automatiquement après interruption par un gestionnaire de
         signal, quelle que soit la configuration de SA_RESTART lors de
         l'installation du gestionnaire.)

       Si l'appel système réussit, la structure décrivant la file de messages
       est mise à jour comme suit.

       • msg_lspid contient le PID du processus appelant.

       • msg_qnum est incrémenté de 1.

       • msg_stime est rempli avec l'heure actuelle.

   msgrcv()
       L'appel système msgrcv() supprime un message depuis la file indiquée par
       msqid et le place dans le tampon pointé par msgp.

       L'argument msgsz indique la taille maximale en octets du membre mtext de
       la structure pointée par l'argument msgp. Si le contenu du message est
       plus long que msgsz octets, le comportement dépend de la présence ou non
       de MSG_NOERROR dans msgflg. Si MSG_NOERROR est spécifié, alors le message
       sera tronqué (et la partie tronquée sera perdue) ; si MSG_NOERROR n'est
       pas spécifié, le message ne sera pas extrait de la file, et l'appel
       système échouera en renvoyant -1 et en indiquant E2BIG dans errno.

       À moins que MSG_COPY ne soit indiqué dans msgflg (voir ci-dessous),
       l’argument msgtyp indique le type de message désiré.

       • Si msgtyp vaut 0, le premier message est lu.

       • Si msgtyp est supérieur à 0, alors le premier message de type msgtyp
         est extrait de la file. Si msgflg contient MSG_EXCEPT l'inverse est
         effectué, le premier message de type différent de msgtyp est extrait de
         la file.

       • Si msgtyp est inférieur à 0, le premier message de la file avec un type
         inférieur ou égal à la valeur absolue de msgtyp est extrait.

       L'argument msgflg est composé d'un OU binaire « | » avec les attributs
       suivants.

       IPC_NOWAIT
              S’arrêter immédiatement si aucun message du type désiré n'est
              présent dans la file. L'appel système échoue et errno est
              configuré à ENOMSG.

       MSG_COPY (depuis Linux 3.8)
              Récupérer une copie de façon non destructive du message dans la
              file à la position ordinale indiquée par msgtyp (les messages sont
              considérées numérotés à partir de 0).

              Cet attribut doit être indiqué en conjonction avec IPC_NOWAIT, de
              telle sorte que si aucun message n’est disponible à la position
              donnée, l’appel échoue immédiatement avec l’erreur ENOMSG. Parce
              qu'ils modifient le sens de msgtyp de manière opposée, MSG_COPY et
              MSG_EXCEPT ne peuvent être définis simultanément dans msgflg.

              L'attribut MSG_COPY a été ajouté pour l’implémentation de point de
              restauration du noyau et n’est disponible que si le noyau a été
              compilé avec l’option CONFIG_CHECKPOINT_RESTORE.

       MSG_EXCEPT
              Utilisé avec msgtyp supérieur à 0 pour lire les messages de type
              différent de msgtyp.

       MSG_NOERROR
              Tronquer silencieusement les messages plus longs que msgsz octets.

       Si aucun message du type requis n'est disponible et si on n'a pas demandé
       IPC_NOWAIT dans msgflg, le processus appelant est bloqué jusqu'à
       l'occurrence d'un des événements suivants.

       • Un message du type désiré arrive dans la file.

       • La file de messages est supprimée. L'appel système échoue et errno
         contient EIDRM.

       • Le processus appelant intercepte un signal. Dans ce cas l'appel système
         échoue avec errno valant EINTR. (msgrcv() n'est jamais relancé
         automatiquement après interruption par un gestionnaire de signal,
         quelle que soit la configuration de SA_RESTART lors de l'installation
         du gestionnaire.)

       Si l'appel système réussit, la structure décrivant la file de messages
       est mise à jour comme suit.

              msg_lrpid est rempli avec le PID du processus appelant.

              msg_qnum est décrémenté de 1.

              msg_rtime est rempli avec l'heure actuelle.

VALEUR RENVOYÉE
       En cas d'échec les deux appels système renvoient -1 et errno contient le
       code d'erreur. Sinon msgsnd() renvoie 0 et msgrcv() renvoie le nombre
       d'octets copiés dans la table mtext.

ERREURS
       En cas d'échec de msgsnd(), errno aura l'une des valeurs suivantes.

       EACCES The calling process does not have write permission on the message
              queue, and does not have the CAP_IPC_OWNER capability in the user
              namespace that governs its IPC namespace.

       EAGAIN Le message n'a pas pu être envoyé à cause de la limite msg_qbytes
              pour la file et de la requête IPC_NOWAIT dans msgflg.

       EFAULT msgp pointe en dehors de l'espace d'adressage accessible.

       EIDRM  La file de messages a été supprimée.

       EINTR  Un signal est arrivé avant d'avoir pu écrire quoi que ce soit.

       EINVAL msqid est invalide, ou bien mtype n'est pas positif, ou bien msgsz
              est invalide (négatif ou supérieur à la valeur MSGMAX du système).

       ENOMEM Le système n'a pas assez de mémoire pour copier le message pointé
              par msgp.

       En cas d'échec de msgrcv(), errno prend l'une des valeurs suivantes.

       E2BIG  Le message est plus long que msgsz, et MSG_NOERROR n'a pas été
              indiqué dans msgflg.

       EACCES The calling process does not have read permission on the message
              queue, and does not have the CAP_IPC_OWNER capability in the user
              namespace that governs its IPC namespace.

       EFAULT msgp pointe en dehors de l'espace d'adressage accessible.

       EIDRM  La file de messages a été supprimée alors que le processus
              attendait un message.

       EINTR  Un signal est arrivé avant d'avoir pu lire quoi que ce soit ;
              consultez signal(7).

       EINVAL msqid was invalid, or msgsz was less than 0.

       EINVAL (depuis Linux 3.14)
              msgflg définit MSG_COPY sans définir IPC_NOWAIT.

       EINVAL (depuis Linux 3.14)
              msgflg définit à la fois MSG_COPY et MSG_EXCEPT.

       ENOMSG IPC_NOWAIT a été indiqué dans msgflg et aucun message du type
              réclamé n'existe dans la file.

       ENOMSG IPC_NOWAIT et MSG_COPY ont été indiqués dans msgflg et la file
              contient moins de msgtyp messages.

       ENOSYS (depuis Linux 3.8)
              MSG_COPY a été indiqué dans msgflg et le noyau a été configuré
              sans CONFIG_CHECKPOINT_RESTORE.

CONFORMITÉ
       POSIX.1-2001, POSIX.1-2008, SVr4.

       Les attributs MSG_EXCEPT et MSG_COPY sont spécifiques à Linux. Leur
       définition peut être obtenue en définissant la macro de test de
       fonctionnalités _GNU_SOURCE.

NOTES
       L'inclusion de <sys/types.h> et <sys/ipc.h> n'est pas nécessaire sous
       Linux et n'est exigée par aucune version de POSIX. Cependant, certaines
       implémentations anciennes nécessitent l'inclusion de ces fichiers
       d'en-tête, et le SVID documente aussi leur inclusion. Les applications
       ayant pour but d'être portables pourraient inclure ces fichiers
       d'en-tête.

       L'argument msgp est déclaré comme un struct msgbuf * avec les
       bibliothèques glibc 2.0 et glibc 2.1. Il est déclaré comme un void * avec
       la bibliothèque glibc 2.2, suivant ainsi les spécifications SUSv2 et
       SUSv3.

       Les limites suivantes concernent les files de messages et affectent
       l’appel msgsnd().

       MSGMAX Maximum size of a message text, in bytes (default value: 8192
              bytes).  On Linux, this limit can be read and modified via
              /proc/sys/kernel/msgmax.

       MSGMNB Maximum number of bytes that can be held in a message queue
              (default value: 16384 bytes).  On Linux, this limit can be read
              and modified via /proc/sys/kernel/msgmnb.  A privileged process
              (Linux: a process with the CAP_SYS_RESOURCE capability)  can
              increase the size of a message queue beyond MSGMNB using the
              msgctl(2)  IPC_SET operation.

       L'implémentation des files de messages sous Linux n'a pas de limites
       système intrinsèques ni pour le nombre d'en‐têtes de messages (MSGTQL) ni
       pour la taille, en octets, de l'ensemble de tous les messages (MSGPOOL).

BOGUES
       Jusqu'à la version Linux 3.13, si msgrcv() était appelé avec l’attribut
       MSG_COPY, mais sans IPC_NOWAIT, et que la file de messages contenait
       moins de msgtyp messages, alors l’appel bloquait jusqu’à ce que le
       message suivant soit écrit dans la file. À ce moment là, l’appel
       renvoyait une copie du message, quelle que soit la position ordinale
       msgtyp de ce message. Ce bogue est corrigé depuis Linux 3.14.

       Indiquer à la fois MSG_COPY et MSC_EXCEPT dans msgflg est une erreur de
       logique (puisque ces attributs imposent des interprétations différentes
       de msgtyp). Jusqu'à Linux 3.13, cette erreur n’était pas diagnostiquée
       par msgsrv(). Ce bogue est corrigé depuis Linux 3.14.

EXEMPLES
       The program below demonstrates the use of msgsnd()  and msgrcv().

       The example program is first run with the -s option to send a message and
       then run again with the -r option to receive a message.

       The following shell session shows a sample run of the program:

           $ ./a.out -s
           sent: a message at Wed Mar  4 16:25:45 2015

           $ ./a.out -r
           message received: a message at Wed Mar  4 16:25:45 2015

   Source du programme

       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <time.h>
       #include <unistd.h>
       #include <errno.h>
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       struct msgbuf {
           long mtype;
           char mtext[80];
       };

       static void
       usage(char *prog_name, char *msg)
       {
           if (msg != NULL)
               fputs(msg, stderr);

           fprintf(stderr, "Usage: %s [options]\n", prog_name);
           fprintf(stderr, "Options are:\n");
           fprintf(stderr, "-s        send message using msgsnd()\n");
           fprintf(stderr, "-r        read message using msgrcv()\n");
           fprintf(stderr, "-t        message type (default is 1)\n");
           fprintf(stderr, "-k        message queue key (default is 1234)\n");
           exit(EXIT_FAILURE);
       }

       static void
       send_msg(int qid, int msgtype)
       {
           struct msgbuf msg;
           time_t t;

           msg.mtype = msgtype;

           time(&t);
           snprintf(msg.mtext, sizeof(msg.mtext), "a message at %s",
                   ctime(&t));

           if (msgsnd(qid, (void *) &msg, sizeof(msg.mtext),
                       IPC_NOWAIT) == -1) {
               perror("msgsnd error");
               exit(EXIT_FAILURE);
           }
           printf("sent: %s\n", msg.mtext);
       }

       static void
       get_msg(int qid, int msgtype)
       {
           struct msgbuf msg;

           if (msgrcv(qid, (void *) &msg, sizeof(msg.mtext), msgtype,
                      MSG_NOERROR | IPC_NOWAIT) == -1) {
               if (errno != ENOMSG) {
                   perror("msgrcv");
                   exit(EXIT_FAILURE);
               }
               printf("No message available for msgrcv()\n");
           } else
               printf("message received: %s\n", msg.mtext);
       }

       int
       main(int argc, char *argv[])
       {
           int qid, opt;
           int mode = 0;               /* 1 = send, 2 = receive */
           int msgtype = 1;
           int msgkey = 1234;

           while ((opt = getopt(argc, argv, "srt:k:")) != -1) {
               switch (opt) {
               case 's':
                   mode = 1;
                   break;
               case 'r':
                   mode = 2;
                   break;
               case 't':
                   msgtype = atoi(optarg);
                   if (msgtype <= 0)
                       usage(argv[0], "-t option must be greater than 0\n");
                   break;
               case 'k':
                   msgkey = atoi(optarg);
                   break;
               default:
                   usage(argv[0], "Unrecognized option\n");
               }
           }

           if (mode == 0)
               usage(argv[0], "must use either -s or -r option\n");

           qid = msgget(msgkey, IPC_CREAT | 0666);

           if (qid == -1) {
               perror("msgget");
               exit(EXIT_FAILURE);
           }

           if (mode == 2)
               get_msg(qid, msgtype);
           else
               send_msg(qid, msgtype);

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI
       msgctl(2), msgget(2), capabilities(7), mq_overview(7), sysvipc(7)

COLOPHON
       Cette page fait partie de la publication 5.08 du projet man-pages Linux.
       Une description du projet et des instructions pour signaler des anomalies
       et la dernière version de cette page, peuvent être trouvées à l'adresse
       https://www.kernel.org/doc/man-pages/.


TRADUCTION
       La traduction française de cette page de manuel a été créée par
       Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin
       <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>,
       François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe
       Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-
       luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas
       Huriaux <thomas.huriaux@gmail.com>, Nicolas François
       <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>,
       Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier
       <barbier@debian.org> et David Prévot <david@tilapin.org>

       Cette traduction est une documentation libre ; veuillez vous reporter à
       la GNU General Public License version 3 concernant les conditions de
       copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

       Si vous découvrez un bogue dans la traduction de cette page de manuel,
       veuillez envoyer un message à <debian-l10n-french@lists.debian.org>.



Linux                             11 avril 2020                         MSGOP(2)