stdio-impl.h 7.68 KB
Newer Older
Paul Eggert's avatar
Paul Eggert committed
1
/* Implementation details of FILE streams.
Paul Eggert's avatar
Paul Eggert committed
2
   Copyright (C) 2007-2008, 2010-2019 Free Software Foundation, Inc.
Paul Eggert's avatar
Paul Eggert committed
3 4 5 6 7 8 9 10 11 12 13 14

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
Paul Eggert's avatar
Paul Eggert committed
15
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Paul Eggert's avatar
Paul Eggert committed
16 17 18 19 20

/* 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.  */

Paul Eggert's avatar
Paul Eggert committed
21 22 23 24 25 26
/* Glibc 2.28 made _IO_IN_BACKUP private.  For now, work around this
   problem by defining it ourselves.  FIXME: Do not rely on glibc
   internals.  */
#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
# define _IO_IN_BACKUP 0x100
#endif
Paul Eggert's avatar
Paul Eggert committed
27 28 29 30 31 32 33 34 35 36 37

/* BSD stdio derived implementations.  */

#if defined __NetBSD__                         /* NetBSD */
/* Get __NetBSD_Version__.  */
# include <sys/param.h>
#endif

#include <errno.h>                             /* For detecting Plan9.  */

#if defined __sferror || defined __DragonFly__ || defined __ANDROID__
Paul Eggert's avatar
Paul Eggert committed
38
  /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
Paul Eggert's avatar
Paul Eggert committed
39 40

# if defined __DragonFly__          /* DragonFly */
Paul Eggert's avatar
Paul Eggert committed
41
  /* See <https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/lib/libc/stdio/priv_stdio.h>.  */
Paul Eggert's avatar
Paul Eggert committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#  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)
Paul Eggert's avatar
Paul Eggert committed
58
  /* See <https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/include/stdio.h>.  */
Paul Eggert's avatar
Paul Eggert committed
59 60 61 62
#  define _p pub._p
#  define _flags pub._flags
#  define _r pub._r
#  define _w pub._w
Paul Eggert's avatar
Paul Eggert committed
63
# elif defined __ANDROID__ /* Android */
Paul Eggert's avatar
Paul Eggert committed
64 65 66 67 68
#  ifdef __LP64__
#   define _gl_flags_file_t int
#  else
#   define _gl_flags_file_t short
#  endif
Paul Eggert's avatar
Paul Eggert committed
69 70 71 72 73 74 75 76 77
  /* Up to this commit from 2015-10-12
     <https://android.googlesource.com/platform/bionic.git/+/f0141dfab10a4b332769d52fa76631a64741297a>
     the innards of FILE were public, and fp_ub could be defined like for OpenBSD,
     see <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/fileext.h>
     and <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/local.h>.
     After this commit, the innards of FILE are hidden.  */
#  define fp_ ((struct { unsigned char *_p; \
                         int _r; \
                         int _w; \
Paul Eggert's avatar
Paul Eggert committed
78 79
                         _gl_flags_file_t _flags; \
                         _gl_flags_file_t _file; \
Paul Eggert's avatar
Paul Eggert committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
                         struct { unsigned char *_base; size_t _size; } _bf; \
                         int _lbfsize; \
                         void *_cookie; \
                         void *_close; \
                         void *_read; \
                         void *_seek; \
                         void *_write; \
                         struct { unsigned char *_base; size_t _size; } _ext; \
                         unsigned char *_up; \
                         int _ur; \
                         unsigned char _ubuf[3]; \
                         unsigned char _nbuf[1]; \
                         struct { unsigned char *_base; size_t _size; } _lb; \
                         int _blksize; \
                         fpos_t _offset; \
                         /* More fields, not relevant here.  */ \
                       } *) fp)
Paul Eggert's avatar
Paul Eggert committed
97 98 99 100
# else
#  define fp_ fp
# endif

Paul Eggert's avatar
Paul Eggert committed
101
# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */
Paul Eggert's avatar
Paul Eggert committed
102
  /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
Paul Eggert's avatar
Paul Eggert committed
103 104
     and <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
     and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */
Paul Eggert's avatar
Paul Eggert committed
105 106 107 108 109 110
  struct __sfileext
    {
      struct  __sbuf _ub; /* ungetc buffer */
      /* More fields, not relevant here.  */
    };
#  define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub
Paul Eggert's avatar
Paul Eggert committed
111 112 113 114 115 116 117 118
# elif defined __ANDROID__                     /* Android */
  struct __sfileext
    {
      struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */
      /* More fields, not relevant here.  */
    };
#  define fp_ub ((struct __sfileext *) fp_->_ext._base)->_ub
# else                                         /* FreeBSD, NetBSD <= 1.5Z, DragonFly, Mac OS X, Cygwin */
Paul Eggert's avatar
Paul Eggert committed
119 120 121 122 123
#  define fp_ub fp_->_ub
# endif

# define HASUB(fp) (fp_ub._base != NULL)

Paul Eggert's avatar
Paul Eggert committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
# if defined __ANDROID__ /* Android */
  /* Needed after this commit from 2016-01-25
     <https://android.googlesource.com/platform/bionic.git/+/e70e0e9267d069bf56a5078c99307e08a7280de7> */
#  ifndef __SEOF
#   define __SLBF 1
#   define __SNBF 2
#   define __SRD 4
#   define __SWR 8
#   define __SRW 0x10
#   define __SEOF 0x20
#   define __SERR 0x40
#  endif
#  ifndef __SOFF
#   define __SOFF 0x1000
#  endif
# endif

Paul Eggert's avatar
Paul Eggert committed
141 142 143 144 145 146 147 148
#endif


/* SystemV derived implementations.  */

#ifdef __TANDEM                     /* NonStop Kernel */
# ifndef _IOERR
/* These values were determined by the program 'stdioext-flags' at
Paul Eggert's avatar
Paul Eggert committed
149
   <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>.  */
Paul Eggert's avatar
Paul Eggert committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
#  define _IOERR   0x40
#  define _IOREAD  0x80
#  define _IOWRT    0x4
#  define _IORW   0x100
# endif
#endif

#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)
Paul Eggert's avatar
Paul Eggert committed
167 168
# elif defined __VMS                /* OpenVMS */
#  define fp_ ((struct _iobuf *) fp)
Paul Eggert's avatar
Paul Eggert committed
169 170 171 172 173 174 175 176 177 178 179
# else
#  define fp_ fp
# endif

# if defined _SCO_DS                /* OpenServer */
#  define _cnt __cnt
#  define _ptr __ptr
#  define _base __base
#  define _flag __flag
# endif

Paul Eggert's avatar
Paul Eggert committed
180
#elif defined _WIN32 && ! defined __CYGWIN__  /* newer Windows with MSVC */
Paul Eggert's avatar
Paul Eggert committed
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

/* <stdio.h> does not define the innards of FILE any more.  */
# define WINDOWS_OPAQUE_FILE

struct _gl_real_FILE
{
  /* Note: Compared to older Windows and to mingw, it has the fields
     _base and _cnt swapped. */
  unsigned char *_ptr;
  unsigned char *_base;
  int _cnt;
  int _flag;
  int _file;
  int _charbuf;
  int _bufsiz;
};
# define fp_ ((struct _gl_real_FILE *) fp)

/* These values were determined by a program similar to the one at
Paul Eggert's avatar
Paul Eggert committed
200
   <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>.  */
Paul Eggert's avatar
Paul Eggert committed
201 202 203 204 205 206 207
# define _IOREAD   0x1
# define _IOWRT    0x2
# define _IORW     0x4
# define _IOEOF    0x8
# define _IOERR   0x10

#endif