Eric Blake <ebb9 <at> byu.net> writes:
POSIX 200x (the next revision of POSIX) will include fmemopen. And while it
can now be implemented in user-space (via my previous fopencookie addition),
it
would be nice to implement it directly in newlib.
Here's a program I was using to test it.
...
else
{
buf = malloc(len);
memcpy(buf, argv[3], len + 1);
Obviously, the malloc should be 1 byte bigger here (or else the memcpy one byte
smaller).
My implementation of fmemopen is even more reliable than glibc (at least as
of
glibc 2.3), since on the Linux machine where I tested:
However, I missed a corner case, where the proposed POSIX wording for fmemopen
was a bit unclear, but where the corresponding open_memstream example was
explicit:
./foo 5 w 12345
fmemopen status 0x909a038, errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? w
char to write? a
fputc write \x61('a'), errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? w
char to write? b
fputc write \x62('b'), errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? w
char to write? c
fputc write \x63('c'), errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? f
fflush status 0, errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? s
offset and whence? 0 0
fseek status 0, errno 0 Success
ftell status 0, errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? w
char to write? d
fputc write \x64('d'), errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? s
offset and whence? 3 0
fseek status 0, errno 0 Success
ftell status 3, errno 0 Success
(r)ead, (w)rite, (s)eek, (d)ump, (f)lush, f(e)rror, (c)learerr, or (q)uit? q
fclose status 0, errno 0 Success
Here, glibc gives:
buf len 5, strnlen 3, contents "dbc\x005"
but my first implementation gave:
buf len 5, strnlen 3, contents "d\x00c\x005"
So my implementation needs to be made a bit smarter - when in write-only mode,
remember the character being overwritten by the trailing NUL, then when seeking
to a different location, restore that byte (ie. the trailing NUL should always
correspond to the current position, rather than being a permanent artifact of
writing).
I'm still working on that - should I go ahead and commit the base
implementation, then a followup patch, or wait to commit until I have the final
patch?