C 调用open(2)忽略S_IWGRP和S_IWOTH标志
C 调用open(2)忽略S_IWGRP和S_IWOTH标志,c,debian,C,Debian,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的补码屏蔽。因此,如果umask已设置为022(典型值),权限将被0755屏蔽(按位anded) 如果在创建文件时确实
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
的补码屏蔽。因此,如果umask
已设置为022
(典型值),权限将被0755
屏蔽(按位anded)
如果在创建文件时确实需要文件以原子方式具有组/世界写入权限,则可以调用
umask(0)
,但这通常是一种不好的做法,因为该设置是进程全局设置,可能会导致在其他地方(或子进程)创建不安全的文件。一个更好的方法,如果它是有效的,只是在打开文件后添加了被屏蔽掉的权限来调用<代码> fCHMOD<代码>。 你需要考虑进程<代码> UMask值。请参见man 2 umask
umask值从提供给open(2)
的权限掩码中减去。也就是说,如果您打开(文件,O|u create | O|u WRONLY,mymask),那么实际的mask不是mymask
,而是mymask&~umask
大多数用户以umask值022
[octal]开始,即S|u IWGRP|S|u IWOTH
用户的umask值可以通过shell内置命令umask
控制
进程可以通过umask(2)
syscall更改umask值。在您的情况下,请尝试:
oldval = umask(0);
open(...);
umask(oldval);
注意:这在单线程环境中可以正常工作,但是多线程程序应该采取额外的步骤
另一种方法是使用fchmod
:
fd = open(...);
fchmod(fd,mymask);
这对于多线程来说可能更安全,但如果程序在打开
之间但在fchmod
之前中止,则最终会出现与您相同的情况(例如零掩码)。因此,适时的
、系统崩溃等都会产生这种情况
更新: 我对此感到困惑,因为当我打印S_IRWXU标志的实际值时,我得到了442。为什么它不仅仅是一个数字7 我不完全确定,因为我不知道
442
是十进制还是八进制,但我会尝试覆盖所有的基数
通常以八进制[“%o”
格式]打印的权限掩码的布局为:
owner(3) | group(3) | other(3)
也就是说,每个都有3位宽
S_IRWXU
define是“所有所有者权限”的固定定义。它的八进制值为700
,即448
十进制。因此,如果您正在执行printf(“%d\n”,S\u IRWXU)
我希望448
printf(“%d\n”,mask&S\u IRWXU)
[或者甚至printf(“%d\n”,mask&S\u IRWXU)
]无法生成442
,因为十进制值是八进制672
。672
将被屏蔽为600
八进制或384
十进制。但是,这是不可能的
因此,如果十进制值真的是448
而不是442
,这将产生700
八进制,这意味着“所有者拥有所有权限”
因此,对我来说,事情有意义的唯一方式是,442
是整个权限掩码的八进制值[并且被777
octal]屏蔽]
为了澄清,这里有一个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
值。但是,即使这样,这仍然没有多大意义,因为作为umask
值,删除所有者的读取权限并不是通常要做的事情
请注意,S_IRWXU
是00700
,因此,如果将其右移6,则会得到7
。同样地,S_IRWXG
是00070
,因此如果将其右移3,您也会得到7
更可能的是,您要屏蔽的值是S|u IRWXG | S|u IRWXO
[group/others],因为这正是您在原始问题中试图覆盖的内容
如果您仍然有问题,并且可以进一步说明如何获取该值,我可能可以进一步修改此内容以提供帮助。绝对是正确的方向!你能建议我如何理解计算算法吗?我对此感到困惑,因为当我打印S_IRWXU标志的实际值时,我得到了442。为什么它不仅仅是一个数字7?