aboutsummaryrefslogtreecommitdiff
path: root/libio/fileops.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-08-15 23:57:00 +0000
committerRoland McGrath <roland@gnu.org>2002-08-15 23:57:00 +0000
commitfc77d66abf6ed97a50e30b619b1647759d43f593 (patch)
tree4eacd4d04abb104c54fe9ef2d05a65da6bafa315 /libio/fileops.c
parent8f83366e132bd7e273ea97c571e2d44c20a8ccbf (diff)
downloadglibc-fc77d66abf6ed97a50e30b619b1647759d43f593.tar
glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.tar.gz
glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.tar.bz2
glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.zip
* libio/fileops.c (_IO_file_seekoff_mmap): Leave read pointers at EOF
if seek would go past it. (mmap_remap_check): If file position is at or past EOF after check, leave read pointers at EOF and don't seek. * libio/tst-mmap-offend.c: New file. * libio/Makefile (tests): Add it.
Diffstat (limited to 'libio/fileops.c')
-rw-r--r--libio/fileops.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/libio/fileops.c b/libio/fileops.c
index 247243f44c..24235e9134 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -665,22 +665,30 @@ mmap_remap_check (_IO_FILE *fp)
# undef ROUNDED
fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
- _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + fp->_offset,
+ _IO_setg (fp, fp->_IO_buf_base,
+ fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
+ ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
fp->_IO_buf_end);
- if (
+ /* If we are already positioned at or past the end of the file, don't
+ change the current offset. If not, seek past what we have mapped,
+ mimicking the position left by a normal underflow reading into its
+ buffer until EOF. */
+
+ if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
+ {
+ if (
# ifdef _G_LSEEK64
- _G_LSEEK64
+ _G_LSEEK64
# else
- __lseek
+ __lseek
# endif
- (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET)
- != fp->_IO_buf_end - fp->_IO_buf_base)
- {
- fp->_flags |= _IO_ERR_SEEN;
- return EOF;
+ (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET)
+ != fp->_IO_buf_end - fp->_IO_buf_base)
+ fp->_flags |= _IO_ERR_SEEN;
+ else
+ fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
}
- fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
return 0;
}
@@ -1152,8 +1160,17 @@ _IO_file_seekoff_mmap (fp, offset, dir, mode)
if (result < 0)
return EOF;
- _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
- fp->_IO_buf_base + offset);
+ if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
+ /* One can fseek arbitrarily past the end of the file
+ and it is meaningless until one attempts to read.
+ Leave the buffer pointers in EOF state until underflow. */
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
+ else
+ /* Adjust the read pointers to match the file position,
+ but so the next read attempt will call underflow. */
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
+ fp->_IO_buf_base + offset);
+
fp->_offset = result;
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);