From fc77d66abf6ed97a50e30b619b1647759d43f593 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 15 Aug 2002 23:57:00 +0000 Subject: * 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. --- libio/fileops.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'libio/fileops.c') 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); -- cgit v1.1