Test case: #include <stdio.h> #include <unistd.h> int main() { FILE *f = tmpfile(); printf("%ld\n", ftell(f)); write(fileno(f), "abc", 3); printf("%ld\n", ftell(f)); } Expected output: 0 3 glibc output: 0 0 The issue is that glibc is wrongly caching the file position when it does not have any guarantee that the stdio FILE stream is or will remain the "active handle" for the open file description (see POSIX XSH 2.5.1 Interaction of File Descriptors and Standard I/O Streams). While the exact semantics for active handle are complex (read the cited text), the basic situation is that you can only guarantee that the FILE remains the active handle once you've started reading from or writing to it, and up until an operation that allows the application to switch to a different active handle (a successful seek, explicit flush, newline-caused flush on line-buffered stream, reaching eof reading, etc.). Note that the test case above only shows the issue for writing, but as far as I can tell it applies equally to reading, and applies to all possible open modes (read/write/update/append/etc.). I used tmpfile() for convenience but the same should work with fopen or fdopen.
One thing I misstated: a successful seek does not permit changing the active handle, so it seems to be valid to keep the cached offset across fseek/fseeko calls.
As discussed on list, this is a variant of bug 16532. *** This bug has been marked as a duplicate of bug 16532 ***