【问题标题】:msgsnd no permission errormsgsnd 没有权限错误
【发布时间】:2017-03-03 07:48:23
【问题描述】:

我想在两个进程之间发送消息。但是当我尝试使用msgsnd() 发送消息时出现EACCES 错误

创建消息队列

const char* MSG_QUEUE = "/tmp/msg_queue";

int file = open(MSG_QUEUE, O_CREAT | O_RDWR | O_APPEND, 0755);
close(file);
key_t key = ftok(MSG_QUEUE, 1);
errno = 0;
msg_queue = msgget(key, IPC_CREAT);
if(msg_queue == -1) {
    M_DEBUG("Error %s\r\n", strerror(errno));
}

消息结构

struct feld_msg_s {
    long id;
    char mtext[5];
};

发送消息

struct feld_msg_s a_msg = {1, "Test"};
errno = 0;
int ret = msgsnd(msg_queue, &a_msg, sizeof(a_msg.mtext), 0);
if(ret == -1) {
    if(errno == EACCES) {
        printf("\r\n NO PERMISSION\r\n");
    } else {
        printf("msgsnd ERROR!: %s\r\n", strerror(errno));
    }
}

在msgsnd的manpage中写着

EACCES调用进程没有消息队列的读权限,也没有CAP_IPC_OWNER能力。

所以我使用setcap 命令添加了以下功能

sudo setcap CAP_SETFCAP,CAP_IPC_OWNER+epi /home/mvollmer/build-APP-Desktop_Qt_5_6_1_GCC_64bit-Debug/APP 

我已经与getcap 核对了应用程序是否具备这些功能。没关系。但我仍然收到无权限错误。

当以 root 权限执行应用程序时,它的工作!

有一点很奇怪,虽然 msgget 成功了ipcs 没有显示任何消息队列。

那么我的错在哪里?

我正在使用 Linux Mint

附加问题:是否可以在 msg 结构中使用另一种数据类型然后是 char,或者消息是否仅限于字符串?

【问题讨论】:

  • 试试这个msg_queue = msgget(key, IPC_CREAT | 0666)
  • msgget 被调用时,我得到一个EACCES。当我删除文件/tmp/msg_queue msggetmsgsnd 时成功...谢谢!但是为什么呢?!
  • 这很奇怪..现在每次都有效..删除文件并添加后| 0666 到 msgget 标志。消息队列现在用 ipcs 显示!非常感谢你
  • 不客气。这是在消息队列上设置正确权限的问题。 0666 表示允许所有人读/写。
  • 您不允许 groupother 写入此文件。

标签: c unix message-queue linux-capabilities


【解决方案1】:

您需要阅读手册页。每the POSIX msgget() standard

概要

#include <sys/msg.h>

int msgget(key_t key, int msgflg); [Option End]

描述

...

  • msg_perm.mode的低9位应设置为msgflg的低9位。

因此,这段代码

msg_queue = msgget(key, IPC_CREAT);

将“msgflg 的低 9 位”全部设置为零。因此消息队列模式也是全部0 - 任何人都没有权限。

【讨论】: