open(name,O_CREAT | O_DIRECTORY,mode)的预期行为是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了open(name,O_CREAT | O_DIRECTORY,mode)的预期行为是什么?相关的知识,希望对你有一定的参考价值。
尽管仔细阅读了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)的手册页,但我找不到任何澄清。
说两个标志的使用是否未指定是否正确?如果是这样,最常见的行为是什么?
open(name, O_CREAT|O_DIRECTORY, mode)
在任何符合POSIX标准的操作系统上都相当于mkdir
吗?
netbsd本身在vn_open中包含以下内容:
if ((fmode & (O_CREAT | O_DIRECTORY)) == (O_CREAT | O_DIRECTORY))
return EINVAL;
所以与这两个人的任何组合都会被直接拒绝。
在Linux中它有点多毛,但任何琐碎的测试都会告诉你目录也没有创建,但你最终可能会得到一个文件
对于踢,我也检查了freebsd,它最终从未以O_DIRECTORY创建任何东西
如果你正在寻找的是一个让你回到fd的mkdir,我恐怕没有那种东西。另一方面,你应该能够安全地打开O_DIRECTORY你所做的任何事情。
我认为你误解了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
提供的路径名(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)
。
到目前为止的答案都不正确。实现可以通过O_CREAT|O_DIRECTORY|O_WRONLY
或O_CREAT|O_DIRECTORY|O_RDWR
自由支持目录创建,但它们不是必需的。这在2014年得到澄清,正如你在bug tracker of the Austin group中看到的那样:
open("/path/to/existing/directory", O_CREAT)
应该与EISDIR
失败,但应该允许实现支持通过open("/path/to/directory", O_CREAT|O_DIRECTORY)
创建和打开目录作为扩展
具有以下基本原理:
当在现有目录上使用
open()
(或O_CREAT|O_RDONLY
)调用O_CREAT|O_SEARCH
时,该标准未指定行为。此外,某些系统希望允许使用open()
函数创建目录。这应该是允许的,但不是必需的扩展。
你从标准的current version引用的措辞
如果设置了O_CREAT和O_DIRECTORY且请求的访问模式既不是O_WRONLY也不是O_RDWR,则结果未指定。
正是允许它做出的改变之一。
正如Rich Felkner所描述的那样,允许这样做的原因之一是,它将提供一个用于原子地创建和打开目录的接口。
但是,我不知道,如果任何POSIX实现确实提供了通过open
创建目录。
以上是关于open(name,O_CREAT | O_DIRECTORY,mode)的预期行为是什么?的主要内容,如果未能解决你的问题,请参考以下文章