#16506: write() doesn't properly update file offset if opened with O_APPEND
--------------------------+-----------------------------
Reporter: mike.dld | Owner: nobody
Type: bug | Status: new
Priority: normal | Milestone: Unscheduled
Component: System/POSIX | Version: R1/Development
Keywords: | Blocked By:
Blocking: | Platform: All
--------------------------+-----------------------------
When opening file (via `open()`) in append mode (with `O_APPEND` flag),
subsequent write operations (via `write()`) update current file offset
(retrieved via `lseek()`) as if they were issued on an empty file, i.e.
current file offset does not take pre-existing file size into account.
Note that data being written does it fact end up at the end of the file.
Environment:
{{{
~> uname -a
Haiku shredder 1 hrev54538 Sep 1 2020 06:01:43 x86_64 x86_64 Haiku
~> df -a
Mount Type Total Free Flags Device
----------------- --------- --------- --------- -------
------------------------
/ rootfs 0 0 ------W
/dev devfs 0 0 ------W
/boot bfs 40.0 GiB 33.7 GiB QAM-P-W
/dev/disk/ata/0/master/raw
/boot/system packagefs 4.0 KiB 4.0 KiB QAM-P--
/boot/home/config packagefs 4.0 KiB 4.0 KiB QAM-P--
}}}
Repro code:
{{{#!c
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char** argv)
{
const char* const data = argc == 2 ? argv[1] : "?";
const int fd = open("a.dat", O_RDWR | O_APPEND | O_CREAT, 0644);
if (fd != -1) {
write(fd, data, strlen(data));
printf("pos1: %d\n", (int)lseek(fd, 0, SEEK_CUR));
write(fd, "\n", 1);
printf("pos2: %d\n", (int)lseek(fd, 0, SEEK_CUR));
close(fd);
}
}
}}}
Expected result:
{{{
~> ./a.out
pos1: 1
pos2: 2
~> ./a.out foo
pos1: 5
pos2: 6
~> ./a.out barbaz
pos1: 12
pos2: 13
~> cat a.dat
?
foo
barbaz
}}}
Actual result:
{{{
~> ./a.out
pos1: 1
pos2: 2
~> ./a.out foo
pos1: 3
pos2: 4
~> ./a.out barbaz
pos1: 6
pos2: 7
~> cat a.dat
?
foo
barbaz
}}}
Related docs:
1. https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
> `O_APPEND` \\
> If set, the file offset shall be set to the end of the file prior to
each write.
2. https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html
> If the `O_APPEND` flag of the file status flags is set, the file
offset shall be set to the end of the file prior to each write and no
intervening file modification operation shall occur between changing the
file offset and the write operation.
3. https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html
> If ''whence'' is `SEEK_CUR`, the file offset shall be set to its
current location plus offset.
>
> ''' RETURN VALUE''' \\
> Upon successful completion, the resulting offset, as measured in
bytes from the beginning of the file, shall be returned.
--
Ticket URL: <https://dev.haiku-os.org/ticket/16506>
Haiku <https://dev.haiku-os.org>
The Haiku operating system.