Chapter Contents

Previous

Next
msgget

msgget



Create or Find a Message Queue

Portability: UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
USAGE NOTES
EXAMPLE 1
EXAMPLE 2
EXAMPLE 3
EXAMPLE 4
EXAMPLE 5
RELATED FUNCTIONS


SYNOPSIS

#include <sys/msg.h>

int msgget(key_t key, int flags);


DESCRIPTION

The msgget function is used either to create a new message queue or to locate an existing queue based on a key. Message queues are implemented by UNIX System Services, and allow messages of multiple types to be queued. UNIX System Services message queues support multiple senders and multiple receivers and do not require the senders and receivers to be running simultaneously. Message queues, once created using msgget , remain in existence until they are explicitly destroyed with a call to msgctl .

The key argument is an integral value which identifies the message queue desired. A key value of IPC_PRIVATE requests a new message queue without an associated key , and which can be accessed only by the queue id returned by msgget .

The flags argument specifies zero or more option flags specifying whether or not the queue already exists, and how access to the queue should be regulated. The argument should be specified as 0 for no flags, or as one or more of the following symbolic constants, combined using the or operator (|):

Additionally, any of the permission bits S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP , S_IROTH and S_IWOTH may be specified as part of the flags argument, to regulate what users are permitted to access or modify the message queue. See the umask function description in the SAS/C Library Reference, Volume 2, for more information about the meaning of these flags.


RETURN VALUE

msgget returns the identifier of the message queue if successful, or -1 if unsuccessful.


USAGE NOTES

The msgget function can only be used with MVS 5.2.2 or a later release.

Note:   A site can impose limits on the number and size of queued messages.  [cautionend]


EXAMPLE 1

This example is compiled using sascc370 -Krent -o . This program uses the functions msgget() , msgsnd() , and msgrcv() to establish IPC Client using Message Queues.

/*------------------------------------------+
| POSIX/UNIX header files                   |
+-------------------------------------------*/
#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

/*------------------------------------------+
| ISO/ANSI header files                     |
+------------------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

/*------------------------------------------+
| Constants                                 |
+------------------------------------------*/
/* maximum message size           */
#define MAX_MSGSIZE          256    

/* message key, set by server     */
#define MSG_KEY      (key_t)1097    

/* Server's message type          */
#define SERVER_MSG_TYPE (long)10    

/* Client's message type          */
#define CLIENT_MSG_TYPE (long)20    

/* give everyone read/write       */
/* permission to messages         */
#define MSG_PERM  (S_IRUSR|S_IWUSR|S_IRGRP
  |S_IWGRP|S_IROTH|S_IWOTH)

/*---------------------------------+
| Types                            |
+---------------------------------*/
/* Declare the message structure. */
typedef struct Message              
{
/* positive message type          */
    long    type;                   
/* message data                   */
    char    text[MAX_MSGSIZE];      
}Message;

/*---------------------------------+
| Name:      main                  |
| Returns:   exit(EXIT_SUCCESS) or |
|            exit(EXIT_FAILURE)    |
+---------------------------------*/
int main()
{
/* message queue id                         */
    int msgQID;           

/* message flags                            */
    int msgFlags;         

/* message type                             */
    long msgType;         

/* message key                              */
    key_t msgKey;         

/* message to send                          */
    Message sendMsg;      

/* message received                         */
    Message recvMsg;      

/*------------------------------------------*/
/* Get the message queue id for MSG_KEY,    */
/* which was set by the                     */
/* message server.                          */
/*------------------------------------------*/
   msgKey = MSG_KEY;
   msgFlags = MSG_PERM;

   if ( (msgQID = msgget(msgKey, msgFlags)) < 0 )
   {
       perror("CLIENT: msgget");
       exit(EXIT_FAILURE);
   }

/*-------------------------------------------*/
/* Send the message.                         */
/*-------------------------------------------*/
   sendMsg.type = CLIENT_MSG_TYPE;
   sprintf
    (sendMsg.text, "From CLIENT: Are you there?");
   msgFlags = 0;

   if (msgsnd(msgQID, &sendMsg, 
     strlen(sendMsg.text)+1, msgFlags) < 0)
   {
   perror("CLIENT: msgsnd");
   exit(EXIT_FAILURE);
   }

/*-----------------------------------------*/
/* Receive a message from server.          */
/*-----------------------------------------*/
   msgType = SERVER_MSG_TYPE;
   msgFlags = 0;

   if (msgrcv(msgQID, &recMsg, MAX_MSGSIZE, 
     msgType, msgFlags) < 0)
   {
   perror("CLIENT: msgrcv");
   exit(EXIT_FAILURE);
   }

/*-------------------------------------------*/
/* Print message received from server.       */
/*-------------------------------------------*/
   printf("%s\n", recvMsg.text);
 
   exit(EXIT_SUCCESS);

}  /* end of main() */


EXAMPLE 2

Refer to msgctl for an example program that establishes an IPC Server using Message Queues.


EXAMPLE 3

This example is compiled using sascc370 -Krent -o . This program uses the msgget() function to create an IPC message queue and then uses the msgctl() function to retrieve statistics on the newly created message queue.

/*-------------------------------------------+
| POSIX/UNIX header files                    |
+-------------------------------------------*/
#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/msg.h>
 
/*-------------------------------------------+
| ISO/ANSI header files                      |
+-------------------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <time.h>

#include <errno.h>

/*-------------------------------------------+
| Types                                      |
+-------------------------------------------*/
/* message queue id structure     */
typedef struct msqid_ds MsgQueueID; 

/*--------------------------------------------+
| Constants                                   |
+--------------------------------------------*/
/* message key                    */
#define MSG_KEY      (key_t)1097    

/* give everyone read/write permission to     */
/*messages                                    */
#define MSG_PERM (S_IRUSR|S_IWUSR|S_IRGRP
  |S_IWGRP|S_IROTH|S_IWOTH)

/*---------------------------------------------+
| Name:      main                              |
| Returns:   exit(EXIT_SUCCESS) or             |
|            exit(EXIT_FAILURE)                |
+---------------------------------------------*/
int main()
{
/* message queue id                   */
    int msgQID;                 

/* message flags                      */
    int msgFlags;               

/* command to message queue.          */
    int msgQcmd;                

/* message key                        */
    key_t msgKey;               

/* message queue id data structure    */
    MsgQueueID * msgQueue;      

/*---------------------------------------------*/
/* Create message queue.                       */
/* Give everyone read/write permissions.       */
/*---------------------------------------------*/
   msgKey = MSG_KEY;
   msgFlags = IPC_CREAT | MSG_PERM;

   if ( (msgQID = msgget(msgKey, msgFlags)) < 0 )
   {
       perror("MSGSTAT: msgget");
       exit(EXIT_FAILURE);
   }

/*-----------------------------------------------*/
/* Allocate memory to store information from     */
/* message queue                                 */
/*-----------------------------------------------*/
   msgQueue = malloc(sizeof(MsgQueueID));

   if (msgQueue == NULL)
   {
   fprintf(stderr,
   "ERROR: 
   Cannot allocate memory for message queue
   stats\n");
   exit(EXIT_FAILURE);
   }

/*-----------------------------------------------*/
/* Call msgctl to retrieve information from      */
/* message queue                                 */
   /*--------------------------------------------*/
   msgQcmd = IPC_STAT;

   if (msgctl(msgQID, msgQcmd, msgQueue) < 0)
   {
   perror
   ("MSGSTAT: msgctl failed to retrieve 
   message queue stats");
   free(msgQueue);
   exit(EXIT_FAILURE);
   }
 
/*-----------------------------------------------*/
/* Print infomation retrieved from message queue */
/*-----------------------------------------------*/
   printf("Message Queue ID statistics:\n\n");
   printf("\tQueue owner's effective user ID: 
     %d\n",(int)msgQueue->msg_perm.uid);
   printf("\tQueue owner's effective group ID: 
     %d\n",(int)msgQueue->msg_perm.gid);
   printf("\tQueue creator's effective user ID: 
     %d\n",(int)msgQueue->msg_perm.cuid);
   printf("\tQueue creator's effective group ID: 
     %d\n",(int)msgQueue->msg_perm.cgid);
   printf("\tQueue permission mode bits: 
     %#.3o\n\n",(int)msgQueue->msg_perm.mode);
   printf("\tNumber of messages currently on Queue: 
     %d\n",msgQueue->msg_qnum);
   printf("\tMaximum bytes of queued info: 
     %d\n", msgQueue->msg_qbytes);
   printf("\tProcess id of last sender: 
     %d\n", (int)msgQueue->msg_lspid);
   printf("\tProcess id of last receiver: 
     %d\n", (int)msgQueue->msg_lrpid);
   printf("\tTime of last msgsnd call: 
     %s",ctime(&msgQueue->msg_stime));
   printf("\tTime of last msg(x)rcv call: 
     %s",ctime(&msgQueue->msg_rtime));
   printf("\tTime of last chg by msgget/msgctl: 
     %s",ctime(&msgQueue->msg_ctime));

/*-------------------------------------------------*/
/* Free memory used to store information from      */
/* message queue                                   */
/*-------------------------------------------------*/
   free(msgQueue);

/*--------------------------------------------------*/
/* Call msgctl to remove message queue.             */
/*--------------------------------------------------*/
   msgQcmd = IPC_RMID;

  if (msgctl(msgQID, msgQcmd, NULL) < 0)
  {
  perror
  ("MSGSTAT: msgctl failed to remove 
    message queue");
  exit(EXIT_FAILURE);
   }
 
   exit(EXIT_SUCCESS);

}  /* end of main() */


EXAMPLE 4

This example is compiled using sascc370 -Krent -o .

This program uses the functions msgget() , msgsnd() , and msgxrcv() to establish an IPC Client using XMessage Queues. Also, it uses UNIX System Service's extended Message structure.

Note:   You cannot use the Extended Message structure to send a message, i.e., call msgsnd() with this structure. Attempting to do so will cause the program to "hang".   [cautionend]

/*---------------------------------+
| POSIX/UNIX header files          |
+---------------------------------*/
#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

/*---------------------------------+
| ISO/ANSI header files            |
+----------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <time.h>

#include <errno.h>

/*---------------------------------+
| Constants                        |
+---------------------------------*/
/* maximum message size           */
#define MAX_MSGSIZE          256    

/* message key, set by server     */
#define MSG_KEY      (key_t)1097    

/* Server's message type          */
#define SERVER_MSG_TYPE (long)10    

/* Client's message type          */
#define CLIENT_MSG_TYPE (long)20    

/* give everyone read/write       */
/* permission to messages         */
#define MSG_PERM  
 (S_IRUSR|S_IWUSR|S_IRGRP
  |S_IWGRP|S_IROTH|S_IWOTH)

/*-----------------------------------+
| Types                              |
+-----------------------------------*/
/* Declare the message structure. */
typedef struct Message              
{
/* positive message type          */
    long    type;                   
/* message data                   */
    char    text[MAX_MSGSIZE];      
}Message;

/* Declare the OE Extended message structure. */
typedef struct XMessage 
{
/* time msg sent                  */
    time_t  time;                   

/* effective uid of sender        */
    uid_t   uid;                    

/* effective gid of sender        */
    gid_t   gid;                    

/* process id of sender           */
    pid_t   pid;                    

/* positive message type          */
    long    type;                   

/* message data                   */
    char    text[MAX_MSGSIZE];      
}XMessage;

/*----------------------------------+
| Name:      main                   |
| Returns:   exit(EXIT_SUCCESS) or  |
|            exit(EXIT_FAILURE)     |
+----------------------------------*/
int main()
{
/* message queue id                         */
    int msgQID;           

/* message flags                            */
    int msgFlags;         

/* message type                             */
    long msgType;         

/* message key                              */
    key_t msgKey;         

/* message to send                          */
    Message sendMsg;      

/* message received - eXtended              */
    XMessage recvMsg;     

/*-------------------------------------------*/
/* Get the message queue id for MSG_KEY,     */
/* which was set by the                      */
/* message server.                           */
/*-------------------------------------------*/
   msgKey = MSG_KEY;
   msgFlags = MSG_PERM;

   if ( (msgQID = msgget(msgKey, msgFlags)) < 0 )
   {
       perror("CLIENT: msgget");
       exit(EXIT_FAILURE);
   }

/*----------------------------------------------*/
/* Send the message.                            */
/*----------------------------------------------*/
sendMsg.type = CLIENT_MSG_TYPE;
sprintf
  (sendMsg.text, "From CLIENT: Are you there?");
  msgFlags = 0;

if (msgsnd(msgQID, &sendMsg, 
   strlen(sendMsg.text)+1, msgFlags) < 0)
   {
       perror("CLIENT: msgsnd");
       exit(EXIT_FAILURE);
   }

/*------------------------------------------*/
/* Receive a message from server.           */
/*------------------------------------------*/
   msgType = SERVER_MSG_TYPE;
   msgFlags = 0;

  if (msgxrcv(msgQID, 
   &recMsg, MAX_MSGSIZE, msgType, msgFlags) < 0)
   {
       perror("CLIENT: msgrcv");
       exit(EXIT_FAILURE);
   }

/*------------------------------------------*/
/* Print message received from server.      */
/*------------------------------------------*/
   printf("Message: %s\n", recvMsg.text);
   printf("   Time message was sent: %s\n", 
     ctime(&recMsg.time));
   printf("   The user id of sender: %d\n", 
    (int)recvMsg.uid);
   printf("  The group id of sender: %d\n", 
    (int)recvMsg.gid);
   printf("The process id of sender: %d\n", 
    (int)recvMsg.pid);
 
   exit(EXIT_SUCCESS);

}  /* end of main() */


EXAMPLE 5

Refer to msgctl for an example that establishes an IPC Server using Message Queues. Also, it uses UNIX System Service's extended Message structure.


RELATED FUNCTIONS

msgctl , msgrcv , msgsnd , msgxrcv


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.