1 /* Implementation details of FILE streams. 2 Copyright (C) 2007-2008, 2010-2020 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16 17 /* Many stdio implementations have the same logic and therefore can share 18 the same implementation of stdio extension API, except that some fields 19 have different naming conventions, or their access requires some casts. */ 20 21 /* Glibc 2.28 made _IO_UNBUFFERED and _IO_IN_BACKUP private. For now, work 22 around this problem by defining them ourselves. FIXME: Do not rely on glibc 23 internals. */ 24 #if defined _IO_EOF_SEEN 25 # if !defined _IO_UNBUFFERED 26 # define _IO_UNBUFFERED 0x2 27 # endif 28 # if !defined _IO_IN_BACKUP 29 # define _IO_IN_BACKUP 0x100 30 # endif 31 #endif 32 33 /* BSD stdio derived implementations. */ 34 35 #if defined __NetBSD__ /* NetBSD */ 36 /* Get __NetBSD_Version__. */ 37 # include <sys/param.h> 38 #endif 39 40 #include <errno.h> /* For detecting Plan9. */ 41 42 #if defined __sferror || defined __DragonFly__ || defined __ANDROID__ 43 /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */ 44 45 # if defined __DragonFly__ /* DragonFly */ 46 /* See <https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/lib/libc/stdio/priv_stdio.h>. */ 47 # define fp_ ((struct { struct __FILE_public pub; \ 48 struct { unsigned char *_base; int _size; } _bf; \ 49 void *cookie; \ 50 void *_close; \ 51 void *_read; \ 52 void *_seek; \ 53 void *_write; \ 54 struct { unsigned char *_base; int _size; } _ub; \ 55 int _ur; \ 56 unsigned char _ubuf[3]; \ 57 unsigned char _nbuf[1]; \ 58 struct { unsigned char *_base; int _size; } _lb; \ 59 int _blksize; \ 60 fpos_t _offset; \ 61 /* More fields, not relevant here. */ \ 62 } *) fp) 63 /* See <https://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/include/stdio.h>. */ 64 # define _p pub._p 65 # define _flags pub._flags 66 # define _r pub._r 67 # define _w pub._w 68 # elif defined __ANDROID__ /* Android */ 69 # ifdef __LP64__ 70 # define _gl_flags_file_t int 71 # else 72 # define _gl_flags_file_t short 73 # endif 74 /* Up to this commit from 2015-10-12 75 <https://android.googlesource.com/platform/bionic.git/+/f0141dfab10a4b332769d52fa76631a64741297a> 76 the innards of FILE were public, and fp_ub could be defined like for OpenBSD, 77 see <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/fileext.h> 78 and <https://android.googlesource.com/platform/bionic.git/+/e78392637d5086384a5631ddfdfa8d7ec8326ee3/libc/stdio/local.h>. 79 After this commit, the innards of FILE are hidden. */ 80 # define fp_ ((struct { unsigned char *_p; \ 81 int _r; \ 82 int _w; \ 83 _gl_flags_file_t _flags; \ 84 _gl_flags_file_t _file; \ 85 struct { unsigned char *_base; size_t _size; } _bf; \ 86 int _lbfsize; \ 87 void *_cookie; \ 88 void *_close; \ 89 void *_read; \ 90 void *_seek; \ 91 void *_write; \ 92 struct { unsigned char *_base; size_t _size; } _ext; \ 93 unsigned char *_up; \ 94 int _ur; \ 95 unsigned char _ubuf[3]; \ 96 unsigned char _nbuf[1]; \ 97 struct { unsigned char *_base; size_t _size; } _lb; \ 98 int _blksize; \ 99 fpos_t _offset; \ 100 /* More fields, not relevant here. */ \ 101 } *) fp) 102 # else 103 # define fp_ fp 104 # endif 105 106 # if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ || defined __minix /* NetBSD >= 1.5ZA, OpenBSD, Minix 3 */ 107 /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> 108 and <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> 109 and <https://github.com/Stichting-MINIX-Research-Foundation/minix/blob/master/lib/libc/stdio/fileext.h> */ 110 struct __sfileext 111 { 112 struct __sbuf _ub; /* ungetc buffer */ 113 /* More fields, not relevant here. */ 114 }; 115 # define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub 116 # elif defined __ANDROID__ /* Android */ 117 struct __sfileext 118 { 119 struct { unsigned char *_base; size_t _size; } _ub; /* ungetc buffer */ 120 /* More fields, not relevant here. */ 121 }; 122 # define fp_ub ((struct __sfileext *) fp_->_ext._base)->_ub 123 # else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, Mac OS X, Cygwin */ 124 # define fp_ub fp_->_ub 125 # endif 126 127 # define HASUB(fp) (fp_ub._base != NULL) 128 129 # if defined __ANDROID__ /* Android */ 130 /* Needed after this commit from 2016-01-25 131 <https://android.googlesource.com/platform/bionic.git/+/e70e0e9267d069bf56a5078c99307e08a7280de7> */ 132 # ifndef __SEOF 133 # define __SLBF 1 134 # define __SNBF 2 135 # define __SRD 4 136 # define __SWR 8 137 # define __SRW 0x10 138 # define __SEOF 0x20 139 # define __SERR 0x40 140 # endif 141 # ifndef __SOFF 142 # define __SOFF 0x1000 143 # endif 144 # endif 145 146 #endif 147 148 149 /* SystemV derived implementations. */ 150 151 #ifdef __TANDEM /* NonStop Kernel */ 152 # ifndef _IOERR 153 /* These values were determined by the program 'stdioext-flags' at 154 <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>. */ 155 # define _IOERR 0x40 156 # define _IOREAD 0x80 157 # define _IOWRT 0x4 158 # define _IORW 0x100 159 # endif 160 #endif 161 162 #if defined _IOERR 163 164 # if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ 165 # define fp_ ((struct { unsigned char *_ptr; \ 166 unsigned char *_base; \ 167 unsigned char *_end; \ 168 long _cnt; \ 169 int _file; \ 170 unsigned int _flag; \ 171 } *) fp) 172 # elif defined __VMS /* OpenVMS */ 173 # define fp_ ((struct _iobuf *) fp) 174 # else 175 # define fp_ fp 176 # endif 177 178 # if defined _SCO_DS /* OpenServer */ 179 # define _cnt __cnt 180 # define _ptr __ptr 181 # define _base __base 182 # define _flag __flag 183 # endif 184 185 #elif defined _WIN32 && ! defined __CYGWIN__ /* newer Windows with MSVC */ 186 187 /* <stdio.h> does not define the innards of FILE any more. */ 188 # define WINDOWS_OPAQUE_FILE 189 190 struct _gl_real_FILE 191 { 192 /* Note: Compared to older Windows and to mingw, it has the fields 193 _base and _cnt swapped. */ 194 unsigned char *_ptr; 195 unsigned char *_base; 196 int _cnt; 197 int _flag; 198 int _file; 199 int _charbuf; 200 int _bufsiz; 201 }; 202 # define fp_ ((struct _gl_real_FILE *) fp) 203 204 /* These values were determined by a program similar to the one at 205 <https://lists.gnu.org/r/bug-gnulib/2010-12/msg00165.html>. */ 206 # define _IOREAD 0x1 207 # define _IOWRT 0x2 208 # define _IORW 0x4 209 # define _IOEOF 0x8 210 # define _IOERR 0x10 211 212 #endif 213