【问题标题】:Is there any valid situation where you would use O_APPEND and O_RDONLY?是否存在使用 O_APPEND 和 O_RDONLY 的有效情况?
【发布时间】:2015-03-24 00:47:53
【问题描述】:

在类 unix 系统上,尝试在文件描述符上调用 write 函数有时会导致错误:

[EBADF]  fildes is not a valid file descriptor open for writing.

这通常是在使用open 和不包括O_WRONLYO_RDWR 的标志组合打开文件描述符时。

(见 man 2 open,man 2 write 了解更多信息)

那么问题来了:

在什么情况下有效使用O_APPENDO_TRUNCO_CREAT 中的任何一个调用open,而不传递其中一个写入标志?

这特别是因为我最近遇到的一个问题,即仅传递 O_APPEND 标志将成功打开文件,但在 fd 上调用 write 将导致 EBADF 因为我未能传递其他内容比O_RDONLYopen 通话。

如果标志的组合无效(例如,O_APPEND 没有任何写入标志),我希望open 应该失败并出现一些错误,但事实并非如此。这是有什么原因,还是只是历史 posix 标准的产物?

是否存在O_APPEND + O_RDONLY 是有效组合的情况?

【问题讨论】:

  • 因为它没有。为什么做出最初的决定并不重要,在这里推测它是无关紧要的,只是讨论。为什么做出设计决定现在可能会产生什么不同?事实是它在编译期间不会失败,因此您需要确保指定有效的标志组合。
  • @KenWhite: s/valid/useful/
  • @KenWhite 它实际上非常相关,具体参见github.com/rust-lang/rust/issues/23626
  • 您的问题是问为什么标准 C 库 open() 不验证它收到的标志组合。没有提到生锈的设计考虑。标签(或文本)也不会生锈。正如它(写得很好)一样,它被表述为对当时做出历史决定的原因的讨论。
  • @KenWhite 老实说,我不确定你想从我这里得到什么。如果我的问题在措辞方面不符合 SO 问题的严格标准,我很抱歉。但是,我认为这是一个简单的是/否答案,我只需要一个明确的答案:是否存在 O_APPEND + O_RDONLY 是有效组合的情况?我很高兴忽略这个的整个历史方面,它真的不相关,除了它可能会通知某些情况,在这些情况下上述内容是有效的。

标签: c io system-calls


【解决方案1】:

这取决于您所说的“有效”。

AFAICT,POSIX 没有特别提到这种标志组合。但它确实说:

应用程序应指定前五个值之一(文件 访问模式)在oflag的值下面:

  • O_EXEC
  • O_RDONLY
  • O_RDWR
  • O_SEARCH
  • O_WRONLY

然后

并非所有标志组合都有意义。例如,使用 O_SEARCH | O_CREAT 将成功打开预先存在的目录进行搜索,但如果没有该名称的现有文件,则未指定是否创建常规文件。

我会得出结论,根据 POSIX,单独的 O_APPEND 将属于“未指定”行为(即不要这样做)。

查看这里了解更多信息:http://pubs.opengroup.org/onlinepubs/9699919799/

【解决方案2】:

我想不出在任何情况下传递O_APPENDO_RDONLY 会产生与传递O_RDONLY 不同的效果。 SUSv4 seems to imply 至少应该允许。

对于O_TRUNC,SUSv4没有指定传递O_RDONLY时的行为:

在没有O_RDWRO_WRONLY 的情况下使用O_TRUNC 的结果是未定义的。

fcntl() 可以在描述符创建后更改状态标志,因此可能看起来像是一种方式,例如O_APPEND 在打开文件 O_RDONLY 时可能很重要。然而,

在 arg 中设置的与文件访问模式和文件创建标志对应的位(如 中定义)应被忽略。如果应用程序更改了 arg 中除此处提及的以外的任何位,则结果未指定

在 Linux 上,fcntl(2) 可以更改 O_APPENDO_ASYNCO_DIRECTO_NOATIMEO_NONBLOCK 标志,但这些都不会改变。这个讨论。

有点做作,但我想传递O_RDONLY | O_APPEND 可能会影响你在传递fcntl(fd, F_GETFL, ...) 时返回的标志。不过,我实际上还没有证实这一点。

至于为什么要这样设计,我不知道。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 2015-06-02
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多