Sources Bugzilla – Bug 12836
fmemopen(buf,size,"w+b") isn't binary
Last modified: 2012-04-28 02:23:59 UTC
The documented behavior of fmemopen behaving in binary mode if 'b' was present in mode does not actually happen if 'b' is not in mode[1]. For consistency with fopen and friends, 'wb+' and 'w+b' should have identical effect.
diff --git i/libio/fmemopen.c w/libio/fmemopen.c index 75f9f7e..ca7c604 100644 --- i/libio/fmemopen.c +++ w/libio/fmemopen.c @@ -251,7 +251,7 @@ fmemopen (void *buf, size_t len, const char *mode) else c->pos = 0; - c->binmode = mode[0] != '\0' && mode[1] == 'b'; + c->binmode = mode[0] && mode[1 + (mode[1] == '+')] == 'b'; iof.read = fmemopen_read; iof.write = fmemopen_write;
An(In reply to comment #0) > The documented behavior of fmemopen behaving in binary mode if 'b' was present > in mode does not actually happen if 'b' is not in mode[1]. For consistency > with fopen and friends, 'wb+' and 'w+b' should have identical effect. Who says that? Any such change would mean that either we'd have to change the version of the fmemopen interface and prevent code compiled now to use fmemopen from running with older glibcs. And for what? Just so that you get "consistency"? No good reason.
(In reply to comment #2) > An(In reply to comment #0) > > The documented behavior of fmemopen behaving in binary mode if 'b' was present > > in mode does not actually happen if 'b' is not in mode[1]. For consistency > > with fopen and friends, 'wb+' and 'w+b' should have identical effect. > > Who says that? The Austin Group: http://austingroupbugs.net/view.php?id=456 At lines 28743-28750 [XSH fmemopen DESCRIPTION], undo the TC1 changes (XSH/TC1/D2/0136), and replace the existing text (in Issue 7, the 6 rows from "r or rb" to "at the first null byte") with: r or rb Open the stream for reading. w or wb Open the stream for writing. a or ab Append; open the stream for writing. r+ or rb+ or r+b Open the stream for update (reading and writing). w+ or wb+ or w+b Open the stream for update (reading and writing). Truncate the buffer contents. a+ or ab+ or a+b Append; open the stream for update (reading and writing). > Any such change would mean that either we'd have to change the > version of the fmemopen interface and prevent code compiled now to use fmemopen > from running with older glibcs. This one-liner patch is forwards compatible: Old programs have four defined choices documented in 'man fmemopen' when mode starts with 'w': fmemopen (,"w") - text mode fmemopen (,"wb") - binary mode fmemopen (,"w+") - text mode fmemopen (,"wb+") - binary mode all other strings starting with w have undefined behavior New programs will have five defined choices: fmemopen (,"w") - text mode fmemopen (,"wb") - binary mode fmemopen (,"w+") - text mode fmemopen (,"wb+") - binary mode fmemopen (,"w+b") - binary mode all other strings starting with w have undefined behavior Old programs should not have been relying on undefined behavior of "w+b", and this patch merely adds one new mode, without changing the behavior of any existing defined modes. I don't know why you are complaining about this not being backwards compatible. I agree that a program compiled against glibc 2.15 (assuming that is the glibc version where this patch is added) but run against glibc 2.14 would do the wrong thing for w+b if fmemopen is not versioned for this fix. But when have we ever supported that type of back compatibility? In general, when you compile against a newer glibc, there are no promises that you can run your program against older glibc. Furthermore, did you even version bump fmemopen when you added support for 'b' in the first place in bug 6544 - that is, if I use "wb" compiled against glibc 2.9 but then run against glibc 2.8, will I get a link failure due to a missing versioned symbol, or just a silent change in behavior because I was tickling behavior that was undefined in 2.8? Likewise, did you version bump fopen when you fixed a mis-parse of the mode string in bug 12685? At the end of the day, this patch is just a one-liner fix to a mis-parse of the mode string, and not a version compatibility nightmare that you are trying to make it out to be. > And for what? Just so that you get > "consistency"? No good reason. It's more than just "consistency", it is so that new programs will be able to use the new requirements to be added in Issue 8 of POSIX.
I've added the following to the fmemopen() man page, under BUGS: === To specify binary mode for .BR fmemopen () the \(aqb\(aq must be the .I second character in .IR mode . Thus, for example, "wb+" has the desired effect, but "w+b" does not. This is inconsistent with the corresponding case in .\" FIXME http://sourceware.org/bugzilla/show_bug.cgi?id=12836 .BR fopen (3). ===