Reputation: 35156
On unix like systems, attempting to call the write
function on a file descriptor can sometimes result in the error:
[EBADF] fildes is not a valid file descriptor open for writing.
This is typically when the file descriptor has been opened with open
and a combination of flags that does not include O_WRONLY
or O_RDWR
.
(see man 2 open, man 2 write for more info)
So, the question:
In what circumstances is it ever valid to call open
with any of O_APPEND
, O_TRUNC
, O_CREAT
, without also passing one of the write flags?
This is specifically because of a recent issue in which I encountered that passing only the O_APPEND
flag would successfully open the file, but calling write
on the fd would result in EBADF
because I failed to pass something other than O_RDONLY
along to the open
call.
I would expect the open
should fail with some error if an invalid combination of flags (eg. O_APPEND
without any write flag), but it does not. Is there some reason for this, or is it just an artifact of the historical posix standard?
Is there, ever, a situation where O_APPEND
+ O_RDONLY
is a valid combination?
Upvotes: 2
Views: 578
Reputation: 4752
I can't think of any situations where passing O_APPEND
along with O_RDONLY
would have a different effect than just passing O_RDONLY
. SUSv4 seems to imply that it should be allowed at least.
For O_TRUNC
, SUSv4 doesn't specify the behavior when passing O_RDONLY
:
The result of using
O_TRUNC
without eitherO_RDWR
orO_WRONLY
is undefined.
fcntl() can change status flags on the descriptor after it's created, and so might seem like a way in which e.g. O_APPEND
could matter when opening a file O_RDONLY
. However,
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
On Linux, fcntl(2)
can change the O_APPEND
, O_ASYNC
, O_DIRECT
, O_NOATIME
, and O_NONBLOCK
flags, but none of those would make a difference re. this discussion.
Slightly contrived, but I guess passing O_RDONLY | O_APPEND
might affect what flags you get back when you do fcntl(fd, F_GETFL, ...)
. I haven't actually confirmed that though.
As for why things were designed this way, I don't know.
Upvotes: 2
Reputation: 512
It depends on what you mean by "valid".
AFAICT, POSIX doesn't specifically mention this combination of flags. but it does say:
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
and then
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.
I would conclude that a lone O_APPEND would fall under "unspecified" behavior according to POSIX (i.e., don't do that).
See here for more info: http://pubs.opengroup.org/onlinepubs/9699919799/
Upvotes: 2