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 <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




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