尽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_WRONLY
和O_CREAT|O_DIRECTORY|O_RDWR
的行为分别等同于O_CREAT|O_WRONLY
和O_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)
。