Author: pfg
Date: Sun Jul 20 20:05:39 2014
New Revision: 268924
URL: http://svnweb.freebsd.org/changeset/base/268924

Log:
  Update fflush(3) to return success on a read-only stream.
  
  This has small changes to what Apple uses for compliance
  with SUSv3. The changes cause no secondary effects in the
  gnulib tests (we pass them).
  
  Obtained from:        Apple Inc. (Libc 997.90.3 with changes)
  Reviewed by:  bde
  Phabric:      D440

Modified:
  head/lib/libc/stdio/fflush.c

Modified: head/lib/libc/stdio/fflush.c
==============================================================================
--- head/lib/libc/stdio/fflush.c        Sun Jul 20 18:44:56 2014        
(r268923)
+++ head/lib/libc/stdio/fflush.c        Sun Jul 20 20:05:39 2014        
(r268924)
@@ -60,7 +60,7 @@ fflush(FILE *fp)
 
        /*
         * There is disagreement about the correct behaviour of fflush()
-        * when passed a file which is not open for reading.  According to
+        * when passed a file which is not open for writing.  According to
         * the ISO C standard, the behaviour is undefined.
         * Under linux, such an fflush returns success and has no effect;
         * under Windows, such an fflush is documented as behaving instead
@@ -68,11 +68,13 @@ fflush(FILE *fp)
         * Given that applications may be written with the expectation of
         * either of these two behaviours, the only safe (non-astonishing)
         * option is to return EBADF and ask that applications be fixed.
+        * SUSv3 now requires that fflush() returns success on a read-only
+        * stream.
+        *
         */
-       if ((fp->_flags & (__SWR | __SRW)) == 0) {
-               errno = EBADF;
-               retval = EOF;
-       } else
+       if ((fp->_flags & (__SWR | __SRW)) == 0)
+               retval = 0;
+       else
                retval = __sflush(fp);
        FUNLOCKFILE(fp);
        return (retval);
@@ -89,10 +91,9 @@ __fflush(FILE *fp)
 
        if (fp == NULL)
                return (_fwalk(sflush_locked));
-       if ((fp->_flags & (__SWR | __SRW)) == 0) {
-               errno = EBADF;
-               retval = EOF;
-       } else
+       if ((fp->_flags & (__SWR | __SRW)) == 0)
+               retval = 0;
+       else
                retval = __sflush(fp);
        return (retval);
 }
@@ -122,6 +123,12 @@ __sflush(FILE *fp)
        for (; n > 0; n -= t, p += t) {
                t = _swrite(fp, (char *)p, n);
                if (t <= 0) {
+                       /* Reset _p and _w. */
+                       if (p > fp->_p) /* Some was written. */
+                               memmove(fp->_p, p, n);
+                       fp->_p += n;
+                       if ((fp->_flags & (__SLBF | __SNBF)) == 0)
+                               fp->_w -= n;
                        fp->_flags |= __SERR;
                        return (EOF);
                }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to