On Thu, Oct 17, 2002 at 12:15:49AM +0200, Andi Kleen wrote:
> > lseek is ignored on O_APPEND files --- the write always re-seeks to
> > EOF. pwrite goes down that same code path too so it also gets the
> > append enforced. In your testing were you testing real writes, or
> > just the lseeks?
> I was testing a real write. Another hole is pwrite().
No, both work fine. The lseek only operates on the internal f_pos, it
doesn't affect the file. The write does affect the file but it
re-seeks back to EOF, so the write always appends. Tested on both 2.4
> #include <sys/fcntl.h>
> #include <unistd.h>
> main(int ac, char **av)
> int fd = open(av, O_APPEND|O_WRONLY);
> if (lseek(fd, 100, SEEK_SET) < 0) perror("expected lseek error");
> if (write(fd, "1", 1) < 0) perror("expected write error");
> else printf("write succeeded\n");
> % gcc -o tseek tseek.c
> % dd if=/dev/zero of=/tmp/TEST bs=1k count=10
> % su
> # chattr +a /tmp/TEST
> % ./tseek /tmp/TEST
> write succeeded
Fine. That's correct behaviour.
Do an "ls -l /tmp/TEST" afterwards and you'll see that it got exactly
one byte longer as a result of the one-byte write. The write was an
append despite the lseek. This is the behaviour required by
Internally, O_APPEND is enforced in generic_file_write, not by lseek.
(Any filesystem which overrides generic_file_write needs to do the
appropriate logic itself.)