Chapter Contents |
Previous |
Next |
msgget |
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 (|):
IPC_CREAT
-
Specifies that if a queue with the requested
key
does not exist, it should be created. This flag is ignored if
IPC_PRIVATE
is specified.
IPC_EXCL
-
Specifies that a queue with the requested
key
must not already exist. This flag is ignored if
IPC_PRIVATE
is specified, or if
IPC_CREAT
is not specified.
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.
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".
/*---------------------------------+ | 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.