]> sourceware.org Git - newlib-cygwin.git/commitdiff
2006-12-14 Jeff Johnston <jjohnstn@redhat.com>
authorJeff Johnston <jjohnstn@redhat.com>
Thu, 14 Dec 2006 22:47:12 +0000 (22:47 +0000)
committerJeff Johnston <jjohnstn@redhat.com>
Thu, 14 Dec 2006 22:47:12 +0000 (22:47 +0000)
            Eric Blake  <ebb9@byu.net>

        * libc/stdio/fflush.c (fflush): On seekable streams, always flush
        read but unused data.
        * libc/stdio/fclose.c (_fclose_r): Always flush streams, since
        even read streams may have side effects that must happen.

newlib/ChangeLog
newlib/libc/stdio/fclose.c
newlib/libc/stdio/fflush.c

index 4978e95cff865306204e65c09a057b1b235b3dd2..0a72707cc6baea6d21ec798f395890af5c50f9fa 100644 (file)
@@ -1,3 +1,11 @@
+2006-12-14  Jeff Johnston  <jjohnstn@redhat.com>
+            Eric Blake  <ebb9@byu.net>
+
+        * libc/stdio/fflush.c (fflush): On seekable streams, always flush
+        read but unused data.
+        * libc/stdio/fclose.c (_fclose_r): Always flush streams, since
+        even read streams may have side effects that must happen.
+
 2006-12-13  Joel Schopp <jschopp@austin.ibm.com>
 
         * libc/machine/spu/setjmp.S: Fix to handle registers past 115
index bb3acb624fde241a3f8484844c8209137f80c4f1..08df75fb4f9589fd623897de9bf686ec1322e288 100644 (file)
@@ -86,7 +86,10 @@ _DEFUN(_fclose_r, (rptr, fp),
       __sfp_lock_release ();
       return (0);
     }
-  r = fp->_flags & __SWR ? fflush (fp) : 0;
+  /* Unconditionally flush to allow special handling for seekable read
+     files to reposition file to last byte processed as opposed to
+     last byte read ahead into the buffer.  */
+  r = fflush (fp);
   if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
     r = EOF;
   if (fp->_flags & __SMBF)
index bac49804f69e0937c70f307108793bd9ccb29fa6..a8ef755c2776b8da4ea386360c1df74ce268c165 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1990 The Regents of the University of California.
+ * Copyright (c) 1990, 2006 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -74,10 +74,56 @@ _DEFUN(fflush, (fp),
   t = fp->_flags;
   if ((t & __SWR) == 0)
     {
+      _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int));
+
       /* For a read stream, an fflush causes the next seek to be
          unoptimized (i.e. forces a system-level seek).  This conforms
          to the POSIX and SUSv3 standards.  */
       fp->_flags |= __SNPT;
+
+      /* For a seekable stream with buffered read characters, we will attempt
+         a seek to the current position now.  A subsequent read will then get
+         the next byte from the file rather than the buffer.  This conforms
+         to the POSIX and SUSv3 standards.  Note that the standards allow
+         this seek to be deferred until necessary, but we choose to do it here
+         to make the change simpler, more contained, and less likely
+         to miss a code scenario.  */
+      if ((fp->_r > 0 || fp->_ur > 0) && (seekfn = fp->_seek) != NULL)
+        {
+          _fpos_t curoff;
+
+          /* Get the physical position we are at in the file.  */
+          if (fp->_flags & __SOFF)
+            curoff = fp->_offset;
+          else
+            {
+              /* We don't know current physical offset, so ask for it.  */
+              curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR);
+              if (curoff == -1L)
+                {
+                  _funlockfile (fp);
+                  return 0;
+                }
+            }
+          if (fp->_flags & __SRD)
+            {
+              /* Current offset is at end of buffer.  Compensate for
+                 characters not yet read.  */
+              curoff -= fp->_r;
+              if (HASUB (fp))
+                curoff -= fp->_ur;
+            }
+          /* Now physically seek to after byte last read.  */
+          if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) != -1)
+            {
+              /* Seek successful.  We can clear read buffer now.  */
+              fp->_flags &= ~__SNPT;
+              fp->_r = 0;
+              fp->_p = fp->_bf._base;
+              if (fp->_flags & __SOFF)
+                fp->_offset = curoff;
+            }
+        } 
       _funlockfile (fp);
       return 0;
     }
This page took 0.053581 seconds and 5 git commands to generate.