【问题标题】:Checking only the O_RDONLY flag to open(2)仅检查 O_RDONLY 标志以打开 (2)
【发布时间】:2016-06-17 22:22:29
【问题描述】:

我正在根据我在某些元文件中设置的权限检查发送到 open(2) 调用的标志。这里的 perms 与通常发送给 chmod 之类的调用的八进制值有关。我希望在 perms 与相关标志不匹配时输入 if 块。

if((perms == 4 && !(flags & O_RDONLY)) ||
   (perms == 2 && !(flags & O_WRONLY)) ||
   (perms == 6 && !(flags & O_RDWR))) 

我希望这可以工作,并且在 O_WRONLY 和 O_RDWR 中运行良好。但是,O_RDONLY 的实际值为 0,因此 & 运算符将为每个值返回 false。不幸的是,删除否定将导致每个 perms 值 4 跳过 if 块的不良行为。我怎样才能在这里实现我的目标?

【问题讨论】:

  • 使用((flags&O_ACCMODE)==O_RDONLY)等
  • 虽然flags 参数可以包含标志,但打开模式本身是非标志。
  • @JoachimPileborg flags 这里等于开放系统参数int flags。

标签: c unix system-calls bitwise-operators


【解决方案1】:

最初,open 的第二个参数被称为 mode,并被记录为 0、1 或 2。Later on,参数被重命名为 oflag ,并且它现在可以包含除了访问模式之外的标志。不过,模式的可能值保持不变,并为它们提供了符号名称,但要注意,与标志不同,只能使用 O_RDONLY、O_WRONLY 和 O_RDWR 之一。 POSIX standard 包含以下定义:

用于文件访问模式的掩码如下:
O_ACCMODE 文件访问模式的掩码。

所以可以使用((flags&O_ACCMODE) == O_RDONLY)等代码

【讨论】:

  • 所以如果((flags&O_ACCMODE) == O_RDONLY 评估为真,((flags&O_ACCMODE) == O_RDWR 无法评估为真,对吗?我遇到了模式评估为 644 的实例,其中当前用户是所有者,但 strace 显示文件正在使用 O_RDONLY 打开。我想我只是添加额外的逻辑,这样当 perms 的值为 6 时,它也会检查 RDONLY 和 WRONLY 但这似乎不仅懒惰而且可能很麻烦。
  • 是的,如果 (flags&O_ACCMODE) == O_RDONLY,那么 (flags&O_ACCMODE) 将不会 == O_RDWR。如果您需要多次比较这些,则可能值得将访问模式转换为一个值,您可以在其中测试表示读取或写入访问的单个位。 UNIX 内核就是这样做的——很久以前,它会接受 mode 参数(大概是 0、1 或 2),然后简单地将其加 1,然后查看结果的低 2 位。
【解决方案2】:

使用

int open_mode = (flags & O_ACCMODE);

然后您可以使用以下检查:

(open_mode == O_RDONLY)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    相关资源
    最近更新 更多