linuxposixfcntl

Is it required to use O_TRUNC and O_APPEND together?


I was going through the book The Linux Programming Interface. On page 73 in Chapter 4, it is written:

fd = open("w.log", O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, S_IRUSR | S_IWUSR);

I read that O_TRUC flag is used to truncate the file length to zero that destroys any existing data in the file.

O_APPEND flag is used to append data to the end of the file.

The kernel records a file offset, sometimes also called the read-write offset or pointer. This is the location in the file at which the next read() or write() will commence.

I am confused that if the file is truncated and the kernel does the subsequent writing at the end of the file, why is the append flag is needed to explicitly tell to append at the end of the file?

Without the append flag (if the file is truncated), the kernel writes at the end of the file for the subsequent write() function call.


Solution

  • O_APPEND flag is used to append data to the end of the file.

    That's true, but incomplete enough to be potentially misleading. And I suspect that you are in fact confused in that regard.

    The kernel records a file offset, sometimes also called the read-write offset or pointer. This is the location in the file at which the next read() or write() will commence.

    That's also incomplete. There is a file offset associated with at least each seekable file. That is the position where the next read() will commence. It is where the next write() will commence if the file is not open in append mode, but in append mode every write happens at the end of the file, as if it were repositioned with lseek(fd, 0, SEEK_END) before each one. In that case, then, the current file offset might not be the position where the next write() will commence.

    I am confused that if the file is truncated and the the kernel does the subsequent writing at the end of the file why the append flag is needed to explicitly tell to append at the end of the file ?

    It is not needed to cause the first write (by any process) after truncation to occur at the end of the file because immediately after the file has been truncated there isn't any other position.

    With out the append flag (if the file is truncated), the kernel writes at the end of the file for the subsequent write() function call.

    It is not needed for subsequent writes either, as long as the file is not repositioned or externally modified. Otherwise, the location of the next write depends on whether the file is open in append mode or not.

    In practice, it is not necessarily the case that every combination of flags is useful, but the combination of O_TRUNC and O_APPEND has observably different effect than does either flag without the other, and the combination is useful in certain situations.