open(name,O_CREAT | O_DIRECTORY,mode)的预期行为是什么?

尽pipe仔细阅读了相关的标准文档 ,但我无法理解当使用包括O_CREAT|O_DIRECTORY标志调用open系统调用时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, 则应该将文件创build为常规文件; […]

但是它也没有指定如果O_DIRECTORY被设置也会发生什么。

我已经看过NetBSD (它非常关心POSIX合规性)和Linux (这是一个广泛使用的系统,尽pipe实际上并不是POSIX系统)的手册页,但我找不到任何解释。

说这两个标志的用法是不确定的是正确的吗? 如果是这样,最常见的行为是什么?

在任何POSIX兼容的操作系统上是否open(name, O_CREAT|O_DIRECTORY, mode)等同于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
如果路径解析为非目录文件,则失败并将errno设置为[ENOTDIR]。

这正是POSIX如何记录它(上面引用的)。

但是,它既没有(O_CREAT | O_DIRECTORY | O_WRONLY)也没有(O_CREAT | O_DIRECTORY | O_RDWR)指定系统的行为

O_CREAT|O_DIRECTORY|O_WRONLYO_CREAT|O_DIRECTORY|O_RDWR的行为分别等同于O_CREAT|O_WRONLYO_CREAT|O_RDWR前提是路径名 (open(2)的第一个参数)是一个目录。 O_DIRECTORY的存在是为了确保打开的文件是一个目录 – 它不会影响其他任何东西。

说这两个标志的用法是不确定的是正确的吗? 如果是这样,最常见的行为是什么?

这意味着特定组合 O_CREAT | O_DIRECTORY的行为 没有指定O_CREAT | O_DIRECTORY ; 并不意味着使用单个标志(有或没有其他标志)是未指定的。

在任何POSIX兼容的操作系统上是否打开(名称,O_CREAT | O_DIRECTORY,模式)等同于mkdir?

一点也不。 这就是为什么它是未指定的 。 在Linux上, 绝对不是 – 创建一个常规文件:

如果在标志中指定了O_CREAT和O_DIRECTORY,并且由pathname指定的文件不存在,则open()将创建一个常规文件(即忽略O_DIRECTORY)。

要创建一个目录,你需要使用mkdir(2)