diff options
Diffstat (limited to 'libio')
-rw-r--r-- | libio/fileops.c | 42 | ||||
-rw-r--r-- | libio/iofopen.c | 12 |
2 files changed, 42 insertions, 12 deletions
diff --git a/libio/fileops.c b/libio/fileops.c index 92f1be49e7..dd8960ef03 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -1197,28 +1197,54 @@ _IO_file_xsgetn_mmap (fp, data, n) { register _IO_size_t have; char *read_ptr = fp->_IO_read_ptr; + register char *s = (char *) data; have = fp->_IO_read_end - fp->_IO_read_ptr; if (have < n) { - /* Maybe the read buffer is not yet fully set up. */ - fp->_IO_read_ptr = fp->_IO_read_end; - if (fp->_IO_read_end < fp->_IO_buf_end - && _IO_file_underflow_mmap (fp) != EOF) - have = fp->_IO_read_end - read_ptr; + if (__builtin_expect (_IO_in_backup (fp), 0)) + { +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif + n -= have; + _IO_switch_to_main_get_area (fp); + read_ptr = fp->_IO_read_ptr; + have = fp->_IO_read_end - fp->_IO_read_ptr; + } + + if (have < n) + { + /* Maybe the read buffer is not yet fully set up. */ + fp->_IO_read_ptr = fp->_IO_read_end; + if (fp->_IO_read_end < fp->_IO_buf_end + && _IO_file_underflow_mmap (fp) != EOF) + have = fp->_IO_read_end - read_ptr; + } } if (have == 0) - fp->_flags |= _IO_EOF_SEEN; + { + if (s == (char *) data) + fp->_flags |= _IO_EOF_SEEN; + } else { have = MIN (have, n); - memcpy (data, read_ptr, have); +#ifdef _LIBC + s = __mempcpy (s, read_ptr, have); +#else + memcpy (s, read_ptr, have); + s += have; +#endif fp->_IO_read_ptr = read_ptr + have; } - return have; + return s - (char *) data; } struct _IO_jump_t _IO_file_jumps = diff --git a/libio/iofopen.c b/libio/iofopen.c index 4bb780de13..c1681a4a10 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -53,7 +53,9 @@ __fopen_maybe_mmap (fp) if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode) && st.st_size != 0 /* Limit the file size to 1MB for 32-bit machines. */ - && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)) + && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024) + /* Sanity check. */ + && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) { /* Try to map the file. */ void *p; @@ -72,15 +74,17 @@ __fopen_maybe_mmap (fp) underflow functions which never tries to read anything from the file. */ INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0); - _IO_setg (fp, p, p, p); + + if (fp->_offset == _IO_pos_BAD) + fp->_offset = 0; + + _IO_setg (fp, p, p + fp->_offset, p + fp->_offset); if (fp->_mode <= 0) _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap; else _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_mmap; fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; - - fp->_offset = 0; } } } |