stdio patch

Jeff Johnston jjohnstn@redhat.com
Thu Dec 14 23:31:00 GMT 2006


Great.  Patch checked in.

-- Jeff J.

Eric Blake wrote:
> Jeff, this patch is based on what you sent me privately, plus a typo fix for 
> SEEK_SET instead of SEEK_CUR, and the additional fix to keep fp->offset up-to-
> date when __SOFF.  With it, I now get the POSIX-mandated behavior on cygwin for:
> 
> $ echo 1 2 3 | tr ' ' '\n' > file
> $ (sed -n 1q; cat) < file
> 2
> 3
> 
> 
> 2006-12-14  Jeff Johnston  <jjohnstn@redhat.com>
>         and 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.
> 
> Index: libc/stdio/fclose.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/fclose.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 fclose.c
> --- libc/stdio/fclose.c 26 Sep 2006 21:22:19 -0000      1.11
> +++ libc/stdio/fclose.c 14 Dec 2006 21:22:44 -0000
> @@ -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: libc/stdio/fflush.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/fflush.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 fflush.c
> --- libc/stdio/fflush.c 26 Sep 2006 21:22:19 -0000      1.7
> +++ libc/stdio/fflush.c 14 Dec 2006 21:22:44 -0000
> @@ -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;
>      }
> 
> 



More information about the Newlib mailing list