jammy (2) msgrcv.2.gz

Provided by: manpages-fr-dev_4.13-4_all bug

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

       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

       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 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.

       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 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'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 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.10 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 ⟨⟩.