Implement fmemopen

Jeff Johnston jjohnstn@redhat.com
Fri Jul 20 11:32:00 GMT 2007


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.



More information about the Newlib mailing list