MSGCTL - Linux手册页

时间:2019-08-20 17:59:01  来源:igfitidea点击:

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位定义了消息队列的访问权限。权限位如下:

0400Read by user
0200Write by user
0040Read by group
0020Write by group
0004Read by others
0002Write by others

系统未使用位0100、0010和0001(执行位)。

cmd的有效值为:

IPC_STAT
将信息从与msqid相关的内核数据结构复制到buf指向的msqid_ds结构中。调用方必须对消息队列具有读取权限。
IPC_SET
将buf指向的msqid_ds结构的某些成员的值写入与此消息队列关联的内核数据结构,同时还更新其msg_ctime成员。该结构的以下成员已更新:msg_qbytesmsg_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/