diff --git a/libio/iofdopen.c b/libio/iofdopen.c index 5167220aa2..c86cf0f3ca 100644 --- a/libio/iofdopen.c +++ b/libio/iofdopen.c @@ -124,8 +124,19 @@ _IO_new_fdopen (fd, mode) #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif - _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &INTUSE(_IO_wfile_jumps)); - _IO_JUMPS (&new_f->fp) = &INTUSE(_IO_file_jumps); + /* Set up initially to use the `maybe_mmap' jump tables rather than using + __fopen_maybe_mmap to do it, because we need them in place before we + call _IO_file_attach or else it will allocate a buffer immediately. */ + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, +#ifdef _G_HAVE_MMAP + (read_write & _IO_NO_WRITES) ? &_IO_wfile_jumps_maybe_mmap : +#endif + &INTUSE(_IO_wfile_jumps)); + _IO_JUMPS (&new_f->fp) = +#ifdef _G_HAVE_MMAP + (read_write & _IO_NO_WRITES) ? &_IO_file_jumps_maybe_mmap : +#endif + &INTUSE(_IO_file_jumps); INTUSE(_IO_file_init) (&new_f->fp); #if !_IO_UNIFIED_JUMPTABLES new_f->fp.vtable = NULL; @@ -143,7 +154,7 @@ _IO_new_fdopen (fd, mode) _IO_mask_flags (&new_f->fp.file, read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); - return __fopen_maybe_mmap (&new_f->fp.file); + return &new_f->fp.file; } INTDEF2(_IO_new_fdopen, _IO_fdopen) diff --git a/libio/iofopen.c b/libio/iofopen.c index c1681a4a10..00a2c5f073 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -43,50 +43,16 @@ __fopen_maybe_mmap (fp) #ifdef _G_HAVE_MMAP if (fp->_flags & _IO_NO_WRITES) { - /* We use the file in read-only mode. This could mean we can - mmap the file and use it without any copying. But not all - file descriptors are for mmap-able objects and on 32-bit - machines we don't want to map files which are too large since - this would require too much virtual memory. */ - struct _G_stat64 st; + /* Since this is read-only, we might be able to mmap the contents + directly. We delay the decision until the first read attempt by + giving it a jump table containing functions that choose mmap or + vanilla file operations and reset the jump table accordingly. */ - 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) - /* Sanity check. */ - && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) - { - /* Try to map the file. */ - void *p; - -# ifdef _G_MMAP64 - p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_PRIVATE, - fp->_fileno, 0); -# else - p = __mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, - fp->_fileno, 0); -# endif - if (p != MAP_FAILED) - { - /* OK, we managed to map the file. Set the buffer up - and use a special jump table with simplified - underflow functions which never tries to read - anything from the file. */ - INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0); - - 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; - } - } + if (fp->_mode <= 0) + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_maybe_mmap; + else + _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_maybe_mmap; + fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap; } #endif return fp; diff --git a/libio/libioP.h b/libio/libioP.h index bfb36c30ef..cb9e918468 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -425,8 +425,10 @@ extern void _IO_default_imbue __P ((_IO_FILE *, void *)); extern struct _IO_jump_t _IO_file_jumps; extern struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden; +extern struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden; extern struct _IO_jump_t _IO_wfile_jumps attribute_hidden; extern struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden; +extern struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden; extern struct _IO_jump_t _IO_old_file_jumps attribute_hidden; extern struct _IO_jump_t _IO_streambuf_jumps; extern struct _IO_jump_t _IO_proc_jumps attribute_hidden; @@ -498,6 +500,8 @@ extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t)); extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int)); extern _IO_off64_t _IO_file_seekoff_mmap __P ((_IO_FILE *, _IO_off64_t, int, int)); +extern _IO_off64_t _IO_file_seekoff_maybe_mmap __P ((_IO_FILE *, _IO_off64_t, + int, int)); extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t)); extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t)); extern int _IO_file_stat __P ((_IO_FILE *, void *)); @@ -505,6 +509,7 @@ extern int _IO_file_close __P ((_IO_FILE *)); extern int _IO_file_close_mmap __P ((_IO_FILE *)); extern int _IO_file_underflow __P ((_IO_FILE *)); extern int _IO_file_underflow_mmap __P ((_IO_FILE *)); +extern int _IO_file_underflow_maybe_mmap __P ((_IO_FILE *)); extern int _IO_file_overflow __P ((_IO_FILE *, int)); #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) extern void _IO_file_init __P ((struct _IO_FILE_plus *));