Update.
authorUlrich Drepper <drepper@redhat.com>
Sat, 19 Jan 2002 17:51:34 +0000 (17:51 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 19 Jan 2002 17:51:34 +0000 (17:51 +0000)
2002-01-19  Ulrich Drepper  <drepper@redhat.com>

* libio/fileops.c (_IO_file_underflow_mmap): Don't define as static.
Set offset if read end wasn't the buffer end.
(_IO_file_seekoff_mmap): New function.
(_IO_file_xsgetn_mmap): New function.
(_IO_file_jumps_mmap): Use the two new functions.
* libio/wfileops.c (_IO_wfile_underflow_mmap): Handle end read buffer
!= end buffer.
* libio/libioP.h: Declare _IO_file_seekoff_mmap and
_IO_file_underflow_mmap.
* libio/iofopen.c: Don't position file descriptor at end of file.
* libio/tst-widetext.c: Improve error messages.
* stdio-common/tst-rndseek.c: Likewise.

ChangeLog
libio/fileops.c
libio/iofopen.c
libio/libioP.h
libio/tst-widetext.c
libio/wfileops.c
stdio-common/tst-rndseek.c

index dacb3a4..793443f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2002-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+       * libio/fileops.c (_IO_file_underflow_mmap): Don't define as static.
+       Set offset if read end wasn't the buffer end.
+       (_IO_file_seekoff_mmap): New function.
+       (_IO_file_xsgetn_mmap): New function.
+       (_IO_file_jumps_mmap): Use the two new functions.
+       * libio/wfileops.c (_IO_wfile_underflow_mmap): Handle end read buffer
+       != end buffer.
+       * libio/libioP.h: Declare _IO_file_seekoff_mmap and
+       _IO_file_underflow_mmap.
+       * libio/iofopen.c: Don't position file descriptor at end of file.
+       * libio/tst-widetext.c: Improve error messages.
+       * stdio-common/tst-rndseek.c: Likewise.
+
 2002-01-18  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/unix/sysv/linux/bits/statvfs.h: Avoid warning about comma at
index 32fa524..60481b1 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997-2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997-2001, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Per Bothner <bothner@cygnus.com>.
 
@@ -33,6 +33,7 @@
 #include "libioP.h"
 #include <assert.h>
 #include <fcntl.h>
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string.h>
@@ -558,7 +559,7 @@ _IO_new_file_underflow (fp)
 
 /* Special callback replacing the underflow callbacks if we mmap the
    file.  */
-static int
+int
 _IO_file_underflow_mmap (_IO_FILE *fp)
 {
   if (fp->_IO_read_end < fp->_IO_buf_end)
@@ -576,6 +577,7 @@ _IO_file_underflow_mmap (_IO_FILE *fp)
          return EOF;
        }
 
+      fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
       fp->_IO_read_end = fp->_IO_buf_end;
       return *fp->_IO_read_ptr;
     }
@@ -857,6 +859,52 @@ resync:
   return offset;
 }
 
+_IO_off64_t
+_IO_file_seekoff_mmap (fp, offset, dir, mode)
+     _IO_FILE *fp;
+     _IO_off64_t offset;
+     int dir;
+     int mode;
+{
+  _IO_off64_t result;
+
+  if (mode == 0)
+    dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+
+  switch (dir)
+    {
+    case _IO_seek_cur:
+      /* Adjust for read-ahead (bytes is buffer). */
+      offset += fp->_IO_read_ptr - fp->_IO_read_base;
+      break;
+    case _IO_seek_set:
+      break;
+    case _IO_seek_end:
+      offset = fp->_IO_read_end - fp->_IO_read_base + offset;
+      break;
+    }
+  /* At this point, dir==_IO_seek_set. */
+
+  if (offset < 0)
+    /* No negative offsets are valid.  */
+    return EOF;
+
+  /* If we are only interested in the current position we've found it now.  */
+  if (mode == 0)
+    return offset;
+
+  result = _IO_SYSSEEK (fp, offset, 0);
+  if (result < 0)
+    return EOF;
+
+  _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
+           fp->_IO_buf_base + offset);
+
+  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+
+  return offset;
+}
+
 _IO_ssize_t
 _IO_file_read (fp, buf, size)
      _IO_FILE *fp;
@@ -1122,6 +1170,39 @@ _IO_file_xsgetn (fp, data, n)
   return n - want;
 }
 
+static _IO_size_t _IO_file_xsgetn_mmap __P ((_IO_FILE *, void *, _IO_size_t));
+static _IO_size_t
+_IO_file_xsgetn_mmap (fp, data, n)
+     _IO_FILE *fp;
+     void *data;
+     _IO_size_t n;
+{
+  register _IO_size_t have;
+  char *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;
+  else
+    {
+      have = MIN (have, n);
+      memcpy (data, read_ptr, have);
+      fp->_IO_read_ptr = read_ptr + have;
+    }
+
+  return have;
+}
+
 struct _IO_jump_t _IO_file_jumps =
 {
   JUMP_INIT_DUMMY,
@@ -1155,8 +1236,8 @@ struct _IO_jump_t _IO_file_jumps_mmap =
   JUMP_INIT(uflow, _IO_default_uflow),
   JUMP_INIT(pbackfail, _IO_default_pbackfail),
   JUMP_INIT(xsputn, _IO_new_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn),
-  JUMP_INIT(seekoff, _IO_new_file_seekoff),
+  JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
+  JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
   JUMP_INIT(seekpos, _IO_default_seekpos),
   JUMP_INIT(setbuf, _IO_new_file_setbuf),
   JUMP_INIT(sync, _IO_new_file_sync),
index e4821cb..e3b9838 100644 (file)
@@ -67,25 +67,12 @@ __fopen_maybe_mmap (fp)
 # endif
          if (p != MAP_FAILED)
            {
-             if (
-# ifdef _G_LSEEK64
-                 _G_LSEEK64 (fp->_fileno, st.st_size, SEEK_SET)
-# else
-                 __lseek (fp->_fileno, st.st_size, SEEK_SET)
-# endif
-                 != st.st_size)
-               {
-                 /* We cannot search the file.  Don't mmap then.  */
-                 __munmap (p, st.st_size);
-                 return fp;
-               }
-
              /* 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.  */
              _IO_setb (fp, p, (char *) p + st.st_size, 0);
-             _IO_setg (fp, p, p, (char *) p + st.st_size);
+             _IO_setg (fp, p, p, p);
 
              if (fp->_mode <= 0)
                _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
@@ -93,7 +80,7 @@ __fopen_maybe_mmap (fp)
                _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_mmap;
              fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
 
-             fp->_offset = st.st_size;
+             fp->_offset = 0;
            }
        }
     }
index f9f44cc..e25a6e7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997-2001, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -486,12 +486,15 @@ extern int _IO_old_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *));
 extern int _IO_file_doallocate __P ((_IO_FILE *));
 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_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 *));
 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_overflow __P ((_IO_FILE *, int));
 #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1)
 extern void _IO_file_init __P ((struct _IO_FILE_plus *));
index 3842403..7a98f64 100644 (file)
@@ -1,6 +1,6 @@
 /* Test program for the wide character stream functions handling larger
    amounts of text.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>.
 
@@ -212,7 +212,7 @@ main (void)
       /* Make sure there is nothing left.  */
       if (fgetc (fp) != EOF)
        {
-         printf ("%Zd: more input avilable", __LINE__);
+         printf ("%Zd: more input available\n", __LINE__);
          status = 1;
        }
 
@@ -347,7 +347,7 @@ main (void)
       /* Make sure there is nothing left.  */
       if (fgetc (fp) != EOF)
        {
-         printf ("%Zd: more input avilable", __LINE__);
+         printf ("%Zd: more input available\n", __LINE__);
          status = 1;
        }
 
index 35d201b..54624f0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993,95,97,98,99,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1993,95,97,98,99,2000,2001,2002 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@cygnus.com>.
    Based on the single byte version by Per Bothner <bothner@cygnus.com>.
@@ -313,6 +313,7 @@ _IO_wfile_underflow_mmap (_IO_FILE *fp)
 {
   struct _IO_codecvt *cd;
   enum __codecvt_result status;
+  const char *read_stop;
 
   if (__builtin_expect (fp->_flags & _IO_NO_READS, 0))
     {
@@ -326,45 +327,48 @@ _IO_wfile_underflow_mmap (_IO_FILE *fp)
   cd = fp->_codecvt;
 
   /* Maybe there is something left in the external buffer.  */
-  if (fp->_IO_read_ptr < fp->_IO_read_end)
+  if (fp->_IO_read_ptr >= fp->_IO_read_end
+      /* No.  But maybe the read buffer is not fully set up.  */
+      && _IO_file_underflow_mmap (fp) == EOF)
     {
-      /* There is more in the external.  Convert it.  */
-      const char *read_stop = (const char *) fp->_IO_read_ptr;
+      /* Nothing available.  */
+      fp->_flags |= _IO_EOF_SEEN;
+      return WEOF;
+    }
+
+  /* There is more in the external.  Convert it.  */
+  read_stop = (const char *) fp->_IO_read_ptr;
 
-      if (fp->_wide_data->_IO_buf_base == NULL)
+  if (fp->_wide_data->_IO_buf_base == NULL)
+    {
+      /* Maybe we already have a push back pointer.  */
+      if (fp->_wide_data->_IO_save_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);
+         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;
+  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);
 
-      /* 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;
+  fp->_IO_read_ptr = (char *) read_stop;
 
-      /* There is some garbage at the end of the file.  */
-      __set_errno (EILSEQ);
-      fp->_flags |= _IO_ERR_SEEN;
-      return WEOF;
-    }
+  /* 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;
 
-  fp->_flags |= _IO_EOF_SEEN;
+  /* There is some garbage at the end of the file.  */
+  __set_errno (EILSEQ);
+  fp->_flags |= _IO_ERR_SEEN;
   return WEOF;
 }
 
index 82a4cfd..41d99e4 100644 (file)
@@ -15,7 +15,7 @@ static int do_test (void);
 
 
 static int
-fp_test (FILE *fp)
+fp_test (const char *name, FILE *fp)
 {
   int result = 0;
   int rounds = 10000;
@@ -28,7 +28,7 @@ fp_test (FILE *fp)
 
       if (fseek (fp, idx, SEEK_SET) != 0)
        {
-         printf ("%d: fseek failed: %m\n", rounds);
+         printf ("%s: %d: fseek failed: %m\n", name, rounds);
          result = 1;
          break;
        }
@@ -37,8 +37,8 @@ fp_test (FILE *fp)
       ch2 = tempdata[idx];
       if (ch1 != ch2)
        {
-         printf ("%d: character at index %d not what is expected ('%c' vs '%c')\n",
-                 rounds, idx, ch1, ch2);
+         printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n",
+                 name, rounds, idx, ch1, ch2);
          result = 1;
          break;
        }
@@ -47,8 +47,8 @@ fp_test (FILE *fp)
       ch2 = tempdata[idx + 1];
       if (ch1 != ch2)
        {
-         printf ("%d: character at index %d not what is expected ('%c' vs '%c')\n",
-                 rounds, idx + 1, ch1, ch2);
+         printf ("%s: %d: character at index %d not what is expected ('%c' vs '%c')\n",
+                 name, rounds, idx + 1, ch1, ch2);
          result = 1;
          break;
        }
@@ -83,7 +83,7 @@ do_test (void)
 
   /* First create some temporary data.  */
   for (i = 0; i < sizeof (tempdata); ++i)
-    tempdata[i] = (char) random ();
+    tempdata[i] = 'a' + random () % 26;
 
   /* Write this data to a file.  */
   if (TEMP_FAILURE_RETRY (write (fd, tempdata, sizeof (tempdata)))
@@ -121,23 +121,23 @@ do_test (void)
        }
     }
 
-  result = fp_test (fp);
+  result = fp_test ("fdopen(\"r\")", fp);
 
   fp = fopen (fname, "r");
-  result |= fp_test (fp);
+  result |= fp_test ("fopen(\"r\")", fp);
 
   fp = fopen64 (fname, "r");
-  result |= fp_test (fp);
+  result |= fp_test ("fopen64(\"r\")", fp);
 
   /* The "rw" mode will prevent the mmap-using code from being used.  */
   fp = fdopen (fd, "rw");
-  result = fp_test (fp);
+  result = fp_test ("fdopen(\"rw\")", fp);
 
   fp = fopen (fname, "rw");
-  result |= fp_test (fp);
+  result |= fp_test ("fopen(\"rw\")", fp);
 
   fp = fopen64 (fname, "rw");
-  result |= fp_test (fp);
+  result |= fp_test ("fopen64(\"rw\")", fp);
 
   return result;
 }