尽管仔细阅读the related standard documentation,但在使用包含open
的标志调用O_CREAT|O_DIRECTORY
系统调用时,我无法理解POSIX兼容系统中的预期行为。
标准指定
如果O_CREAT和O_DIRECTORY设置为且,请求的访问模式既不是O_WRONLY也不是O_RDWR,则结果未指定。
但是,它没有指定系统的行为,既没有(O_CREAT|O_DIRECTORY|O_WRONLY)
也没有(O_CREAT|O_DIRECTORY|O_RDWR)
。确实(据我所知)EISDIR
上的行为仅适用于现有的目录。
在与O_CREATE相关的部分中,标准指定当命名文件不存在时,
如果未设置O_DIRECTORY ,则应将文件创建为常规文件; [...]
但同样没有说明如果设置O_DIRECTORY
会发生什么。
我看过NetBSD(非常关心POSIX合规性)和Linux(这是一个广泛使用的系统,尽管实际上并不是POSIX)的手册页,但我找不到任何澄清。
说两个标志的使用是否未指定是否正确? 如果是这样,最常见的行为是什么?
在任何符合POSIX标准的操作系统上open(name, O_CREAT|O_DIRECTORY, mode)
等同于mkdir
吗?
答案 0 :(得分:4)
我认为你误解了O_DIRECTORY
的含义。它不是创建目录,而是确保open(2)
打开的“文件”是一个目录。
O_DIRECTORY
如果path解析为非目录文件,则失败并将errno设置为[ENOTDIR]。
这正是POSIX记录它的方式(上面引用过)。
但是它既没有指定系统的行为(O_CREAT | O_DIRECTORY | O_WRONLY)也没有指定(O_CREAT | O_DIRECTORY | O_RDWR)
O_CREAT|O_DIRECTORY|O_WRONLY
和O_CREAT|O_DIRECTORY|O_RDWR
的行为相当于O_CREAT|O_WRONLY
和O_CREAT|O_RDWR
分别提供 pathname (open(2)的第一个参数)是一个目录。 O_DIRECTORY
的存在是为了确保文件被打开
是一个目录 - 它不会影响任何其他内容。
说两个标志的使用是否未指定是否正确?如果是这样,最常见的行为是什么?
这意味着未指定特定组合 O_CREAT | O_DIRECTORY
的行为;并不意味着使用单个标志
(有或没有其他标志)未指定。
在任何符合POSIX标准的操作系统上,是否打开(名称,O_CREAT | O_DIRECTORY,模式)等同于mkdir?
完全没有。这就是为什么它留下未指定。在Linux上,it's definitely not - 创建了一个常规文件:
在flags和文件中指定O_CREAT和O_DIRECTORY时 由pathname指定不存在,open()将创建一个常规 文件(即忽略O_DIRECTORY)。
要创建目录,请使用mkdir(2)
。
答案 1 :(得分:2)
netbsd本身在vn_open中包含以下内容:
if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY))
return EINVAL;
所以与这两个人的任何组合都会被直接拒绝。
在Linux中它有点毛茸茸,但是任何微不足道的测试都会告诉你目录也没有创建,但是你最终可以得到一个文件对于踢,我也检查了freebsd,它从来没有最终用O_DIRECTORY创建任何东西
如果您正在寻找的是mkdir,它会让您回到fd,我担心没有任何类似的东西。另一方面,你应该能够安全地使用O_DIRECTORY打开任何你想要的东西。
答案 2 :(得分:2)
到目前为止的答案都不正确。实现可以通过O_CREAT|O_DIRECTORY|O_WRONLY
或O_CREAT|O_DIRECTORY|O_RDWR
自由支持目录创建,但不是必需的。
正如您在bug tracker of the Austin group:
open("/path/to/existing/directory", O_CREAT)
应该以{{1}}失败,但应允许实施支持通过EISDIR
作为扩展名创建和打开目录
具有以下基本原理:
标准未指定在现有目录上使用
open("/path/to/directory", O_CREAT|O_DIRECTORY)
(或open()
)调用O_CREAT|O_RDONLY
时的行为。此外,某些系统希望允许使用O_CREAT|O_SEARCH
函数创建目录。这应该是允许的,但不是必需的扩展名。
您从标准current version中引用的措辞
如果设置了O_CREAT和O_DIRECTORY且请求的访问模式既不是O_WRONLY也不是O_RDWR,则结果未指定。
正是允许它做出的改变之一。
如Rich Felkner所述,允许这样做的原因之一是,它将提供一个原子创建和打开目录的接口。
但是,我不知道,如果有任何POSIX实现确实通过open()
提供了目录创建。