【问题标题】:What is the written-out word for O_EXCLO_EXCL 写出来的字是什么
【发布时间】:2018-07-01 11:24:49
【问题描述】:

我正在为open(3) 中列出的不同文件标志写一个安全的enum class,但我发现我找不到O_EXCL 的写出词。

enum class Flags {
    readOnly, // O_RDONLY
    truncate, // O_TRUNC
    ?         // O_EXCL
};

我想到了两种可能的含义:

  • OPEN_EXCLUSIVE
  • OPEN_EXISTS_CLOSE

但我找不到任何关于预期含义的资源。

【问题讨论】:

  • 我是OPEN_EXCLUSIVE
  • 你能提供一个你找到这个网站的参考吗?
  • 好吧,reference 就在那里。这是对我所说的行为的解释问题。
  • 您应该明确分配枚举的值(例如readOnly = O_RDONLY,)。您不希望允许意外重新排序或删除来更改任何枚举值的含义。

标签: c++ linux c++11 posix system-calls


【解决方案1】:

O_EXCL的真正含义是“error if create and file exists”但是名字来源于“EXCLusive”,有点意思虽然具有误导性,并导致许多人误解该标志。

使用O_EXCL 打开文件将不会像某些人错误地认为的那样授予您对它的独占访问权限。一个进程用O_EXCL打开的文件,可以同时被其他进程打开读写,没问题,所以访问显然不是独占的。

此标志存在的主要原因是“锁定文件”。早在文件咨询锁定(使用fcntl)和可以在进程之间共享的信号量/互斥体之前很久,就需要一种简单的方法来确保跨多个进程对某些系统资源进行原子访问。实现锁定文件的方法。第一个想要访问资源的进程将在/var/lock 中创建一个锁定文件,以声明对该资源的所有权,并在完成后再次将其删除。其他进程将监视该目录,从而知道资源是否可用。

问题:如果两个进程查看目录并且都看到某个文件不存在,因此资源可用,现在都尝试创建这个文件,如何确保只有一个会成功?这就是O_EXCL 发挥作用的地方。如果他们都尝试创建设置了O_EXCL 的文件,则此操作只会对其中一个成功,而这就是现在拥有资源锁的进程。

所以O_EXCL 不是为了获得对文件的独占访问权限,而是为了制作独占访问文件,其目的是规范对某种资源的独占访问。

O_EXCL 今天的第二个最重要的用途是文件访问安全。考虑这种情况:一个根进程想要创建一个文件,并用只有根用户才能看到的内容填充它,而不是普通用户,但是它正在一个普通用户确实有写权限的目录中创建它(例如/tmp)。如果进程会按如下方式创建文件

open("/tmp/root-only", O_CREAT | O_WRONLY, 0600);

并且文件不存在,它是由root创建,拥有,只有root有读写权限,所以普通用户看不到它的内容。任务完成。

但是如果一个普通用户之前已经创建了/tmp/root-only呢?然后这个文件归那个用户所有,这个用户可以读取它,上面的 open 调用只会打开现有文件。即使根进程在打开文件后直接更改了所有权和文件权限,这对之前已经打开过文件的进程(例如tail -f)没有影响。

所以实现那个case的正确方法其实是:

unlink("/tmp/root-only"); // best effort, may not even exist
open("/tmp/root-only", O_CREAT | O_EXCL | O_WRONLY, 0600);

如果open 确实成功了,进程可以依赖该文件归进程所有者所有,并且没有其他人有权读取/写入它。

【讨论】:

    【解决方案2】:

    Exclusive 在这里是一个正确的词,因为该标志是 O_CREAT 标志独有的,并且如果文件存在则使函数失败。 (如果未设置 O_CREAT 标志,则行为未定义。)

    【讨论】:

      猜你喜欢
      • 2021-11-25
      • 2012-08-25
      • 2022-11-29
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      • 2015-01-26
      • 2019-09-25
      • 1970-01-01
      相关资源
      最近更新 更多