open(name, O_CREAT|O_DIRECTORY, mode) 的预期行为是什么?
What's the expected behavior of open(name, O_CREAT|O_DIRECTORY, mode)?
尽管仔细阅读了 the related standard documentation,但我无法理解当使用包括 O_CREAT|O_DIRECTORY
.
标准规定
If O_CREAT and O_DIRECTORY are set and the requested access mode is neither O_WRONLY nor O_RDWR, the result is unspecified.
但是它没有指定系统的行为,既没有 (O_CREAT|O_DIRECTORY|O_WRONLY)
也没有 (O_CREAT|O_DIRECTORY|O_RDWR)
。事实上(据我所知)EISDIR
上的行为仅适用于 existing 目录。
在与O_CREATE相关的部分中,标准规定,当命名文件不存在时,
if O_DIRECTORY is not set the file shall be created as a regular file; [...]
但它同样没有指定如果也设置了 O_DIRECTORY
会发生什么。
我查看了 NetBSD (which notoriously cares a lot about POSIX compliance) and Linux 的手册页(这是一个广泛使用的系统,尽管实际上不是 POSIX 系统)但我找不到任何说明。
说这两个标志的使用未指定是否正确?
如果是这样,最常见的行为是什么?
在任何符合 POSIX 的 OS 上,open(name, O_CREAT|O_DIRECTORY, mode)
是否等同于 mkdir
?
netbsd本身在vn_open中包含以下内容:
if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY))
return EINVAL;
所以与这 2 个的任何组合都会被直接拒绝。
在 linux 中有点多毛,但是任何简单的测试都会告诉你目录也没有创建,但你可以得到一个文件
为了好玩,我还检查了 freebsd,它从一开始就不会用 O_DIRECTORY 创建任何东西
如果您正在寻找的是一个 mkdir,它可以返回 fd,恐怕没有这样的东西。另一方面,您应该能够使用 O_DIRECTORY 任何您 mkdir 编辑的内容安全地打开。
我认为您误解了 O_DIRECTORY
的含义。不是创建一个目录,而是保证open(2)
打开的"file"是一个目录。
O_DIRECTORY
If path resolves to a non-directory file, fail and set errno to [ENOTDIR].
这正是 POSIX 记录它的方式(上面引用)。
However it does not specify the behavior of the system with neither (O_CREAT|O_DIRECTORY|O_WRONLY) nor (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
的存在是为了保证文件被打开
是一个目录 - 它不会影响任何其他内容。
Is it correct to say that the use of both flags is unspecified? And if so, what's the most common behavior?
表示未指定特定组合 O_CREAT | O_DIRECTORY
的行为;并不意味着使用单独的标志
(有或没有其他标志)未指定。
Is open(name, O_CREAT|O_DIRECTORY, mode) equivalent to mkdir on any POSIX compliant OS?
完全没有。这就是为什么它被保留为 未指定 的原因。在 Linux、it's definitely not - 创建了一个常规文件:
When both O_CREAT and O_DIRECTORY are specified in flags and the file
specified by pathname does not exist, open() will create a regular
file (i.e., O_DIRECTORY is ignored).
要创建目录,您需要使用 mkdir(2)
。
到目前为止的答案都不正确。实现可以通过 O_CREAT|O_DIRECTORY|O_WRONLY
或 O_CREAT|O_DIRECTORY|O_RDWR
免费支持目录创建,但它们不是必需的。
正如您在 bug tracker of the Austin group:
中看到的那样,这在 2014 年得到了澄清
open("/path/to/existing/directory", O_CREAT)
should fail with EISDIR
, but implementations should be allowed to support creating and opening a directory via open("/path/to/directory", O_CREAT|O_DIRECTORY)
as an extension
基于以下理由:
The standard does not specify the behavior when open()
is called with O_CREAT|O_RDONLY
(or O_CREAT|O_SEARCH
) on an existing directory. Additionally, some systems want to allow creation of directories using the open()
function. This should be an allowed, but not required, extension.
您从标准current version中引用的措辞
If O_CREAT and O_DIRECTORY are set and the requested access mode is neither O_WRONLY nor O_RDWR, the result is unspecified.
恰恰是允许它进行的更改之一。
如 Rich Felkner 所述,允许这样做的原因之一是,它将提供一个用于自动创建和打开目录的接口。
但是,我不知道是否有任何 POSIX 实现确实通过 open
.
提供目录创建
尽管仔细阅读了 the related standard documentation,但我无法理解当使用包括 O_CREAT|O_DIRECTORY
.
标准规定
If O_CREAT and O_DIRECTORY are set and the requested access mode is neither O_WRONLY nor O_RDWR, the result is unspecified.
但是它没有指定系统的行为,既没有 (O_CREAT|O_DIRECTORY|O_WRONLY)
也没有 (O_CREAT|O_DIRECTORY|O_RDWR)
。事实上(据我所知)EISDIR
上的行为仅适用于 existing 目录。
在与O_CREATE相关的部分中,标准规定,当命名文件不存在时,
if O_DIRECTORY is not set the file shall be created as a regular file; [...]
但它同样没有指定如果也设置了 O_DIRECTORY
会发生什么。
我查看了 NetBSD (which notoriously cares a lot about POSIX compliance) and Linux 的手册页(这是一个广泛使用的系统,尽管实际上不是 POSIX 系统)但我找不到任何说明。
说这两个标志的使用未指定是否正确? 如果是这样,最常见的行为是什么?
在任何符合 POSIX 的 OS 上,open(name, O_CREAT|O_DIRECTORY, mode)
是否等同于 mkdir
?
netbsd本身在vn_open中包含以下内容:
if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY))
return EINVAL;
所以与这 2 个的任何组合都会被直接拒绝。
在 linux 中有点多毛,但是任何简单的测试都会告诉你目录也没有创建,但你可以得到一个文件
为了好玩,我还检查了 freebsd,它从一开始就不会用 O_DIRECTORY 创建任何东西
如果您正在寻找的是一个 mkdir,它可以返回 fd,恐怕没有这样的东西。另一方面,您应该能够使用 O_DIRECTORY 任何您 mkdir 编辑的内容安全地打开。
我认为您误解了 O_DIRECTORY
的含义。不是创建一个目录,而是保证open(2)
打开的"file"是一个目录。
O_DIRECTORY
If path resolves to a non-directory file, fail and set errno to [ENOTDIR].
这正是 POSIX 记录它的方式(上面引用)。
However it does not specify the behavior of the system with neither (O_CREAT|O_DIRECTORY|O_WRONLY) nor (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
的存在是为了保证文件被打开
是一个目录 - 它不会影响任何其他内容。
Is it correct to say that the use of both flags is unspecified? And if so, what's the most common behavior?
表示未指定特定组合 O_CREAT | O_DIRECTORY
的行为;并不意味着使用单独的标志
(有或没有其他标志)未指定。
Is open(name, O_CREAT|O_DIRECTORY, mode) equivalent to mkdir on any POSIX compliant OS?
完全没有。这就是为什么它被保留为 未指定 的原因。在 Linux、it's definitely not - 创建了一个常规文件:
When both O_CREAT and O_DIRECTORY are specified in flags and the file specified by pathname does not exist, open() will create a regular file (i.e., O_DIRECTORY is ignored).
要创建目录,您需要使用 mkdir(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)
should fail withEISDIR
, but implementations should be allowed to support creating and opening a directory viaopen("/path/to/directory", O_CREAT|O_DIRECTORY)
as an extension
基于以下理由:
The standard does not specify the behavior when
open()
is called withO_CREAT|O_RDONLY
(orO_CREAT|O_SEARCH
) on an existing directory. Additionally, some systems want to allow creation of directories using theopen()
function. This should be an allowed, but not required, extension.
您从标准current version中引用的措辞
If O_CREAT and O_DIRECTORY are set and the requested access mode is neither O_WRONLY nor O_RDWR, the result is unspecified.
恰恰是允许它进行的更改之一。
如 Rich Felkner 所述,允许这样做的原因之一是,它将提供一个用于自动创建和打开目录的接口。
但是,我不知道是否有任何 POSIX 实现确实通过 open
.