work around a nasty bug in linux readv syscall
authorRich Felker <dalias@aerifal.cx>
Sat, 9 Apr 2011 05:17:55 +0000 (01:17 -0400)
committerRich Felker <dalias@aerifal.cx>
Sat, 9 Apr 2011 05:17:55 +0000 (01:17 -0400)
commit2cff36a84f268c09f4c9dc5a1340652c8e298dc0
tree9304edd800f3388484b0882b27c26dfb2e48c943
parent67e793e5e14fe031569117fd88328268e67ad4ee
work around a nasty bug in linux readv syscall

according to posix, readv "shall be equivalent to read(), except..."
that it places the data into the buffers specified by the iov array.
however on linux, when reading from a terminal, each iov element
behaves almost like a separate read. this means that if the first iov
exactly satisfied the request (e.g. a length-one read of '\n') and the
second iov is nonzero length, the syscall will block again after
getting the blank line from the terminal until another line is read.
simply put, entering a single blank line becomes impossible.

the solution, fortunately, is simple. whenever the buffer size is
nonzero, reduce the length of the requested read by one byte and let
the last byte go through the buffer. this way, readv will already be
in the second (and last) iov, and won't re-block on the second iov.
src/stdio/__stdio_read.c