|Age||Commit message (Collapse)||Author||Lines|
previously, POSIX erroneously required this to fail with EINVAL
despite the traditional glibc implementation, on which the POSIX
interface was based, allowing it. the resolution of Austin Group issue
818 removes the requirement to fail.
libc.h was intended to be a header for access to global libc state and
related interfaces, but ended up included all over the place because
it was the way to get the weak_alias macro. most of the inclusions
removed here are places where weak_alias was needed. a few were
recently introduced for hidden. some go all the way back to when
libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented)
cancellation points had to include it.
remaining spurious users are mostly callers of the LOCK/UNLOCK macros
and files that use the LFS64 macro to define the awful *64 aliases.
in a few places, new inclusion of libc.h is added because several
internal headers no longer implicitly include libc.h.
declarations for __lockfile and __unlockfile are moved from libc.h to
stdio_impl.h so that the latter does not need libc.h. putting them in
libc.h made no sense at all, since the macros in stdio_impl.h are
needed to use them correctly anyway.
the w+ mode is specified to "truncate the buffer contents". like most
of fmemopen, exactly what this means is underspecified. mode w and w+
of course implicitly 'truncate' the buffer if a write from the initial
position is flushed, so in order for this part of the text about w+
not to be spurious, it should be interpreted as requiring something
else, and the obvious reasonable interpretation is that the truncation
is immediately visible if you attempt to read from the stream or the
buffer before writing/flushing.
this interpretation agrees with reported conformance test failures.
rather than manually performing pointer arithmetic to carve multiple
objects out of one allocation, use a containing struct that
encompasses them all.
when a null buffer pointer is passed to fmemopen, requesting it
allocate its own memory buffer, extremely large size arguments near
SIZE_MAX could overflow and result in underallocation. this results
from omission of the size of the cookie structure in the overflow
check but inclusion of it in the calloc call.
instead of accounting for individual small contributions to the total
allocation size needed, simply reject sizes larger than PTRDIFF_MAX,
which will necessarily fail anyway. then adding arbitrary fixed-size
structures is safe without matching up the expressions in the
comparison and the allocation.
functions which open in-memory FILE stream variants all shared a tail
with __fdopen, adding the FILE structure to stdio's open file list.
replacing this common tail with a function call reduces code size and
duplication of logic. the list is also partially encapsulated now.
function signatures were chosen to facilitate tail call optimization
and reduce the need for additional accessor functions.
with these changes, static linked programs that do not use stdio no
longer have an open file list at all.
per interpretation for austin group issue #626, fflush(0) and exit()
must block waiting for a lock if another thread has locked a memory
stream with flockfile. this adds some otherwise-unnecessary
synchronization cost to use of memory streams, but there was already a
synchronization cost calling malloc anyway.
previously the stream was only added to the open file list in
single-threaded programs, so that upon subsequent call to
pthread_create, locking could be turned on for the stream.
this header evolved to facilitate the extremely lazy practice of
omitting explicit includes of the necessary headers in individual
stdio source files; not only was this sloppy, but it also increased
now, stdio_impl.h is only including the headers it needs for its own
use; any further headers needed by source files are included directly
to deal with the fact that the public headers may be used with pre-c99
compilers, __restrict is used in place of restrict, and defined
appropriately for any supported compiler. we also avoid the form
[restrict] since older versions of gcc rejected it due to a bug in the
original c99 standard, and instead use the form *restrict.
null termination is only added when current size grows.
in update modes, null termination is not added if it does not fit
(i.e. it is not allowed to clobber data).
these rules make very little sense, but that's how it goes..
read should not be allowed past "current size".
append mode should write at "current size", not buffer size.
null termination should not be written except when "current size" grows.
disallow seek past end of buffer (per posix)
fix position accounting to include data buffered for read
don't set eof flag when no data was requested
testing so far has been minimal. may need further work.