MSGCTL - Linux手册页
Linux程序员手册 第2部分
更新日期: 2020-04-11
名称
msgctl-系统V消息控制操作
语法
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf);
说明
msgctl()在标识符为msqid的System V消息队列上执行cmd指定的控制操作。
msqid_ds数据结构定义如下:
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; /* Creation time/time of last modification via msgctl() */ unsigned long __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) */ };
msgid_ds结构的字段如下:
- msg_perm
- 这是一个ipc_perm结构(请参见下文),用于指定对消息队列的访问权限。
- msg_qnum
- 当前在消息队列上的消息数。
- msg_qbytes
- 消息队列上允许的消息文本的最大字节数。
- msg_lspid
- 执行上一次msgsnd(2)系统调用的进程的ID。
- msg_lrpid
- 执行最后一个msgrcv(2)系统调用的进程的ID。
- msg_stime
- 上一次msgsnd(2)系统调用的时间。
- msg_rtime
- 上一次msgrcv(2)系统调用的时间。
- msg_ctime
- 创建队列的时间或上一次msgctl()IPC_SET操作的时间。
ipc_perm结构的定义如下(突出显示的字段可使用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 */ unsigned short mode; /* Permissions */ unsigned short __seq; /* Sequence number */ };
ipc_perm结构的mode字段的最低9位定义了消息队列的访问权限。权限位如下:
0400 | Read by user |
0200 | Write by user |
0040 | Read by group |
0020 | Write by group |
0004 | Read by others |
0002 | Write by others |
系统未使用位0100、0010和0001(执行位)。
cmd的有效值为:
- IPC_STAT
- 将信息从与msqid相关的内核数据结构复制到buf指向的msqid_ds结构中。调用方必须对消息队列具有读取权限。
- IPC_SET
- 将buf指向的msqid_ds结构的某些成员的值写入与此消息队列关联的内核数据结构,同时还更新其msg_ctime成员。该结构的以下成员已更新:msg_qbytes,msg_perm.uid,msg_perm.gid和msg_perm.mode(最低9位)。调用过程的有效UID必须与消息队列的所有者(msg_perm.uid)或创建者(msg_perm.cuid)相匹配,否则调用者必须具有特权。为了使msg_qbytes值超出系统参数MSGMNB,需要具有适当的特权(Linux:CAP_SYS_RESOURCE功能)。
- IPC_RMID
- 立即删除消息队列,唤醒所有等待的读取器和写入器进程(错误返回并将errno设置为EIDRM)。调用过程必须具有适当的特权,或其有效用户ID必须是消息队列的创建者或所有者的ID。在这种情况下,将忽略msgctl()的第三个参数。
- IPC_INFO(Linux-specific)
- 在buf指向的结构中返回有关系统范围的消息队列限制和参数的信息。如果定义了_GNU_SOURCE功能测试宏,则此结构的类型为msginfo(因此需要强制转换):
struct msginfo { int msgpool; /* Size in kibibytes of buffer pool used to hold message data; unused within kernel */ int msgmap; /* Maximum number of entries in message map; unused within kernel */ int msgmax; /* Maximum number of bytes that can be written in a single message */ int msgmnb; /* Maximum number of bytes that can be written to queue; used to initialize msg_qbytes during queue creation (msgget(2)) */ int msgmni; /* Maximum number of message queues */ int msgssz; /* Message segment size; unused within kernel */ int msgtql; /* Maximum number of messages on all queues in system; unused within kernel */ unsigned short int msgseg; /* Maximum number of segments; unused within kernel */ };
- 可以通过同名的/ proc文件更改msgmni,msgmax和msgmnb设置。有关详细信息,请参见proc(5)。
- MSG_INFO(Linux-specific)
- 返回一个msginfo结构,该结构包含与IPC_INFO相同的信息,不同之处在于,以下字段返回有关消息队列消耗的系统资源的信息:msgpool字段返回系统上当前存在的消息队列的数量; msgmap字段返回系统上所有队列中的消息总数; msgtql字段返回系统上所有队列中所有消息中的字节总数。
- MSG_STAT(Linux-specific)
- 返回与IPC_STAT相同的msqid_ds结构。但是,msqid参数不是队列标识符,而是进入内核内部数组的索引,该索引维护有关系统上所有消息队列的信息。
- MSG_STAT_ANY(Linux-specific, since Linux 4.17)
- 返回与MSG_STAT相同的msqid_ds结构。但是,不会检查msg_perm.mode是否具有msqid的读取访问权限,这意味着任何用户都可以使用此操作(就像任何用户都可以读取/ proc / sysvipc / msg以获得相同的信息一样)。
返回值
成功时,IPC_STAT,IPC_SET和IPC_RMID返回0。成功的IPC_INFO或MSG_INFO操作将返回内核内部阵列中使用最高的条目的索引,该索引记录有关所有消息队列的信息。 (此信息可以与重复的MSG_STAT或MSG_STAT_ANY操作一起使用,以获取有关系统上所有队列的信息。)成功的MSG_STAT或MSG_STAT_ANY操作将返回其索引以msqid给出的队列的标识符。
发生错误时,返回-1,并带有errno表示错误。
错误说明
失败时,errno设置为以下之一:
- EACCES
- 参数cmd等于IPC_STAT或MSG_STAT,但是调用进程对消息队列msqid没有读取权限,并且在控制其IPC名称空间的用户名称空间中不具有CAP_IPC_OWNER功能。
- EFAULT
- 参数cmd的值为IPC_SET或IPC_STAT,但是buf指向的地址不可访问。
- EIDRM
- 消息队列已删除。
- EINVAL
- cmd或msqid的值无效。或:对于MSG_STAT操作,在msqid中指定的索引值引用了当前未使用的阵列插槽。
- EPERM
- 参数cmd的值为IPC_SET或IPC_RMID,但是调用进程的有效用户ID不是消息队列的创建者(在msg_perm.cuid中找到)或所有者(在msg_perm.uid中找到)以及调用者没有特权(Linux:不具有CAP_SYS_ADMIN功能)。
- EPERM
- 尝试(IPC_SET)将msg_qbytes增加到系统参数MSGMNB之后,但是没有给调用方特权(Linux:不具有CAP_SYS_RESOURCE功能)。
遵循规范
POSIX.1-2001,POSIX.1-2008,SVr4。
备注
在Linux或任何版本的POSIX上,都不需要包含和。但是,一些旧的实现需要包含这些头文件,并且SVID也记录了这些头文件。打算移植到这样的旧系统的应用程序可能需要包含这些头文件。
ipcs(1)程序使用IPC_INFO,MSG_STAT和MSG_INFO操作来提供有关已分配资源的信息。将来,这些内容可能会修改或移至/ proc文件系统接口。
在Linux 2.2下,结构msqid_ds中的各个字段键入为short,而在Linux 2.4下则变为long。要利用此优势,在glibc-2.1.91或更高版本下进行重新编译就足够了。 (内核通过cmd中的IPC_64标志区分新旧呼叫。)
另外参见
msgget(2),msgrcv(2),msgsnd(2),功能(7),mq_overview(7),sysvipc(7)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。