Doug
Doug

Reputation: 35156

Is there any valid situation where you would use O_APPEND and O_RDONLY?

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

Answers (2)

Ulfalizer
Ulfalizer

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 either O_RDWR or O_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

davlet
davlet

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

Related Questions