C 设置消息队列的大小“;“不允许”;

C 设置消息队列的大小“;“不允许”;,c,linux,permissions,message-queue,C,Linux,Permissions,Message Queue,我试图设置POSIX消息队列的大小,但似乎不被允许 msgctl()手册页说明: IPC_集只能由具有适当权限的进程执行 或的有效用户ID等于 msqid_ds数据结构中的msg_perm.cuid或msg_perm.uid 与msqid关联。只有具有适当权限的进程才能 提高msg_qbytes的值 以下测试程序返回: uid: 1324 effective uid: 1324 msgctl(msqid=8028175, IPC_SET, ...) failed (msg_perm.uid=1

我试图设置POSIX消息队列的大小,但似乎不被允许

msgctl()
手册页说明:

IPC_集只能由具有适当权限的进程执行 的有效用户ID等于 msqid_ds数据结构中的msg_perm.cuid或msg_perm.uid 与msqid关联。只有具有适当权限的进程才能 提高msg_qbytes的值

以下测试程序返回:

uid: 1324
effective uid: 1324
msgctl(msqid=8028175, IPC_SET, ...) failed 
(msg_perm.uid=1324,msg_perm.cuid=1324): Operation not permitted (errno=1)

#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int iArgC,字符**ppszArgv)
{
printf(“uid:%u\n”,getuid());
printf(“有效uid:%u\n”,geteuid());
int msqid=msgget(
IPC_PRIVATE,
IPC_创建|
S|u IRGRP | S|u IWGRP|
S|u IRUSR | S|u IWUSR|
S|IROTH | S|IWOTH);
如果(0>msqid)
{
fprintf(标准,
“msgget()失败。\n”);
返回退出失败;
}
{
结构msqid_ds ds={0};
如果(msgctl(
msqid,
IPC_统计,
&()
{
fprintf(标准,
msgctl(msqid=%d,IPC_STAT,…)失败:
%s(错误号=%d)\n,
msqid,
斯特雷罗(埃尔诺),
埃尔诺);
返回退出失败;
}
ds.msg_qbytes=1024*1024;
如果(msgctl(
msqid,
IPC_集,
&()
{
fprintf(标准,
msgctl(msqid=%d,IPC_集,…)失败
(msg_perm.uid=%u)
“msg_perm.cuid=%u:”
%s(错误号=%d)\n,
msqid,
ds.msg_perm.uid,
ds.msg_perm.cuid,
斯特雷罗(埃尔诺),
埃尔诺);
}
返回退出失败;
}
返回退出成功;
}
/*EOF*/
那么,诀窍是什么呢?

来自:

将msg_qbytes值提升到系统参数MSGMNB之外需要适当的权限(Linux:CAP_IPC_资源能力)


在我的系统上,MSGNMB是16kb,远低于您尝试设置的1Mb。你查过这个限额了吗?(Do
cat/proc/sys/kernel/msgmnb

cat/proc/sys/kernel/msgmnb
给我65536,msgctl(…,IPC_STAT…)在
msg_qbytes
中返回的值是多少。已经看到了这一点,我仍然不确定有效用户ID[是否]等于与msqid关联的msqid ds数据结构中msg_perm.cuid或msg_perm.uid的值。是
适当的特权
,因为我引用的手册页中有
**或**
@jpalecek@alk:否。“适当权限”是CAP_IPC_资源能力。您引用的内容基本上意味着您只能操作队列的
msgqbytes
,但只能在0-64 kB范围内操作。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int iArgC, char ** ppszArgv)
{
  printf("uid: %u\n", getuid());
  printf("effective uid: %u\n", geteuid());

  int msqid = msgget(
    IPC_PRIVATE,
    IPC_CREAT |
    S_IRGRP | S_IWGRP |
    S_IRUSR | S_IWUSR |
    S_IROTH | S_IWOTH);

  if (0 > msqid)
  {
    fprintf(stderr,
        "msgget() failed.\n");
    return EXIT_FAILURE;
  }

  {
    struct msqid_ds ds = {0};

    if (msgctl(
        msqid,
        IPC_STAT,
        &ds))
    {
      fprintf(stderr,
          "msgctl(msqid=%d, IPC_STAT, ...) failed: "
          "%s (errno=%d)\n",
          msqid,
          strerror(errno),
          errno);

      return EXIT_FAILURE;
    }

    ds.msg_qbytes = 1024*1024;

    if (msgctl(
        msqid,
        IPC_SET,
        &ds))
    {
      fprintf(stderr,
          "msgctl(msqid=%d, IPC_SET, ...) failed "
          "(msg_perm.uid=%u,"
          "msg_perm.cuid=%u): "
          "%s (errno=%d)\n",
          msqid,
          ds.msg_perm.uid,
          ds.msg_perm.cuid,
          strerror(errno),
          errno);
    }

    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

/* EOF */