This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implement fmemopen


Eric Blake wrote:
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?


Just wait until you have the final patch to submit.


-- Jeff J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]