![]() 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. ![[cautionend]](../common/images/cautend.gif)
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". ![[cautionend]](../common/images/cautend.gif)
/*--------------------------------------------+
| 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.