Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 调用open(2)忽略S_IWGRP和S_IWOTH标志_C_Debian - Fatal编程技术网

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?