MSGOP(2) System Calls Manual MSGOP(2) NOM msgrcv, msgsnd - Operations sur les files de messages System V BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include 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 systeme msgsnd() et msgrcv() servent respectivement a envoyer et a recevoir des messages d'une file de messages System V. Le processus appelant doit avoir une permission d'ecriture 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 definie par l'appelant de la forme generale suivante : struct msgbuf { long mtype; /* type de message, doit etre > 0 */ char mtext[1]; /* contenu du message */ }; Le champ mtext est un tableau (ou une autre structure) de taille msgsz, valeur entiere positive ou nulle. Les messages de taille nulle (sans champ mtext) sont autorises. Le membre mtype doit avoir une valeur strictement positive qui puisse etre utilisee par le processus lecteur pour la selection de messages (voir la description de msgrcv() ci-dessous). msgsnd() L'appel systeme msgsnd() insere une copie du message pointe par l'argument msgp dans la file dont l'identifiant est indique par la valeur de l'argument msqid. S'il y a assez de place dans la file, msgsnd() reussit immediatement. La capacite de la file est regie par le champ msg_qbytes de la structure associee a la file de messages. Durant la creation de la file, ce champ est initialise a MSGMNB octets, mais cette limite peut etre modifiee avec msgctl(2). Une file de message est consideree pleine si une de ces conditions est remplie : - Apres l'ajout d'un message a la file, le nombre total d'octets dans la file aurait depasse la taille maximale de la file (champ msg_qbytes). - Apres l'ajout d'un message a la file, le nombre total de messages dans la file aurait depasse la taille maximale de la file (champ msg_qbytes).Cette verification permet d'eviter qu'un nombre illimite de messages de taille nulle soit ajoute a la file. Bien que tels messages ne contiennent pas de donnees, ils consomment neanmoins de la memoire du noyau, sujette a un verrou. S'il n'y a pas assez de place, alors le comportement par defaut de msgsnd() est de bloquer jusqu'a obtenir suffisamment d'espace. En indiquant IPC_NOWAIT dans l'argument msgflg, le message ne sera pas envoye et l'appel systeme echouera en retournant EAGAIN dans errno. Un appel a msgsnd() bloque peut echouer si : - la file est supprimee, auquel cas l'appel systeme echoue avec errno valant EIDRM ; ou - un signal a ete intercepte, auquel cas l'appel systeme echoue avec errno valant EINTR ; consultez signal(7). (msgsnd() n'est jamais relance automatiquement apres interruption par un gestionnaire de signal, quelle que soit la configuration de SA_RESTART lors de l'installation du gestionnaire.) Si l'appel systeme reussit, la structure decrivant la file de messages est mise a jour comme suit. - msg_lspid contient le PID du processus appelant. - msg_qnum est incremente de 1. - msg_stime est rempli avec l'heure actuelle. msgrcv() L'appel systeme msgrcv() supprime un message depuis la file indiquee par msqid et le place dans le tampon pointe par msgp. L'argument msgsz indique la taille maximale en octets du membre mtext de la structure pointee par l'argument msgp. Si le contenu du message est plus long que msgsz octets, le comportement depend de la presence ou non de MSG_NOERROR dans msgflg. Si MSG_NOERROR est specifie, alors le message sera tronque (et la partie tronquee sera perdue) ; si MSG_NOERROR n'est pas specifie, le message ne sera pas extrait de la file, et l'appel systeme echouera en renvoyant -1 et en indiquant E2BIG dans errno. A moins que MSG_COPY ne soit indique dans msgflg (voir ci-dessous), l'argument msgtyp indique le type de message desire. - Si msgtyp vaut 0, le premier message est lu. - Si msgtyp est superieur a 0, alors le premier message de type msgtyp est extrait de la file. Si msgflg contient MSG_EXCEPT l'inverse est effectue, le premier message de type different de msgtyp est extrait de la file. - Si msgtyp est inferieur a 0, le premier message de la file avec un type le plus proche inferieur ou egal a la valeur absolue de msgtyp est extrait. L'argument msgflg est compose d'un OU binaire << | >> avec les attributs suivants. IPC_NOWAIT S'arreter immediatement si aucun message du type desire n'est present dans la file. L'appel systeme echoue et errno est configure a ENOMSG. MSG_COPY (depuis Linux 3.8) Recuperer une copie de facon non destructive du message dans la file a la position ordinale indiquee par msgtyp (les messages sont considerees numerotes a partir de 0). Cet attribut doit etre indique en conjonction avec IPC_NOWAIT, de telle sorte que si aucun message n'est disponible a la position donnee, l'appel echoue immediatement avec l'erreur ENOMSG. Parce qu'ils modifient le sens de msgtyp de maniere opposee, MSG_COPY et MSG_EXCEPT ne peuvent etre definis simultanement dans msgflg. L'attribut MSG_COPY a ete ajoute pour l'implementation du point de restauration du noyau et n'est disponible que si le noyau a ete compile avec l'option CONFIG_CHECKPOINT_RESTORE. MSG_EXCEPT Utilise avec msgtyp superieur a 0 pour lire les messages de type different 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 demande IPC_NOWAIT dans msgflg, le processus appelant est bloque jusqu'a l'occurrence d'un des evenements suivants: - Un message du type desire arrive dans la file. - La file de messages est supprimee. L'appel systeme echoue et errno contient EIDRM. - Le processus appelant intercepte un signal. Dans ce cas l'appel systeme echoue avec errno valant EINTR. (msgrcv() n'est jamais relance automatiquement apres interruption par un gestionnaire de signal, quelle que soit la configuration de SA_RESTART lors de l'installation du gestionnaire.) Si l'appel systeme reussit, la structure decrivant la file de messages est mise a jour comme suit. msg_lrpid est rempli avec le PID du processus appelant. msg_qnum est decremente de 1. msg_rtime est rempli avec l'heure actuelle. VALEUR RENVOYEE En cas de succes, msgsnd() renvoie 0 et msgrcv() renvoie le nombre d'octets vraiment copies dans la table mtext. En cas d'echec les deux appels systeme renvoient -1 et definissent errno pour indiquer l'erreur. ERREURS msgsnd() peut echouer avec les valeurs suivantes : EACCES Le processus appelant n'a pas de permission de lecture dans la file et n'a pas la capacite CAP_IPC_OWNER dans l'espace de noms qui gere son espace de noms IPC. EAGAIN Le message n'a pas pu etre envoye a cause de la limite msg_qbytes pour la file et de la requete IPC_NOWAIT dans msgflg. EFAULT msgp pointe en dehors de l'espace d'adressage accessible. EIDRM La file de messages a ete supprimee. EINTR Un signal est arrive avant d'avoir pu ecrire quoi que ce soit. EINVAL msqid est n'est pas valable, ou bien mtype n'est pas positif, ou bien msgsz est non valable (negatif ou superieur a la valeur MSGMAX du systeme). ENOMEM Le systeme n'a pas assez de memoire pour copier le message pointe par msgp. msgrcv() peut echouer avec les valeurs suivantes : E2BIG Le message est plus long que msgsz, et MSG_NOERROR n'a pas ete indique dans msgflg. EACCES Le processus appelant n'a pas de permission de lecture dans la file et n'a pas la capacite CAP_IPC_OWNER dans l'espace de noms qui gere son espace de noms IPC. EFAULT msgp pointe en dehors de l'espace d'adressage accessible. EIDRM La file de messages a ete supprimee alors que le processus attendait un message. EINTR Un signal est arrive avant d'avoir pu lire quoi que ce soit ; consultez signal(7). EINVAL msgqid n'etait pas valable ou msgsz valait moins de 0. EINVAL (depuis Linux 3.14) msgflg definit MSG_COPY sans definir IPC_NOWAIT. EINVAL (depuis Linux 3.14) msgflg definit a la fois MSG_COPY et MSG_EXCEPT. ENOMSG IPC_NOWAIT a ete indique dans msgflg et aucun message du type reclame n'existe dans la file. ENOMSG IPC_NOWAIT et MSG_COPY ont ete indiques dans msgflg et la file contient moins de msgtyp messages. ENOSYS (depuis Linux 3.8) MSG_COPY et IPC_NOWAIT ont ete indiques dans msgflg et le noyau a ete configure sans CONFIG_CHECKPOINT_RESTORE. STANDARDS POSIX.1-2008. Les attributs MSG_EXCEPT et MSG_COPY sont specifiques a Linux. Leur definition peut etre obtenue en definissant la macro de test de fonctionnalites _GNU_SOURCE. HISTORIQUE POSIX.1-2001, SVr4. L'argument msgp est declare comme un struct msgbuf * avec les bibliotheques glibc 2.0 et glibc 2.1. Il est declare comme un void * avec la bibliotheque glibc 2.2, suivant ainsi les specifications SUSv2 et SUSv3. NOTES Les limites suivantes concernent les files de messages et affectent l'appel msgsnd(). MSGMAX Taille maximale d'un message texte, en octets (valeur par defaut : 8192 octets). Sous Linux, cette limite peut etre lue et modifiee grace au fichier /proc/sys/kernel/msgmax). MSGMNB Nombre maximal d'octets d'une file de messages (valeur par defaut : 16384 octets. Sous Linux, elle peut etre lue et modifiee grace au fichier /proc/sys/kernel/msgmnb). Un processus privilegie (sous Linux : avec la capacite CAP_SYS_RESOURCE) peut augmenter la taille d'une file de messages au-dela de MSGMNB en utilisant l'operation IPC_SET de msgctl(2). L'implementation des files de messages sous Linux n'a pas de limites systeme intrinseques ni pour le nombre d'en-tetes de messages (MSGTQL) ni pour la taille, en octets, de l'ensemble de tous les messages (MSGPOOL). BOGUES Jusqu'a la version Linux 3.13, si msgrcv() etait appele 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'a ce que le message suivant soit ecrit dans la file. A ce moment la, l'appel renvoyait une copie du message, quelle que soit la position ordinale msgtyp de ce message. Ce bogue est corrige depuis Linux 3.14. Indiquer a la fois MSG_COPY et MSC_EXCEPT dans msgflg est une erreur de logique (puisque ces attributs imposent des interpretations differentes de msgtyp). Jusqu'a Linux 3.13, cette erreur n'etait pas diagnostiquee par msgsrv(). Ce bogue est corrige depuis Linux 3.14. EXEMPLES Le programme ci-dessous montre l'utilisation de msgsnd() et de msgrcv(). Le programme d'exemple est d'abord execute avec l'option -s pour envoyer un message, puis reexecute avec l'option -r pour recevoir un message. La session d'interpreteur suivant montre un echantillon d'execution du programme : $ ./a.out -s envoi : un message le mercredi 4 mars 2015 a 16:25:45 $ ./a.out -r message recu : un message le mercredi 4 mars 2015 a 16:25:45 Source du programme #include #include #include #include #include #include #include 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 defaut)\n"); fprintf(stderr, "-k cle de mise en attente du message (1234 par defaut)\n"); exit(EXIT_FAILURE); } static void send_msg(int qid, int msgtype) { time_t t;0 struct msgbuf msg; 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("envoye : %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( exit(EXIT_FAILURE); } printf("Aucun message disponible pour msgrcv()\n"); } else { printf("message recu : %s\n", msg.mtext); } } int main(int argc, char *argv[]) { int qid, opt; int mode = 0; /* 1 = send, 2 = receive */0 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], break; case 'k': msgkey = atoi(optarg); break; default: usage(argv[0], "Option non reconnue\n"); } } if (mode == 0) usage(argv[0], "doit etre 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 francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 MSGOP(2)