The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct are as defined by the SV API Intel 386 Processor Supplement. don't complain about too long msgs.
typedef unsigned long | msglen_t |
typedef unsigned long | msgqnum_t |
typedef __pid_t | pid_t |
typedef __size_t | size_t |
typedef __ssize_t | ssize_t |
typedef __time_t | time_t |
IMPORT_C int | msgget | ( | key_t | key, |
int | msgflg | |||
) |
The msgget function returns the message queue identifier associated with key. A message queue identifier is a unique integer greater than zero.
A message queue is created if either key is equal to IPC_PRIVATE, or key does not have a message queue identifier associated with it and the IPC_CREAT bit is set in msgflg.
If a new message queue is created, the data structure associated with it (the msqid_ds structure, see msgctl is initialized as follows: msg_perm.cuid and msg_perm.uid are set to the effective uid of the calling process. In the current implementation, uid is set to root. msg_perm.gid and msg_perm.cgid are set to the effective gid of the calling process. In the current implementation, gid is set to root. msg_perm.mode is set to the lower 9 bits of msgflg. msg_cbytes, msg_qnum, msg_lspid, msg_lrpid, msg_rtime, and msg_stime are set to 0. msg_qbytes is set to the system wide maximum value for the number of bytes in a queue (Dv MSGMNB). msg_ctime is set to the current time.
Examples:
Example code to create a message queue using msgget
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id, len; struct { long mtype; char mtext[128]; } msg_buf; /* Create a message queue with a given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) { printf("Message Q create failed with errno %d ", errno); return -1; } msg_buf.mtype = 1; /* message identifier */ strcpy(msg_buf.mtext, "some_data_to_send"); /* data */ len = strlen(msg_buf.mtext)+1; /* Put the message in the queue */ if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) { printf("Message Q send failed with errno %d ", errno); } return 0; }Example code to return an existing message queue with msgget
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id; int msg_len = 128; int msg_type = 0; /* Any type of message */ struct { long mtype; char mtext[128]; } msg_buf; /* Get the message queue id for the given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, 0)) == -1) { printf("Message Q get id failed with errno %d ", errno); return -1; } /* Get the message from the queue */ if (msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0) == -1) { printf("Message Q recv failed with errno %d ", errno); } /* Remove the message queue */ if (msgctl(msq_id, IPC_RMID, NULL) == -1) { printf("Message Q delete failed with errno %d ", errno); return -1; } return 0; }
IMPORT_C int | msgsnd | ( | int | msqid, |
const void * | msgp, | |||
size_t | msgsz, | |||
int | msgflg | |||
) |
long mtype; /* message type */ char mtext[1]; /* body of message */
mtype is an integer greater than 0 that can be used for selecting messages (see msgrcv mtext is an array of bytes, with a size up to that of the system limit (Dv MSGMAX).
If the number of bytes already on the message queue plus msgsz is bigger than the maximum number of bytes on the message queue (Va msg_qbytes, see msgctl or the number of messages on all queues system-wide is already equal to the system limit, msgflg determines the action of msgsnd. If msgflg has IPC_NOWAIT mask set in it, the call will return immediately. If msgflg does not have IPC_NOWAIT set in it, the call will block until:
The condition which caused the call to block does no longer exist. The message will be sent. The message queue is removed, in which case -1 will be returned, and errno is set to EINVAL. After a successful call, the data structure associated with the message queue is updated in the following way:
msg_cbytes is incremented by the size of the message. msg_qnum is incremented by 1. msg_lspid is set to the pid of the calling process. msg_stime is set to the current time.
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id, len; struct { long mtype; char mtext[128]; } msg_buf; /* Create a message queue with the given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) { printf("Message Q create failed with errno %d ", errno); return -1; } msg_buf.mtype = 1; /* message identifier */ strcpy(msg_buf.mtext, "some_data_to_send"); /* data */ len = strlen(msg_buf.mtext)+1; /* Put the message in the queue */ if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) { printf("Message Q send failed with errno %d ", errno); } return 0; }
long mtype; /* message type */ char mtext[1]; /* body of message */
mtype is an integer greater than 0 that can be used for selecting messages, mtext is an array of bytes with a size up to that of the system limit (Dv MSGMAX).
The value of msgtyp has one of the following meanings: The msgtyp argument is greater than 0. The first message of type msgtyp will be received. The msgtyp argument is equal to 0. The first message on the queue (of any message type) will be received. The msgtyp argument is less than 0. The first message of the lowest message type that is less than or equal to the absolute value of msgtyp will be received.
The msgsz argument specifies the maximum length of the requested message. If the received message has a length greater than msgsz it will be silently truncated if the MSG_NOERROR flag is set in msgflg, otherwise an error will be returned.
If no matching message is present on the message queue specified by msqid, the behavior of msgrcv depends on whether the IPC_NOWAIT flag is set in msgflg or not. If IPC_NOWAIT is set, msgrcv will immediately return a value of -1 and set errno to ENOMSG. If IPC_NOWAIT is not set, the calling process will be blocked until: A message of the requested type becomes available on the message queue. The message queue is removed, in which case -1 will be returned and errno set to EINVAL.
If a message is successfully received, the data structure associated with msqid is updated as follows: msg_cbytes is decremented by the size of the message. msg_lrpid is set to the pid of the caller. msg_lrtime is set to the current time. msg_qnum is decremented by 1.
Examples:
Receive a message from the queue
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id; int msg_len = 128; int msg_type = 0; /* Any type of message */ struct { long mtype; char mtext[128]; } msg_buf; int ret_val = -1; /* Get the message queue id for the given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT)) == -1) { printf("Message Q get id failed with errno %d ", errno); return -1; } /* Get the message from the queue */ if ((ret_val = msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0)) == -1) { printf("Message Q recv failed with errno %d ", errno); } /* Remove the message queue */ if (msgctl(msq_id, IPC_RMID, NULL) == -1) { printf("Message Q delete failed with errno %d ", errno); return -1; } return ret_val; } Send a message to the queue #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id, len; struct { long mtype; char mtext[128]; } msg_buf; /* Create a message queue with the given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) { printf("Message Q create failed with errno %d0, errno); return -1; } msg_buf.mtype = 1; /* message identifier */ strcpy(msg_buf.mtext, "some_data_to_send"); /* data */ len = strlen(msg_buf.mtext)+1; /* Put the message in the queue */ if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) { printf("Message Q send failed with errno %d ", errno); } return 0; }
IMPORT_C int | msgctl | ( | int | msqid, |
int | cmd, | |||
struct msqid_ds * | buf | |||
) |
The msgctl system call performs some control operations on the message queue specified by msqid. Each message queue has a data structure associated with it, parts of which may be altered by msgctl and parts of which determine the actions of msgctl. The data structure is defined in <sys/msg.h> and contains (amongst others) the following members:
struct msqid_ds { struct ipc_perm msg_perm; /* msg queue permission bits */ struct msg *msg_first; /* first message in the queue */ struct msg *msg_last; /* last message in the queue */ u_long msg_cbytes; /* number of bytes in use on the queue */ u_long msg_qnum; /* number of msgs in the queue */ u_long msg_qbytes; /* max # of bytes on the queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* time of last msgsnd() */ long msg_pad1; time_t msg_rtime; /* time of last msgrcv() */ long msg_pad2; time_t msg_ctime; /* time of last msgctl() */ long msg_pad3; long msg_pad4[4]; };
struct ipc_perm { ushort cuid; /* creator user id */ ushort cgid; /* creator group id */ ushort uid; /* user id */ ushort gid; /* group id */ ushort mode; /* r/w permission */ ushort seq; /* sequence # (to generate unique msg/sem/shm id) */ key_t key; /* user specified msg/sem/shm key */ };
The operation to be performed by msgctl is specified in cmd and is one of: IPC_STAT Gather information about the message queue and place it in the structure pointed to by buf. IPC_SET Set the value of the msg_perm.uid, msg_perm.gid, msg_perm.mode and msg_qbytes fields in the structure associated with msqid. The values are taken from the corresponding fields in the structure pointed to by buf. Values for msg_qbytes that exceed the system limit (MSGMNB from <sys/msg.h>) are silently truncated to that limit. IPC_RMID Remove the message queue specified by msqid and destroy the data associated with it.
The permission to read from or write to a message queue (see msgsnd and msgrcv is determined by the msg_perm.mode field in the same way as is done with files (see chmod)
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id, len; struct { long mtype; char mtext[128]; } msg_buf; /* Create a message queue with a given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, IPC_CREAT | IPC_EXCL | 0666)) == -1) { printf("Message Q create failed with errno %d ", errno); return -1; } msg_buf.mtype = 1; /* message identifier */ strcpy(msg_buf.mtext, "some_data_to_send"); /* data */ len = strlen(msg_buf.mtext)+1; /* Put the message in the queue */ if (msgsnd(msq_id, (struct msgbuf *)&msg;_buf, len, 0) == -1) { printf("Message Q send failed with errno %d ", errno); } return 0; }
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> #include <errno.h> #define MESSAGE_Q_KEY 1000 int main(void) { int msq_id; int msg_len = 128; int msg_type = 0; /* Any type of message */ struct { long mtype; char mtext[128]; } msg_buf; /* Get the message queue id for the given key */ if ((msq_id = msgget(MESSAGE_Q_KEY, 0)) == -1) { printf("Message Q get id failed with errno %d ", errno); return -1; } /* Get the message from the queue */ if (msgrcv(msq_id, (struct msgbuf *)&msg;_buf, msg_len, msg_type, 0) == -1) { printf("Message Q recv failed with errno %d ", errno); } /* Remove the message queue */ if (msgctl(msq_id, IPC_RMID, NULL) == -1) { printf("Message Q delete failed with errno %d ", errno); return -1; } return 0; }
struct msg *msg_first struct msg *msg_last; long msg_pad1; long msg_pad2; long msg_pad3; long msg_pad4[4];and are not filled if msgctl is called with the flag IPC_STAT.