Provided by: manpages-fr-dev_4.15.0-9_all bug

NOM

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

SYNOPSIS

       #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

       Les appels système msgsnd() et msgrcv() servent respectivement à envoyer et à recevoir des
       messages d'une file de messages System V. Le processus appelant doit avoir une  permission
       d'écriture  sur  la  file  pour  envoyer  un message, et une permission de lecture pour en
       recevoir un.

       L'argument msgp est un pointeur vers une structure définie  par  l'appelant  de  la  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 une autre structure) de taille msgsz, valeur entière
       positive ou nulle. Les messages 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  file  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 file 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 à un 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 le  plus  proche
         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 du 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

       On  success, msgsnd()  returns 0 and msgrcv()  returns the number of bytes actually copied
       into the mtext array. On failure, both functions return -1, and set errno to indicate  the
       error.

ERREURS

       msgsnd()  can fail with the following errors:

       EACCES Le  processus  appelant n'a pas de permission de lecture dans la file et n'a pas la
              capacité CAP_IPC_OWNER dans l'espace de noms qui gère son espace de noms IPC.

       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.

       msgrcv()  can fail with the following errors:

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

       EACCES Le processus appelant n'a pas de permission de lecture dans la file et n'a  pas  la
              capacité CAP_IPC_OWNER dans l'espace de noms qui gère son espace de noms IPC.

       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 msgqid n'était pas valable ou msgsz valait moins de 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  et  IPC_NOWAIT  ont  été indiqués 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'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 Taille  maximale  d'un  message texte, en octets (valeur par défaut : 8192 octets).
              Sous  Linux,  cette  limite  peut  être  lue   et   modifiée   grâce   au   fichier
              /proc/sys/kernel/msgmax).

       MSGMNB Nombre  maximal  d'octets d'une file de messages (valeur par défaut : 16384 octets.
              Sous   Linux,   elle   peut   être   lue   et    modifiée    grâce    au    fichier
              /proc/sys/kernel/msgmnb).  Un  processus  privilégié (sous Linux : avec la capacité
              CAP_SYS_RESOURCE) peut augmenter la taille d'une file de messages au-delà de MSGMNB
              en utilisant l’opération IPC_SET de msgctl(2).

       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

       Le programme ci-dessous montre l'utilisation de msgsnd() et de msgrcv().

       Le programme d'exemple est d'abord exécuté avec l'option -s pour envoyer un message,  puis
       réexécuté avec l'option -r pour recevoir un message.

       La session d'interpréteur suivant montre un échantillon d'exécution du programme :

           $ ./a.out -s
           envoi : un message le mercredi 4 mars 2015 à 16:25:45

           $ ./a.out -r
           message reçu : un message le mercredi 4 mars 2015 à 16:25:45

   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, "Utilisation : %s [options]\n", prog_name);
           fprintf(stderr, "Les options sont :\n");
           fprintf(stderr, "-s        envoyer un message en utilisant msgsnd()\n");
           fprintf(stderr, "-r        lire un message en utilisant msgrcv()\n");
           fprintf(stderr, "-t        type de message (1 par défaut)\n");
           fprintf(stderr, "-k        clé de la file de messages (1234 par défaut)\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, &msg, sizeof(msg.mtext),
                       IPC_NOWAIT) == -1) {
               perror("msgsnd error");
               exit(EXIT_FAILURE);
           }
           printf("envoyé : %s\n", msg.mtext);
       }

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

           if (msgrcv(qid, &msg, sizeof(msg.mtext), msgtype,
                      MSG_NOERROR | IPC_NOWAIT) == -1) {
               if (errno != ENOMSG) {
                   perror("msgrcv");
                   exit(EXIT_FAILURE);
               }
               printf("Aucun message disponible pour msgrcv()\n");
           } else
               printf("message reçu : %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.13 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>, David Prévot <david@tilapin.org>  et  Jean-Philippe  MENGUAL
       <jpmengual@debian.org>

       Cette  traduction  est  une  documentation libre ; veuillez vous reporter à la GNU General
       Public  License  version 3  ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   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⟩.