mq_open 的 oflag 参数不反映创建的 mqueue 文件的实际访问位

mq_open's oflag argument doesn't reflect actual access bits of created mqueue file

我在 linux 5.5.6 上给 mq_open 打电话,像这样:

mq_open("/testing12345", O_RDWR | O_CREAT | O_NONBLOCK, 0777, & (struct mq_attr) {0, 10, 255, 0));

请注意,我将 0777 作为第三个参数传递。

该函数成功并创建了适当的 mqueue,之后我从 shell 安装 mqueue 文件系统:

mount -t mqueue none ./mqueue_dir

但是,stat-ing 新 mqueue 的节点显示 0755 作为访问位:

stat -c %a ./mqueue_dir/testing12345

0755

这是为什么?我在调用 mq_open.

时显然传递了 0777 常量

可重现的例子

编译为 gcc -Wall -Werror -lrt a.c -o ./a

#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <mqueue.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(void) {
    const mqd_t descriptor = mq_open("/testing12345", O_RDWR | O_CREAT | O_NONBLOCK, 0777, & (struct mq_attr) {0, 10, 255, 0});
    if(descriptor == -1) {
        perror("parent: failed opening mqueue");
        return EXIT_FAILURE;
    }

    sleep(30u);

    mq_unlink("/testing123");

    return EXIT_SUCCESS;
}

您的 "file creation mask" 设置几乎可以肯定设置为 022,因此 "masking" 您将 "down" 指定为 0755

Per the POSIX umask() documentation(加粗我的):

NAME

umask - set and get the file mode creation mask

SYNOPSIS

#include <sys/stat.h>

mode_t umask(mode_t cmask);

DESCRIPTION

The umask() function shall set the file mode creation mask of the process to cmask and return the previous value of the mask. Only the file permission bits of cmask (see <sys/stat.h>) are used; the meaning of the other bits is implementation-defined.

The file mode creation mask of the process is used to turn off permission bits in the mode argument supplied during calls to the following functions:

  • open(), openat(), creat(), mkdir(), mkdirat(), mkfifo(), and mkfifoat()

  • mknod(), mknodat()

  • mq_open()

  • sem_open()

Bit positions that are set in cmask are cleared in the mode of the created file.

另见 When is umask() useful?

有效地,为了确保您创建的文件具有特定模式,您要么必须使用 umask( 0 ) 清空文件创建掩码,要么必须明确设置您要创建的确切模式想要 你创建文件之后。由于调用 umask() 会影响 整个 进程的状态,因此直接显式设置模式几乎总是更好。