是否有任何有效的情况可以使用 O_APPEND 和 O_RDONLY?
Is there any valid situation where you would use O_APPEND and O_RDONLY?
在类似 unix 的系统上,尝试在文件描述符上调用 write
函数有时会导致错误:
[EBADF] fildes is not a valid file descriptor open for writing.
这通常是在使用 open
和不包括 O_WRONLY
或 O_RDWR
.
的标志组合打开文件描述符时出现的
(查看 man 2 open,man 2 write 获取更多信息)
所以,问题:
在什么情况下用O_APPEND
、O_TRUNC
、O_CREAT
调用open
是有效的也没有传递写入标志之一?
这是因为我最近遇到一个问题,只传递 O_APPEND
标志可以成功打开文件,但是在 fd 上调用 write
会导致 EBADF
因为我未能将 O_RDONLY
以外的内容传递给 open
调用。
如果标志组合无效(例如 O_APPEND
没有任何写入标志),我希望 open
会失败并出现一些错误,但事实并非如此。这有什么原因吗,或者它只是历史 posix 标准的产物?
是否存在 O_APPEND
+ O_RDONLY
是有效组合的情况?
这取决于你"valid"的意思。
AFAICT,POSIX 没有具体提及这种标志组合。但它确实说:
Applications shall specify exactly one of the first five values (file
access modes) below in the value of oflag:
- O_EXEC
- O_RDONLY
- O_RDWR
- O_SEARCH
- O_WRONLY
然后
Not all combinations of flags make sense. For example, using O_SEARCH | O_CREAT will successfully open a pre-existing directory for searching, but if there is no existing file by that name, then it is unspecified whether a regular file will be created.
我会得出结论,根据 POSIX,一个孤独的 O_APPEND 会属于 "unspecified" 行为(即,不要那样做)。
我想不出在任何情况下传递 O_APPEND
和 O_RDONLY
会产生与传递 O_RDONLY
不同的效果。 SUSv4 seems to imply 至少应该允许。
对于 O_TRUNC
,SUSv4 未指定传递 O_RDONLY
:
时的行为
The result of using O_TRUNC
without either O_RDWR
or O_WRONLY
is undefined.
fcntl() 可以在描述符创建后更改其状态标志,因此看起来像是一种方式,例如O_APPEND
在打开文件时可能很重要 O_RDONLY
。然而,
Bits corresponding to the file access mode and the file creation flags, as defined in <fcntl.h>, that are set in arg shall be ignored. If any bits in arg other than those mentioned here are changed by the application, the result is unspecified
在Linux、fcntl(2)
上可以改变O_APPEND
、O_ASYNC
、O_DIRECT
、O_NOATIME
和O_NONBLOCK
标志,但其中 none 会有所不同。这个讨论。
有点做作,但我想传递 O_RDONLY | O_APPEND
可能会影响你在传递 fcntl(fd, F_GETFL, ...)
时返回的标志。不过我还没有真正证实这一点。
至于为什么要这样设计,我也不知道。
在类似 unix 的系统上,尝试在文件描述符上调用 write
函数有时会导致错误:
[EBADF] fildes is not a valid file descriptor open for writing.
这通常是在使用 open
和不包括 O_WRONLY
或 O_RDWR
.
(查看 man 2 open,man 2 write 获取更多信息)
所以,问题:
在什么情况下用O_APPEND
、O_TRUNC
、O_CREAT
调用open
是有效的也没有传递写入标志之一?
这是因为我最近遇到一个问题,只传递 O_APPEND
标志可以成功打开文件,但是在 fd 上调用 write
会导致 EBADF
因为我未能将 O_RDONLY
以外的内容传递给 open
调用。
如果标志组合无效(例如 O_APPEND
没有任何写入标志),我希望 open
会失败并出现一些错误,但事实并非如此。这有什么原因吗,或者它只是历史 posix 标准的产物?
是否存在 O_APPEND
+ O_RDONLY
是有效组合的情况?
这取决于你"valid"的意思。
AFAICT,POSIX 没有具体提及这种标志组合。但它确实说:
Applications shall specify exactly one of the first five values (file access modes) below in the value of oflag:
- O_EXEC
- O_RDONLY
- O_RDWR
- O_SEARCH
- O_WRONLY
然后
Not all combinations of flags make sense. For example, using O_SEARCH | O_CREAT will successfully open a pre-existing directory for searching, but if there is no existing file by that name, then it is unspecified whether a regular file will be created.
我会得出结论,根据 POSIX,一个孤独的 O_APPEND 会属于 "unspecified" 行为(即,不要那样做)。
我想不出在任何情况下传递 O_APPEND
和 O_RDONLY
会产生与传递 O_RDONLY
不同的效果。 SUSv4 seems to imply 至少应该允许。
对于 O_TRUNC
,SUSv4 未指定传递 O_RDONLY
:
The result of using
O_TRUNC
without eitherO_RDWR
orO_WRONLY
is undefined.
fcntl() 可以在描述符创建后更改其状态标志,因此看起来像是一种方式,例如O_APPEND
在打开文件时可能很重要 O_RDONLY
。然而,
Bits corresponding to the file access mode and the file creation flags, as defined in <fcntl.h>, that are set in arg shall be ignored. If any bits in arg other than those mentioned here are changed by the application, the result is unspecified
在Linux、fcntl(2)
上可以改变O_APPEND
、O_ASYNC
、O_DIRECT
、O_NOATIME
和O_NONBLOCK
标志,但其中 none 会有所不同。这个讨论。
有点做作,但我想传递 O_RDONLY | O_APPEND
可能会影响你在传递 fcntl(fd, F_GETFL, ...)
时返回的标志。不过我还没有真正证实这一点。
至于为什么要这样设计,我也不知道。