Solved with glibc 2.24 -- See UPDATE below
Here is a piece of C-Code (compiled with gcc 5.3.1, glibc 2.23):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int main() {
const char* s1="Original content of file.\n"
"still original content and some remaining original content.\n";
const char* s2="overwriting data with new content\n";
const char* s3="appended data\n";
const size_t bufsz=strlen(s1)+1;
char buf[bufsz];
FILE *f;
int r;
f=fmemopen(buf,bufsz,"w");
assert(f!=NULL);
// setbuf(f, NULL); // variant no. 1
// setbuffer(f, buf, bufsz); // variant no. 2
r=fwrite(s1,strlen(s1),1,f);
assert(r==1);
r=fflush(f);
assert(r==0);
rewind(f);
r=fwrite(s2,strlen(s2),1,f);
assert(r==1);
r=fwrite(s3,strlen(s3),1,f);
assert(r==1);
r=fclose(f);
assert(r==0);
printf("%s",buf);
}
It does what I expect -- The output is:
overwriting data with new content appended data and some remaining original content.
Now, the manpage fmemopen(3) advices to either disable buffering (uncomment variant 1), or to explicitely set
buf
as buffer (uncomment variant 2).However, in both cases, I get as result:
appended data ta with new content ginal content and some remaining original content.
Thus, the appended data was not written after the second content, as expected, but did overwrite the second content.
The behaviour remains the same if I open the file in binary mode (i.e. replacing the "w" mode by "wb").
valgrind does not report any errors (Except a false positive "Source and destination overlap" in the case of buffering. The latter one is due to the try to write the STDIO buffer into the memory, which is indeed the same address.)
What is wrong? Did I make a mistake? Or is this a GLIBC bug?
UPDATE
On August 4th, a new glibc version 2.24 was released. With gcc 5.4.0 and glibc 2.24, variant no. 1 (unbuffered FILE) works fine. Variant 2 (self-buffered version) gives a different, but still erroneous result. Thus I believe R.. is right in claiming that this is a documentation bug in the manpage fmemopen(3). I will raise a bug report ...