This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: Implement fmemopen
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Thu, 19 Jul 2007 15:19:13 +0000 (UTC)
- Subject: Re: Implement fmemopen
- References: <loom.20070719T001200-214@post.gmane.org>
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?
--
Eric Blake