about summary refs log tree commit diff
path: root/libio
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-02-26 05:23:31 +0000
committerUlrich Drepper <drepper@redhat.com>2002-02-26 05:23:31 +0000
commitb39d571990557cc5ab855794ff0d4d7876f4596b (patch)
treef5f6918e0520a86a5576cc393c39fabb1cb4e0eb /libio
parent77fe0b9cd86ccba7349921082d886cbca613404c (diff)
downloadglibc-b39d571990557cc5ab855794ff0d4d7876f4596b.tar.gz
glibc-b39d571990557cc5ab855794ff0d4d7876f4596b.tar.xz
glibc-b39d571990557cc5ab855794ff0d4d7876f4596b.zip
Update.
2002-02-25  Jakub Jelinek  <jakub@redhat.com>

	* libio/iofopen.c (__fopen_maybe_mmap): Set the initial
	position to fp->_offset if it is set.
	* stdio-common/Makefile (tests): Add tst-fdopen.
	* stdio-common/tst-fdopen.c: New test.

2002-02-25  Jakub Jelinek  <jakub@redhat.com>

	* libio/fileops.c (_IO_file_xsgetn_mmap): Handle reading from backup.
	* stdio-common/tst-ungetc.c (main): Add another test.
Diffstat (limited to 'libio')
-rw-r--r--libio/fileops.c42
-rw-r--r--libio/iofopen.c12
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;
 	    }
 	}
     }