[haiku-bugs] [Haiku] #16506: write() doesn't properly update file offset if opened with O_APPEND

  • From: "Haiku" <trac@xxxxxxxxxxxx>
  • To: undisclosed-recipients: ;
  • Date: Wed, 02 Sep 2020 18:50:38 -0000

#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.

Other related posts: