Bash-4.2 distribution sources and documentation
[platform/upstream/bash.git] / lib / sh / fpurge.c
index f9e1b9d..13e8c78 100644 (file)
@@ -1,6 +1,6 @@
 /* fpurge - Flushing buffers of a FILE stream. */
 
-/* Copyright (C) 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2007-2010 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -36,6 +36,90 @@ extern int fpurge __P((FILE *stream));
 #endif
 #include <stdlib.h>
 
+/* Inline contents of gnulib:stdio-impl.h */
+
+/* Many stdio implementations have the same logic and therefore can share
+   the same implementation of stdio extension API, except that some fields
+   have different naming conventions, or their access requires some casts.  */
+
+/* BSD stdio derived implementations.  */
+
+#if defined __NetBSD__                         /* NetBSD */
+/* Get __NetBSD_Version__.  */
+# include <sys/param.h>
+#endif
+
+#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */
+
+# if defined __DragonFly__          /* DragonFly */
+  /* See <http://www.dragonflybsd.org/cvsweb/src/lib/libc/stdio/priv_stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>.  */
+#  define fp_ ((struct { struct __FILE_public pub; \
+                         struct { unsigned char *_base; int _size; } _bf; \
+                         void *cookie; \
+                         void *_close; \
+                         void *_read; \
+                         void *_seek; \
+                         void *_write; \
+                         struct { unsigned char *_base; int _size; } _ub; \
+                         int _ur; \
+                         unsigned char _ubuf[3]; \
+                         unsigned char _nbuf[1]; \
+                         struct { unsigned char *_base; int _size; } _lb; \
+                         int _blksize; \
+                         fpos_t _offset; \
+                         /* More fields, not relevant here.  */ \
+                       } *) fp)
+  /* See <http://www.dragonflybsd.org/cvsweb/src/include/stdio.h?rev=HEAD&content-type=text/x-cvsweb-markup>.  */
+#  define _p pub._p
+#  define _flags pub._flags
+#  define _r pub._r
+#  define _w pub._w
+# else
+#  define fp_ fp
+# endif
+
+# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ /* NetBSD >= 1.5ZA, OpenBSD */
+  /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
+     and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */
+  struct __sfileext
+    {
+      struct  __sbuf _ub; /* ungetc buffer */
+      /* More fields, not relevant here.  */
+    };
+#  define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
+# else                                         /* FreeBSD, NetBSD <= 1.5Z, DragonFly, MacOS X, Cygwin */
+#  define fp_ub fp_->_ub
+# endif
+
+# define HASUB(fp) (fp_ub._base != NULL)
+
+#endif
+
+/* SystemV derived implementations.  */
+
+#if defined _IOERR
+
+# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */
+#  define fp_ ((struct { unsigned char *_ptr; \
+                         unsigned char *_base; \
+                         unsigned char *_end; \
+                         long _cnt; \
+                         int _file; \
+                         unsigned int _flag; \
+                       } *) fp)
+# else
+#  define fp_ fp
+# endif
+
+# if defined _SCO_DS                /* OpenServer */
+#  define _cnt __cnt
+#  define _ptr __ptr
+#  define _base __base
+#  define _flag __flag
+# endif
+
+#endif
+
 int
 fpurge (FILE *fp)
 {
@@ -45,7 +129,7 @@ fpurge (FILE *fp)
   /* The __fpurge function does not have a return value.  */
   return 0;
 
-#elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */
+#elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin 1.7 */
 
   /* Call the system's fpurge function.  */
 # undef fpurge
@@ -59,10 +143,10 @@ fpurge (FILE *fp)
        <stdio.h> on BSD systems says:
          "The following always hold: if _flags & __SRD, _w is 0."
        If this invariant is not fulfilled and the stream is read-write but
-       currently writing, subsequent putc or fputc calls will write directly
+       currently reading, subsequent putc or fputc calls will write directly
        into the buffer, although they shouldn't be allowed to.  */
-    if ((fp->_flags & __SRD) != 0)
-      fp->_w = 0;
+    if ((fp_->_flags & __SRD) != 0)
+      fp_->_w = 0;
 # endif
   return result;
 
@@ -101,7 +185,7 @@ fpurge (FILE *fp)
   fp->_wcount = 0;
   fp->_ungetc_count = 0;
   return 0;
-# elif defined _IOERR               /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
+# elif defined _IOERR || defined __TANDEM    /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */
   fp->_ptr = fp->_base;
   if (fp->_ptr != NULL)
     fp->_cnt = 0;