summary refs log tree commit diff
path: root/libio/wfileops.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-01-07 09:33:53 +0000
committerUlrich Drepper <drepper@redhat.com>2002-01-07 09:33:53 +0000
commit0469311e8702371ee6270ec0ccd05e85e5138483 (patch)
treeefbf96c9796b587b09119d832df76a1a23ccd186 /libio/wfileops.c
parent463918b5f2323285b89bde42c732b83f63eb4881 (diff)
downloadglibc-0469311e8702371ee6270ec0ccd05e85e5138483.tar.gz
glibc-0469311e8702371ee6270ec0ccd05e85e5138483.tar.xz
glibc-0469311e8702371ee6270ec0ccd05e85e5138483.zip
Update.
2002-01-07  Ulrich Drepper  <drepper@redhat.com>

	* libio/fileops.c (_IO_file_underflow_mmap): New function.
	(_IO_file_close_mmap): New function.
	(_IO_file_jumps_mmap): New variable.
	* libio/wfileops.c (_IO_wfile_underflow): Reset read pointer before
	trying to convert rest of byte buffer.
	(_IO_wfile_underflow_mmap): New function.
	(_IO_wfile_jumps_mmap): New variable.
	* libio/iofopen.c (__fopen_maybe_mmap): New function.
	(__fopen_internal): New function.  Split out from _IO_new_fopen.
	(_IO_new_fopen): Call __fopen_internal.
	* libio/iofopen64.c: Just call __fopen_internal.
	* libio/iofdopen.c: Call __fopen_maybe_mmap before returning
	successfully.
	* libio/iolibio.h: Declare __fopen_internal and __fopen_maybe_mmap.
	* libio/libioP.h: Declare _IO_file_jumps_mmap, _IO_wfile_jumps_mmap,
	_IO_file_close_mmap.

	* sysdeps/gnu/_G_config.h: Define _G_MMAP64.
	* sysdeps/unix/sysv/linux/cris/_G_config.h: Likewise.

	* stdio-common/Makefile (tests): Add tst-rndseek.
	* stdio-common/tst-rndseek.c: New file.
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r--libio/wfileops.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 92d1a08190..35d201b939 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -143,7 +143,7 @@ _IO_wfile_underflow (fp)
   int tries;
   const char *read_ptr_copy;
 
-  if (fp->_flags & _IO_NO_READS)
+  if (__builtin_expect (fp->_flags & _IO_NO_READS, 0))
     {
       fp->_flags |= _IO_ERR_SEEN;
       __set_errno (EBADF);
@@ -161,10 +161,12 @@ _IO_wfile_underflow (fp)
       const char *read_stop = (const char *) fp->_IO_read_ptr;
 
       fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+      fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
+	fp->_wide_data->_IO_buf_base;
       status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
 				       fp->_IO_read_ptr, fp->_IO_read_end,
 				       &read_stop,
-				       fp->_wide_data->_IO_read_end,
+				       fp->_wide_data->_IO_read_ptr,
 				       fp->_wide_data->_IO_buf_end,
 				       &fp->_wide_data->_IO_read_end);
 
@@ -306,6 +308,67 @@ _IO_wfile_underflow (fp)
 }
 
 
+static wint_t
+_IO_wfile_underflow_mmap (_IO_FILE *fp)
+{
+  struct _IO_codecvt *cd;
+  enum __codecvt_result status;
+
+  if (__builtin_expect (fp->_flags & _IO_NO_READS, 0))
+    {
+      fp->_flags |= _IO_ERR_SEEN;
+      __set_errno (EBADF);
+      return WEOF;
+    }
+  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+    return *fp->_wide_data->_IO_read_ptr;
+
+  cd = fp->_codecvt;
+
+  /* Maybe there is something left in the external buffer.  */
+  if (fp->_IO_read_ptr < fp->_IO_read_end)
+    {
+      /* There is more in the external.  Convert it.  */
+      const char *read_stop = (const char *) fp->_IO_read_ptr;
+
+      if (fp->_wide_data->_IO_buf_base == NULL)
+	{
+	  /* Maybe we already have a push back pointer.  */
+	  if (fp->_wide_data->_IO_save_base != NULL)
+	    {
+	      free (fp->_wide_data->_IO_save_base);
+	      fp->_flags &= ~_IO_IN_BACKUP;
+	    }
+	  _IO_wdoallocbuf (fp);
+	}
+
+      fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+      fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
+	fp->_wide_data->_IO_buf_base;
+      status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
+				       fp->_IO_read_ptr, fp->_IO_read_end,
+				       &read_stop,
+				       fp->_wide_data->_IO_read_ptr,
+				       fp->_wide_data->_IO_buf_end,
+				       &fp->_wide_data->_IO_read_end);
+
+      fp->_IO_read_ptr = (char *) read_stop;
+
+      /* If we managed to generate some text return the next character.  */
+      if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+	return *fp->_wide_data->_IO_read_ptr;
+
+      /* There is some garbage at the end of the file.  */
+      __set_errno (EILSEQ);
+      fp->_flags |= _IO_ERR_SEEN;
+      return WEOF;
+    }
+
+  fp->_flags |= _IO_EOF_SEEN;
+  return WEOF;
+}
+
+
 wint_t
 _IO_wfile_overflow (f, wch)
      _IO_FILE *f;
@@ -789,3 +852,28 @@ struct _IO_jump_t _IO_wfile_jumps =
   JUMP_INIT(showmanyc, _IO_default_showmanyc),
   JUMP_INIT(imbue, _IO_default_imbue)
 };
+
+
+struct _IO_jump_t _IO_wfile_jumps_mmap =
+{
+  JUMP_INIT_DUMMY,
+  JUMP_INIT(finish, _IO_new_file_finish),
+  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
+  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+  JUMP_INIT(xsputn, _IO_wfile_xsputn),
+  JUMP_INIT(xsgetn, _IO_file_xsgetn),
+  JUMP_INIT(seekoff, _IO_wfile_seekoff),
+  JUMP_INIT(seekpos, _IO_default_seekpos),
+  JUMP_INIT(setbuf, _IO_new_file_setbuf),
+  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+  JUMP_INIT(doallocate, _IO_wfile_doallocate),
+  JUMP_INIT(read, _IO_file_read),
+  JUMP_INIT(write, _IO_new_file_write),
+  JUMP_INIT(seek, _IO_file_seek),
+  JUMP_INIT(close, _IO_file_close_mmap),
+  JUMP_INIT(stat, _IO_file_stat),
+  JUMP_INIT(showmanyc, _IO_default_showmanyc),
+  JUMP_INIT(imbue, _IO_default_imbue)
+};