DESCRIPTION
msgctl() performs the control operation specified by cmd on the System V message queue with identifier msqid.
The msqid_ds data structure is defined in <sys/msg.h> as follows:struct msqid_ds {struct ipc_perm msg_perm;/* Ownership and permissions */
time_t msg_stime;/* Time of last msgsnd(2) */
time_t msg_rtime;/* Time of last msgrcv(2) */
time_t msg_ctime;/* Time of last change */unsignedlong __msg_cbytes;/* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum;/* Current number of messages
in queue */
msglen_t msg_qbytes;/* Maximum number of bytes
allowed in queue */
pid_t msg_lspid;/* PID of last msgsnd(2) */
pid_t msg_lrpid;/* PID of last msgrcv(2) */};
The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):struct ipc_perm {
key_t __key;/* Key supplied to msgget(2) */
uid_t uid;/* Effective UID of owner */
gid_t gid;/* Effective GID of owner */
uid_t cuid;/* Effective UID of creator */
gid_t cgid;/* Effective GID of creator */unsignedshort mode;/* Permissions */unsignedshort __seq;/* Sequence number */};
Valid values for cmd are:
IPC_STAT
Copy information from the kernel data structure associated with msqid into the msqid_ds structure pointed to by buf. The caller must have read permission on the message queue.
IPC_SET
Write the values of some members of the msqid_ds structure pointed to by buf to the kernel data structure associated with this message queue, updating also its msg_ctime member. The
following members of the structure are updated: msg_qbytes, msg_perm.uid, msg_perm.gid, and (the least significant 9 bits of) msg_perm.mode. The effective UID of the calling process
must match the owner (msg_perm.uid) or creator (msg_perm.cuid) of the message queue, or the caller must be privileged. Appropriate privilege (Linux: the CAP_SYS_RESOURCE capability) is
required to raise the msg_qbytes value beyond the system parameter MSGMNB.
IPC_RMID
Immediately remove the message queue, awakening all waiting reader and writer processes (with an error return and errno set to EIDRM). The calling process must have appropriate privi‐
leges or its effective user ID must be either that of the creator or owner of the message queue. The third argument to msgctl() is ignored in this case.
学习源码
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<errno.h>#include<string.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#define DEBUG#define MAX_LEN 80struct msg_body
{long mtype;char msg_data[MAX_LEN];};typedefstruct msg_body msg_t;enum msg_error
{
SUCCESS =0,
PARA_ERR,
SEND_ERR,
NONE_MSG,
RECV_ERR,
DATA_LONG,
MSGID_ERR,
DEBUG_ERR
};intmsg_err(int error,int line){#ifdef DEBUGfprintf(stderr,"---%d---\n", line);#endifswitch(error){case PARA_ERR:fprintf(stderr,"parament is NULL\n");break;case SEND_ERR:fprintf(stderr,"send data error\n");break;case NONE_MSG:fprintf(stderr,"no message in queue\n");break;case RECV_ERR:fprintf(stderr,"receive data error\n");break;case DATA_LONG:fprintf(stderr,"data is too long\n");break;case MSGID_ERR:fprintf(stderr,"get msg id error\n");break;case DEBUG_ERR:break;default:fprintf(stderr,"unrecognized error\n");}return error;}intmsg_usage(char*err){if(err ==NULL)return0;fprintf(stderr,"error : %s\n", err);fprintf(stderr,"Usage: msg [option]\n");fprintf(stderr,"option args\n");fprintf(stderr,"-s write message using msgsnd\n");fprintf(stderr,"-r read message using msgrcv\n");fprintf(stderr,"-d want to send message data, it must follow -s\n");fprintf(stderr,"-t message type(default is 1)\n");fprintf(stderr,"-k message queue key(default is 1234)\n");exit(EXIT_FAILURE);}intsend_msg(int msg_id, msg_t *msg){if(msg_id <0|| msg ==NULL){printf("msg_id = %d\n", msg_id);returnmsg_err(PARA_ERR,__LINE__);}#ifdef DEBUGfprintf(stderr,"mtype = %ld\n", msg->mtype);fprintf(stderr,"msg_id = %ld\n", msg_id);fprintf(stderr,"msg_data = %s\n", msg->msg_data);#endifif(0>msgsnd(msg_id,(void*)msg, MAX_LEN, IPC_NOWAIT)){returnmsg_err(SEND_ERR,__LINE__);}fprintf(stderr,"send msg successful...\n");return0;}intrecv_msg(int msg_id, msg_t *msg){if(msg_id <0|| msg ==NULL){printf("msg_id = %d\n", msg_id);returnmsg_err(PARA_ERR,__LINE__);}#ifdef DEBUGfprintf(stderr,"mtype = %ld\n", msg->mtype);fprintf(stderr,"msg_id = %ld\n", msg_id);#endifif(-1==msgrcv(msg_id,(void*)msg, MAX_LEN, msg->mtype, MSG_NOERROR | IPC_NOWAIT)){if(errno == ENOMSG){returnmsg_err(NONE_MSG,__LINE__);}returnmsg_err(RECV_ERR,__LINE__);}fprintf(stderr,"get msg is %s\n", msg->msg_data);return0;}intmain(int argc,char**argv){int ret =0;
msg_t msg;int mode =0;int key =1234;int msgid =0;int mtype =1;int opt =0;int len =0;memset(&msg,0,sizeof(msg_t));
msg.mtype = mtype;while(-1!=(opt =getopt(argc, argv,"srd:t:k:"))){switch(opt){case's':
mode =1;break;case'r':
mode =2;break;case'd':if(mode !=1)msg_usage("-d must at -s later\n");if((len =strlen(optarg))> MAX_LEN -1)returnmsg_err(DATA_LONG,__LINE__);memcpy(&(msg.msg_data), optarg, len);break;case't':
msg.mtype =atoi(optarg);break;case'k':
key =atoi(optarg);break;default:fprintf(stderr,"Unknow opt\n");exit(EXIT_FAILURE);}}if(mode ==0)msg_usage("must use either -s or -r\n");if(0>(msgid =msgget(key, IPC_CREAT |0666)))returnmsg_err(MSGID_ERR,__LINE__);#ifdef DEBUGfprintf(stderr,"mtype = %ld\n", msg.mtype);fprintf(stderr,"msg_id = %d\n", msgid);#endifif(mode ==1)send_msg(msgid,&msg);if(mode ==2)recv_msg(msgid,&msg);return0;}