This is a regression from 2.15.
Test case below, does not assert with glibc-2.15, but asserts with current trunk.
If I use fopen() instead of fdopen() ["./a.out -o"] or if I fflush() after fwrite() ["./a.out -f"], then assert goes away.
/* --- cut --- */
int main(int argc, char *argv)
int do_flush = 0, do_fopen = 0;
const char *const fname = "/tmp/output";
while ((opt = getopt (argc, argv, "fo")) != -1)
case 'f': do_flush = 1; break;
case 'o': do_fopen = 1; break;
fp = fopen (fname, "w");
written = fwrite ("abcabc", 1, 6, fp);
assert (written == 6);
fp = fopen (fname, "a");
int fd = open (fname, O_WRONLY, 0);
assert (fd != -1);
fp = fdopen (fd, "a");
assert (fp != NULL);
written = fwrite ("ghi", 1, 3, fp);
assert (written == 3);
off = ftello (fp);
assert (off == 9);
/* --- cut --- */
This broke with commit adb26faefe47b7d34c941cbfc193ca7a5fde8e3f:
2012-09-28 Siddhesh Poyarekar <firstname.lastname@example.org>
* libio/fileops.c (_IO_new_file_seekoff): Don't flush buffer
for ftell. Compute offsets from write pointers instead.
* libio/wfileops.c (_IO_wfile_seekoff): Likewise.
Thanks, I'll look into it.
*** Bug 16605 has been marked as a duplicate of this bug. ***
Fixed in master:
Author: Siddhesh Poyarekar <email@example.com>
Date: Tue Mar 4 07:45:58 2014 +0530
Separate ftell from fseek logic and avoid modifying FILE data (#16532)
ftell semantics are distinct from fseek(SEEK_CUR) especially when it
is called on a file handler that is not yet active. Due to this
caveat, much care needs to be taken while modifying the handler data
and hence, this first iteration on separating out ftell focusses on
maintaining handler data integrity at all times while it figures out
the current stream offset. The result is that it makes a syscall for
every offset request.
There is scope for optimizing this by caching offsets when we know
that the handler is active. A simple way to find out is when the
buffers have data. It is not so simple to find this out when the
buffer is empty without adding some kind of flag.
I am afraid the provided fix has caused a memory leak.
The malloc in the patch has not been freed.