<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/stdio, branch v1.1.14</title>
<subtitle>musl - an implementation of the standard library for Linux-based systems</subtitle>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/'/>
<entry>
<title>fix assumption in fputs that fwrite returning 0 implies an error</title>
<updated>2016-02-16T18:26:16+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-02-16T18:26:16+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=10a17dfbad2c267d885817abc9c7589fc7ff630b'/>
<id>10a17dfbad2c267d885817abc9c7589fc7ff630b</id>
<content type='text'>
internally, the idiom of passing nmemb=1 to fwrite and interpreting
the return value of fwrite (which is necessarily 0 or 1) as
failure/success is fairly widely used. this is not correct, however,
when the size argument is unknown and may be zero, since C requires
fwrite to return 0 in that special case. previously fwrite always
returned nmemb on success, but this was changed for conformance with
ISO C by commit 500c6886c654fd45e4926990fee2c61d816be197.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
internally, the idiom of passing nmemb=1 to fwrite and interpreting
the return value of fwrite (which is necessarily 0 or 1) as
failure/success is fairly widely used. this is not correct, however,
when the size argument is unknown and may be zero, since C requires
fwrite to return 0 in that special case. previously fwrite always
returned nmemb on success, but this was changed for conformance with
ISO C by commit 500c6886c654fd45e4926990fee2c61d816be197.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix return value for fread/fwrite when size argument is 0</title>
<updated>2016-02-11T00:44:19+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-02-11T00:44:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=500c6886c654fd45e4926990fee2c61d816be197'/>
<id>500c6886c654fd45e4926990fee2c61d816be197</id>
<content type='text'>
when the size argument was zero but nmemb was nonzero, these functions
were returning nmemb, despite no data having been written.
conceptually this is not wrong, but the standard requires a return
value of zero in this case.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
when the size argument was zero but nmemb was nonzero, these functions
were returning nmemb, despite no data having been written.
conceptually this is not wrong, but the standard requires a return
value of zero in this case.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix failed write reporting by fwrite in line-buffered mode</title>
<updated>2016-02-10T18:51:05+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-02-10T18:51:05+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=5a6e8d098abfef67028e6c3edbac39e0bbaf8bd8'/>
<id>5a6e8d098abfef67028e6c3edbac39e0bbaf8bd8</id>
<content type='text'>
when a write error occurred while flushing output due to a newline,
fwrite falsely reported all bytes up to and including the newline as
successfully written. in general, due to buffering such "spurious
success" returns are acceptable for stdio; however for line-buffered
mode it was subtly wrong. errors were still visible via ferror() or as
a short-write return if there was more data past the newline that
should have been written, but since the contract for line-buffered
mode is that everything up through the newline be written out
immediately, a discrepency was observable in the actual file contents.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
when a write error occurred while flushing output due to a newline,
fwrite falsely reported all bytes up to and including the newline as
successfully written. in general, due to buffering such "spurious
success" returns are acceptable for stdio; however for line-buffered
mode it was subtly wrong. errors were still visible via ferror() or as
a short-write return if there was more data past the newline that
should have been written, but since the contract for line-buffered
mode is that everything up through the newline be written out
immediately, a discrepency was observable in the actual file contents.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix overly pessimistic realloc strategy in getdelim</title>
<updated>2015-12-20T05:39:35+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-12-20T05:32:46+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=c673158d91ad995ed59dd910777cd6464f61fe8e'/>
<id>c673158d91ad995ed59dd910777cd6464f61fe8e</id>
<content type='text'>
previously, getdelim was allocating twice the space needed every time
it expanded its buffer to implement exponential buffer growth (in
order to avoid quadratic run time). however, this doubling was
performed even when the final buffer length needed was already known,
which is the common case that occurs whenever the delimiter is in the
FILE's buffer.

this patch makes two changes to remedy the situation:

1. over-allocation is no longer performed if the delimiter has already
been found when realloc is needed.

2. growth factor is reduced from 2x to 1.5x to reduce the relative
excess allocation in cases where the delimiter is not initially in the
buffer, including unbuffered streams.

in theory these changes could lead to quadratic time if the same
buffer is reused to process a sequence of lines successively
increasing in length, but once this length exceeds the stdio buffer
size, the delimiter will not be found in the buffer right away and
exponential growth will still kick in.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
previously, getdelim was allocating twice the space needed every time
it expanded its buffer to implement exponential buffer growth (in
order to avoid quadratic run time). however, this doubling was
performed even when the final buffer length needed was already known,
which is the common case that occurs whenever the delimiter is in the
FILE's buffer.

this patch makes two changes to remedy the situation:

1. over-allocation is no longer performed if the delimiter has already
been found when realloc is needed.

2. growth factor is reduced from 2x to 1.5x to reduce the relative
excess allocation in cases where the delimiter is not initially in the
buffer, including unbuffered streams.

in theory these changes could lead to quadratic time if the same
buffer is reused to process a sequence of lines successively
increasing in length, but once this length exceeds the stdio buffer
size, the delimiter will not be found in the buffer right away and
exponential growth will still kick in.
</pre>
</div>
</content>
</entry>
<entry>
<title>avoid updating caller's size when getdelim fails to realloc</title>
<updated>2015-12-20T04:43:31+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-12-20T04:43:31+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=d87f0a9a95f0a1228ee5579e5822a8c93bc96823'/>
<id>d87f0a9a95f0a1228ee5579e5822a8c93bc96823</id>
<content type='text'>
getdelim was updating *n, the caller's stored buffer size, before
calling realloc. if getdelim then failed due to realloc failure, the
caller would see in *n a value larger than the actual size of the
allocated block, and use of that value is unsafe. in particular,
passing it again to getdelim is unsafe.

now, temporary storage is used for the desired new size, and *n is not
written until realloc succeeds.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
getdelim was updating *n, the caller's stored buffer size, before
calling realloc. if getdelim then failed due to realloc failure, the
caller would see in *n a value larger than the actual size of the
allocated block, and use of that value is unsafe. in particular,
passing it again to getdelim is unsafe.

now, temporary storage is used for the desired new size, and *n is not
written until realloc succeeds.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix single-byte overflow of malloc'd buffer in getdelim</title>
<updated>2015-10-25T02:42:10+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-10-25T02:42:10+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=b114190b29417fff6f701eea3a3b3b6030338280'/>
<id>b114190b29417fff6f701eea3a3b3b6030338280</id>
<content type='text'>
the buffer enlargement logic here accounted for the terminating null
byte, but not for the possibility of hitting the delimiter in the
buffer-refill code path that uses getc_unlocked, in which case two
additional bytes (the delimiter and the null termination) are written
without another chance to enlarge the buffer.

this patch and the corresponding bug report are by Felix Janda.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the buffer enlargement logic here accounted for the terminating null
byte, but not for the possibility of hitting the delimiter in the
buffer-refill code path that uses getc_unlocked, in which case two
additional bytes (the delimiter and the null termination) are written
without another chance to enlarge the buffer.

this patch and the corresponding bug report are by Felix Janda.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix open_[w]memstream behavior when no writes take place</title>
<updated>2015-10-08T22:10:09+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-10-08T22:03:53+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=7b9f57f207b51132f188f750161953b7baf32154'/>
<id>7b9f57f207b51132f188f750161953b7baf32154</id>
<content type='text'>
the specification for these functions requires that the buffer/size
exposed to the caller be valid after any successful call to fflush or
fclose on the stream. the implementation's approach is to update them
only at flush time, but that misses the case where fflush or fclose is
called without any writes having taken place, in which case the write
flushing callback will not be called.

to fix both the observable bug and the desired invariant, setup empty
buffers at open time and fail the open operation if no memory is
available.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the specification for these functions requires that the buffer/size
exposed to the caller be valid after any successful call to fflush or
fclose on the stream. the implementation's approach is to update them
only at flush time, but that misses the case where fflush or fclose is
called without any writes having taken place, in which case the write
flushing callback will not be called.

to fix both the observable bug and the desired invariant, setup empty
buffers at open time and fail the open operation if no memory is
available.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix fclose of permanent (stdin/out/err) streams</title>
<updated>2015-09-09T04:31:07+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-09-09T04:31:07+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=426a0e2912c07f0e86feee2ed12f24a808eac2f4'/>
<id>426a0e2912c07f0e86feee2ed12f24a808eac2f4</id>
<content type='text'>
this fixes a bug reported by Nuno Gonçalves. previously, calling
fclose on stdin or stdout resulted in deadlock at exit time, since
__stdio_exit attempts to lock these streams to flush/seek them, and
has no easy way of knowing that they were closed.

conceptually, leaving a FILE stream locked on fclose is valid since,
in the abstract machine, it ceases to exist. but to satisfy the
implementation-internal assumption in __stdio_exit that it can access
these streams unconditionally, we need to unlock them.

it's also necessary that fclose leaves permanent streams in a state
where __stdio_exit will not attempt any further operations on them.
fortunately, the call to fflush already yields this property.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this fixes a bug reported by Nuno Gonçalves. previously, calling
fclose on stdin or stdout resulted in deadlock at exit time, since
__stdio_exit attempts to lock these streams to flush/seek them, and
has no easy way of knowing that they were closed.

conceptually, leaving a FILE stream locked on fclose is valid since,
in the abstract machine, it ceases to exist. but to satisfy the
implementation-internal assumption in __stdio_exit that it can access
these streams unconditionally, we need to unlock them.

it's also necessary that fclose leaves permanent streams in a state
where __stdio_exit will not attempt any further operations on them.
fortunately, the call to fflush already yields this property.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix failure of tempnam to null-terminate result</title>
<updated>2015-08-09T22:51:09+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-08-09T22:51:09+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=062bb737de06c3906b4b4a07c7fc0fb286287efe'/>
<id>062bb737de06c3906b4b4a07c7fc0fb286287efe</id>
<content type='text'>
tempnam uses an uninitialized buffer which is filled using memcpy and
__randname. It is therefore necessary to explicitly null-terminate it.

based on patch by Felix Janda.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
tempnam uses an uninitialized buffer which is filled using memcpy and
__randname. It is therefore necessary to explicitly null-terminate it.

based on patch by Felix Janda.
</pre>
</div>
</content>
</entry>
<entry>
<title>refactor stdio open file list handling, move it out of global libc struct</title>
<updated>2015-06-16T07:11:19+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-06-16T07:11:19+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=1b0cdc8700d29ef018bf226d74b2b58b23bce91c'/>
<id>1b0cdc8700d29ef018bf226d74b2b58b23bce91c</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
</feed>
