dwww Home | Manual pages | Find package

MSGOP(2)                      System Calls Manual                     MSGOP(2)

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

BIBLIOTHÈQUE
       Bibliothèque C standard (libc, -lc)

SYNOPSIS
       #include <sys/msg.h>

       int msgsnd(int msqid, const void msgp[.msgsz], size_t msgsz,
                      int msgflg);

       ssize_t msgrcv(int msqid, void msgp[.msgsz], size_t msgsz, long msgtyp,
                      int msgflg);

DESCRIPTION
       Les  appels  système  msgsnd() et msgrcv() servent respectivement à en-
       voyer 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'appe-
       lant 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-des-
       sous).

   msgsnd()
       L'appel système msgsnd() insère une copie du message pointé par l'argu-
       ment 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  struc-
       ture  associée à la file de messages. Durant la création de la file, ce
       champ est initialisé à MSGMNB octets, mais cette limite peut être modi-
       fié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 msg-
       snd() est de bloquer jusqu'à obtenir suffisamment  d'espace.  En  indi-
       quant  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 re-
          lancé  automatiquement après interruption par un gestionnaire de si-
          gnal, quelle que soit la configuration de SA_RESTART lors de  l'ins-
          tallation 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 confi-
              guré à 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  posi-
              tion  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 oc-
              tets.

       Si aucun message du type requis n'est disponible et si on n'a  pas  de-
       mandé  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 sys-
          tè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'installa-
          tion 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 de succès, msgsnd() renvoie 0  et  msgrcv()  renvoie  le  nombre
       d'octets  vraiment  copiés dans la table mtext. En cas d'échec les deux
       appels système renvoient -1 et définissent errno  pour  indiquer  l'er-
       reur.

ERREURS
       msgsnd() peut échouer avec les 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 n'est pas valable, ou bien mtype n'est pas positif, ou
              bien  msgsz  est  non  valable (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() peut échouer avec les 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  at-
              tendait 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.

STANDARDS
       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 fonction-
       nalités _GNU_SOURCE.

NOTES
       L'argument  msgp  est déclaré comme un struct msgbuf * avec les biblio-
       thè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  aug-
              menter  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  (MSG-
       POOL).

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 mes-
       sage 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  en-
       voyer un message, puis réexécuté avec l'option -r pour recevoir un mes-
       sage.

       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 <errno.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>
       #include <time.h>
       #include <unistd.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", nom_prog);
           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)
       {
           time_t         t;
           struct msgbuf  msg;

           msg.mtype = msgtype;

           time(&t);
           snprintf(msg.mtext, sizeof(msg.mtext), "un message à %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 = envoyé, 2 = reçu */
           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], "l'option -t doit être plus grande que 0\n");
                   break;
               case 'k':
                   msgkey = atoi(optarg);
                   break;
               default:
                   usage(argv[0], "option non reconnue\n");
               }
           }

           if (mode == 0)
               usage(argv[0], "doit être l'option -s ou -r \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)

TRADUCTION
       La  traduction française de cette page de manuel a été créée par Chris-
       tophe Blaess <https://www.blaess.fr/christophe/>, Stéphan  Rafin  <ste-
       phan.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.cou-
       lon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>,  Thomas  Huriaux
       <thomas.huriaux@gmail.com>,  Nicolas François <nicolas.francois@centra-
       liens.net>, Florentin Duneau <fduneau@gmail.com>, Simon  Paillard  <si-
       mon.paillard@resel.enst-bretagne.fr>,    Denis   Barbier   <barbier@de-
       bian.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⟩.

Pages du manuel de Linux 6.03   5 février 2023                        MSGOP(2)

Generated by dwww version 1.15 on Sat Jun 29 00:26:21 CEST 2024.