调用 open(2) 会忽略 S_IWGRP 和 S_IWOTH 标志

标签 c debian

S_IWGRPS_IWOTH 标志在 open(2) 中指定时不会产生任何效果。

文件打开并创建为

open(file,O_CREAT|O_WRONLY,S_IWGRP|S_IWOTH);  

结果

---------- 1 root root 0 Jul 16 21:25 file  

任何其他标志都可以正常工作。

我应该从哪里开始排除故障?

最佳答案

您需要考虑进程 umask值(value)。请参阅man 2 umask .

从赋予 open(2) 的权限掩码中减去 umask 值。也就是说,如果你这样做 open(file,O_CREAT|O_WRONLY,mymask)那么实际掩码不是 mymask但是mymask & ~umask .

大多数用户以 022 的 umask 值开始[八进制],即S_IWGRP | S_IWOTH .

用户的umask值可以通过shell内置命令umask来控制.

进程可以通过 umask(2) 更改 umask 值系统调用。对于您的情况,请尝试:

oldval = umask(0);
open(...);
umask(oldval);

注意:这在单线程环境中工作正常,但对于多线程程序应采取额外的步骤。

另一种方法是使用fchmod :

fd = open(...);
fchmod(fd,mymask);

这对于多线程来说可能更安全,但是如果程序在 open 之间中止但在fchmod之前,您最终会遇到与您相同的情况(例如零掩码)。所以,一个<CTRL-C> 、系统崩溃等适时的事件都可能导致这种情况。


更新:

I'm confused about it because when I'm printing the real value of S_IRWXU flag I get an 442. Why it is not just a number 7

我不太确定,因为我不知道是否 442是十进制或八进制,但我会尝试涵盖所有基础[双关语:-)]。

权限掩码的布局,通常以八进制打印[ "%o"格式]是:

owner(3) | group(3) | other(3)

即每个位宽为3位

S_IRWXU Define 是“所有所有者权限”的固定定义。它的八进制值为 700这是 448十进制。所以,如果你正在做printf("%d\n",S_IRWXU)我期望 448

printf("%d\n",mask & S_IRWXU) [甚至printf("%d\n",mask & S_IRWXU) ] 不能产生 442因为十进制值是八进制 672672会被屏蔽为 600八进制或384十进制。但是,这是不可能的。

所以,如果十进制值真的 448442 ,这会产生 700八进制表示“所有者拥有所有权限”

所以,对我来说事情有意义的唯一方式是 442整个权限掩码的八进制值[并且根据 777 进行掩码八进制]。

为了澄清,这里是 stat.h 的文件片段定义了各种值[评论是我添加的]:

#define S_IRWXU 00700       // mask for owner
#define S_IRUSR 00400       // owner may read
#define S_IWUSR 00200       // owner may write
#define S_IXUSR 00100       // owner may execute

#define S_IRWXG 00070       // mask for group
#define S_IRGRP 00040       // group may read
#define S_IWGRP 00020       // group may write
#define S_IXGRP 00010       // group may execute

#define S_IRWXO 00007       // mask for others
#define S_IROTH 00004       // others may read
#define S_IWOTH 00002       // others may write
#define S_IXOTH 00001       // others may execute

所以,442r|r|w其中表示所有者和组可以读取,其他人可以写入[但不能读取]。这对于给定的文件没有多大意义,因此这意味着有问题的掩码是 umask值(value)。但是,即便如此,这仍然没有多大意义,因为,作为 umask值,删除所有者的读取权限并不是通常要做的事情。

请注意S_IRWXU00700 ,所以如果你将其右移 6,你就会得到 7 。同样,S_IRWXG00070 ,因此如果右移 3,您还会得到 7

更有可能的是,您想要屏蔽的值是 S_IRWXG | S_IRWXO [组/其他]因为这就是您在最初的问题中试图覆盖的内容。

如果您仍然遇到问题,并且可以进一步澄清您正在做什么来获得该值,我也许可以进一步修改此内容以提供帮助。

关于调用 open(2) 会忽略 S_IWGRP 和 S_IWOTH 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38415421/

相关文章:

linux - Parrot 操作系统问题

使用scanf检查C中用户输入是否为空

C 联编文件错误

node.js - 无法在我的 docker 镜像中安装 bcrypt

ubuntu - apt-get 更新在 chroot ubuntu 16.04 上失败

linux - 在 Linux 上升级 Aspnet Core 应用程序出现错误

php - 使用 php 邮件发送的邮件未显示

在 Unix 系统上创建子进程?

c - 如何正确比较 C 中的字符串?

c - pthread 指针数组