diff options
author | Roland McGrath <roland@gnu.org> | 2002-08-15 23:57:00 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-08-15 23:57:00 +0000 |
commit | fc77d66abf6ed97a50e30b619b1647759d43f593 (patch) | |
tree | 4eacd4d04abb104c54fe9ef2d05a65da6bafa315 /libio/fileops.c | |
parent | 8f83366e132bd7e273ea97c571e2d44c20a8ccbf (diff) | |
download | glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.zip glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.tar.gz glibc-fc77d66abf6ed97a50e30b619b1647759d43f593.tar.bz2 |
* 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.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/libio/fileops.c b/libio/fileops.c index 247243f..24235e9 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); |