S_IWGRP
和 S_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
因为十进制值是八进制 672
。 672
会被屏蔽为 600
八进制或384
十进制。但是,这是不可能的。
所以,如果十进制值真的 448
和不442
,这会产生 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
所以,442
是 r|r|w
其中表示所有者和组可以读取,其他人可以写入[但不能读取]。这对于给定的文件没有多大意义,因此这意味着有问题的掩码是 umask
值(value)。但是,即便如此,这仍然没有多大意义,因为,作为 umask
值,删除所有者的读取权限并不是通常要做的事情。
请注意S_IRWXU
是 00700
,所以如果你将其右移 6,你就会得到 7
。同样,S_IRWXG
是 00070
,因此如果右移 3,您还会得到 7
更有可能的是,您想要屏蔽的值是 S_IRWXG | S_IRWXO
[组/其他]因为这就是您在最初的问题中试图覆盖的内容。
如果您仍然遇到问题,并且可以进一步澄清您正在做什么来获得该值,我也许可以进一步修改此内容以提供帮助。
关于调用 open(2) 会忽略 S_IWGRP 和 S_IWOTH 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38415421/