aboutsummaryrefslogtreecommitdiff
path: root/libio/fileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'libio/fileops.c')
-rw-r--r--libio/fileops.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/libio/fileops.c b/libio/fileops.c
index c75accdaf8..15e30a43c8 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -781,7 +781,8 @@ _IO_file_xsgetn (fp, data, n)
void *data;
_IO_size_t n;
{
- register _IO_size_t want, have, count;
+ register _IO_size_t want, have;
+ register _IO_ssize_t count;
register char *s = data;
want = n;
@@ -815,7 +816,7 @@ _IO_file_xsgetn (fp, data, n)
/* If we now want less than a buffer, underflow and repeat
the copy. Otherwise, _IO_SYSREAD directly to
the user buffer. */
- if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
+ if (fp->_IO_buf_base && want <= fp->_IO_buf_end - fp->_IO_buf_base)
{
if (__underflow (fp) == EOF)
break;
@@ -823,6 +824,11 @@ _IO_file_xsgetn (fp, data, n)
continue;
}
+ /* These must be set before the sysread as we might longjmp out
+ waiting for input. */
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+
count = _IO_SYSREAD (fp, s, want);
if (count <= 0)
{
@@ -836,6 +842,8 @@ _IO_file_xsgetn (fp, data, n)
s += count;
want -= count;
+ if (fp->_offset != _IO_pos_BAD)
+ _IO_pos_adjust (fp->_offset, count);
}
}