Chapter Contents |
Previous |
Next |
msgctl |
Portability: |
SYNOPSIS | |
DESCRIPTION | |
RETURN VALUE | |
USAGE NOTES | |
EXAMPLE 1 | |
EXAMPLE 2 | |
RELATED FUNCTIONS |
SYNOPSIS |
#include <sys/msg.h> int msgctl(int id, int cmd, struct msgid_ds *buf);
DESCRIPTION |
The
msgctl
function is used to perform one of several control operations on an
UNIX System Services message queue.
Note: See the
msgget
function description in section msgget for general
information about message queues.
The
id
argument to
msgctl
specifies a message queue
id. This argument is an id, such as the id returned by
msgget
, not a message queue key, which might
be passed as an argument to
msgget
.
The
cmd
argument
should be specified as a symbolic constant specifying the particular operation
to be performed by
msgctl
.
The constant values are described below.
Several of the
msgctl
operations allow you to obtain or access the message queue id data structure,
which is mapped by the
struct
msqid_ds
type defined in
sys/msg.h
. This data structure is defined as follows:
struct msqid_ds { /* permission information */ struct ipc_perm msg_perm; /* messages presently on the queue */ unsigned msg_qnum; /* max bytes of queued info */ unsigned msg_qbytes; /* process id of last sender */ pid_t msg_lspid; /* process id of last receiver */ pid_t msg_lrpid; /* time of last msgsnd call */ time_t msg_stime; /* time of last msg(x)rcv call */ time_t msg_rtime; /* time of last change by msgget/msgctl */ time_t msg_ctime; };
The
ipc_perm
structure,
which contains security information about the owner and the creator of the
message queue, is defined as follows:
struct ipc_perm { /* owner's effective user ID */ uid_t uid; /* owner's effective group ID */ gid_t gid; /* creator's effective user ID */ uid_t cuid; /* creator's effective group ID */ gid_t cgid; /* read/write permission bits */ mode_t mode; };
For
msgctl
operations
which access or modify the message queue data structure, the
buf
argument addresses a
struct msqid_ds
, used as described below. For
other operations, the
buf
argument is ignored.
The
cmd
values accepted
by
msgctl
and their meanings
are as follows:
IPC_RMID
-
Removes the message queue and its id from the system. The
buf
argument is not used by this operation.
IPC_SET
-
Can be used to change the ownership of a message queue or the access rules.
The contents of
buf->msg_perm.uid
,
buf->msg_perm.gid
and
buf->msg_perm.mode
will be copied to the message queue id data structure.
IPC_STAT
-
Returns the contents of the message queue id data structure. All elements
of the data structure are stored in the object addressed by
buf
.
RETURN VALUE |
msgctl
returns
0
if successful,
or
-1
if unsuccessful.
USAGE NOTES |
The
msgctl
function can only be used with MVS 5.2.2 or a later release.
EXAMPLE 1 |
This example is compiled using
sascc370 -Krent -o
. This program uses the functions
msgget()
,
msgsnd()
,
msgrcv()
,
and
msgctl()
to establish
an IPC Server using Message Queues.
/*-------------------------+ | 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 <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; /*------------------------------------*/ /* Create message queue. */ /* Give everyone read/write */ /* permissions. */ /*------------------------------------*/ msgKey = MSG_KEY; msgFlags = IPC_CREAT | MSG_PERM; if ( (msgQID = msgget(msgKey, msgFlags)) < 0 ) { perror("SERVER: msgget"); exit(EXIT_FAILURE); } /*---------------------------------------*/ /* Receive a message from client. */ /*---------------------------------------*/ msgType = CLIENT_MSG_TYPE; msgFlags = 0; if (msgrcv(msgQID, &recMsg, MAX_MSGSIZE, msgType, msgFlags) < 0) { perror("SERVER: msgrcv"); msgctl(msgQID, IPC_RMID, NULL); exit(EXIT_FAILURE); } /*-----------------------------------------*/ /* Print message received from client. */ /*-----------------------------------------*/ printf("%s\n", recvMsg.text); /*------------------------------------------*/ /* Send ACK Message to client. */ /*------------------------------------------*/ sendMsg.type = SERVER_MSG_TYPE; sprintf(sendMsg.text, "From SERVER: Message received!"); msgFlags = 0; if (msgsnd(msgQID, &sendMsg, strlen(sendMsg.text)+1, msgFlags) < 0) { perror("SERVER: msgsnd"); msgctl(msgQID, IPC_RMID, NULL); exit(EXIT_FAILURE); } /*--------------------------------------------*/ /* Go to sleep to allow time for the client */ /* to recieve the message */ /* before removing the message queue. */ /*--------------------------------------------*/ sleep(60); /*--------------------------------------------*/ /* Call msgctl to remove message queue. */ /*--------------------------------------------*/ if (msgctl(msgQID, IPC_RMID, NULL) < 0) { perror("SERVER: msgctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } /* end of main() */
EXAMPLE 2 |
This example is compiled using
sascc370 -Krent -o.
This program usese the functions
msgctl()
,
msgget()
,
msgsnd()
, and
msgxrcv
to establish 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 <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> /*--------------------------------------------+ | 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 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; /* command to message queue, used w/ msgctl * int msgQcmd; / /* message type */ long msgType; /* message key */ key_t msgKey; /* message to send */ Message sendMsg; /* message received - eXtended */ XMessage recvMsg; /*------------------------------------------*/ /* Create message queue. */ /* Give everyone read/write permissions. */ /*------------------------------------------*/ msgKey = MSG_KEY; msgFlags = IPC_CREAT | MSG_PERM; if ( (msgQID = msgget(msgKey, msgFlags)) < 0 ) { perror("SERVER: msgget"); exit(EXIT_FAILURE); } /*---------------------------------------------*/ /* Receive a message from client. */ /*---------------------------------------------*/ msgType = CLIENT_MSG_TYPE; msgFlags = 0; if (msgxrcv(msgQID, &recMsg, MAX_MSGSIZE, msgType, msgFlags) < 0) { perror("SERVER: msgrcv"); msgctl(msgQID, IPC_RMID, NULL); exit(EXIT_FAILURE); } /*---------------------------------------------*/ /* Print message received from client. */ /*---------------------------------------------*/ printf("Message: %s\n", recvMsg.text); printf(" Time message was sent: %s\n", ctime(&recvMsg.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); /*-------------------------------------------*/ /* Send ACK XMessage to client. */ /*-------------------------------------------*/ sendMsg.type = SERVER_MSG_TYPE; sprintf( sendMsg.text, "From SERVER: XMessage received!"); msgFlags = 0; if (msgsnd(msgQID, &sendMsg, strlen(sendMsg.text)+1, msgFlags) < 0) { perror("SERVER: msgsnd"); msgctl(msgQID, IPC_RMID, NULL); exit(EXIT_FAILURE); } /*----------------------------------------------*/ /* Go to sleep to allow time for the client to */ /* recieve the message */ /* before removing the message queue. */ /*-------------------------------------------*/ sleep(60); /*----------------------------------------------*/ /* Call msgctl to remove message queue. */ /*----------------------------------------------*/ if (msgctl(msgQID, IPC_RMID, NULL) < 0) { perror("SERVER: msgctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } /* end of main() */
RELATED FUNCTIONS |
msgget
,
msgrcv
,
msgsnd
,
msgxrcv
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.