<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/stdio, branch v1.1.13</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 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>
<entry>
<title>byte-based C locale, phase 2: stdio and iconv (multibyte callers)</title>
<updated>2015-06-16T06:10:29+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2015-06-16T05:35:31+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=16f18d036d9a7bf590ee6eb86785c0a9658220b6'/>
<id>16f18d036d9a7bf590ee6eb86785c0a9658220b6</id>
<content type='text'>
this patch adjusts libc components which use the multibyte functions
internally, and which depend on them operating in a particular
encoding, to make the appropriate locale changes before calling them
and restore the calling thread's locale afterwards. activating the
byte-based C locale without these changes would cause regressions in
stdio and iconv.

in the case of iconv, the current implementation was simply using the
multibyte functions as UTF-8 conversions. setting a multibyte UTF-8
locale for the duration of the iconv operation allows the code to
continue working.

in the case of stdio, POSIX requires that FILE streams have an
encoding rule bound at the time of setting wide orientation. as long
as all locales, including the C locale, used the same encoding,
treating high bytes as UTF-8, there was no need to store an encoding
rule as part of the stream's state.

a new locale field in the FILE structure points to the locale that
should be made active during fgetwc/fputwc/ungetwc on the stream. it
cannot point to the locale active at the time the stream becomes
oriented, because this locale could be mutable (the global locale) or
could be destroyed (locale_t objects produced by newlocale) before the
stream is closed. instead, a pointer to the static C or C.UTF-8 locale
object added in commit commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
is used. this is valid since categories other than LC_CTYPE will not
affect these functions.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this patch adjusts libc components which use the multibyte functions
internally, and which depend on them operating in a particular
encoding, to make the appropriate locale changes before calling them
and restore the calling thread's locale afterwards. activating the
byte-based C locale without these changes would cause regressions in
stdio and iconv.

in the case of iconv, the current implementation was simply using the
multibyte functions as UTF-8 conversions. setting a multibyte UTF-8
locale for the duration of the iconv operation allows the code to
continue working.

in the case of stdio, POSIX requires that FILE streams have an
encoding rule bound at the time of setting wide orientation. as long
as all locales, including the C locale, used the same encoding,
treating high bytes as UTF-8, there was no need to store an encoding
rule as part of the stream's state.

a new locale field in the FILE structure points to the locale that
should be made active during fgetwc/fputwc/ungetwc on the stream. it
cannot point to the locale active at the time the stream becomes
oriented, because this locale could be mutable (the global locale) or
could be destroyed (locale_t objects produced by newlocale) before the
stream is closed. instead, a pointer to the static C or C.UTF-8 locale
object added in commit commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
is used. this is valid since categories other than LC_CTYPE will not
affect these functions.
</pre>
</div>
</content>
</entry>
</feed>
