1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Copyright 2020 Robert Mustacchi 32 */ 33 34 /* 35 * stdiom.h - shared guts of stdio 36 */ 37 38 #ifndef _STDIOM_H 39 #define _STDIOM_H 40 41 #include <thread.h> 42 #include <synch.h> 43 #include <mtlib.h> 44 #include <stdarg.h> 45 #include "file64.h" 46 #include <wchar.h> 47 #include "mse.h" 48 49 50 /* 51 * The following flags, and the macros that manipulate them, operate upon 52 * the FILE structure used by stdio. If new flags are required, they should 53 * be created in this file. The values of the flags must be different from 54 * the currently used values. New macros should be created to use the flags 55 * so that the compilation mode dependencies can be isolated here. 56 */ 57 58 /* 59 * The 32-bit version of the stdio FILE has 8 bits for its flags (see 60 * lib/libc/port/stdio/README.design). These 8 bits are used to determine if the 61 * FILE structure is allocated. We define '_DEF_FLAG_MASK' as a means to 62 * indicate this. 63 */ 64 #define _DEF_FLAG_MASK 0377 65 #ifdef _LP64 66 #define _BYTE_MODE_FLAG 0400 67 #define _WC_MODE_FLAG 01000 68 #define _IONOLOCK 02000 69 #define _SEEKABLE 04000 /* is it seekable? */ 70 #define SET_IONOLOCK(iop) ((iop)->_flag |= _IONOLOCK) 71 #define CLEAR_IONOLOCK(iop) ((iop)->_flag &= ~_IONOLOCK) 72 #define GET_IONOLOCK(iop) ((iop)->_flag & _IONOLOCK) 73 #define SET_BYTE_MODE(iop) ((iop)->_flag |= _BYTE_MODE_FLAG) 74 #define CLEAR_BYTE_MODE(iop) ((iop)->_flag &= ~_BYTE_MODE_FLAG) 75 #define GET_BYTE_MODE(iop) ((iop)->_flag & _BYTE_MODE_FLAG) 76 #define SET_WC_MODE(iop) ((iop)->_flag |= _WC_MODE_FLAG) 77 #define CLEAR_WC_MODE(iop) ((iop)->_flag &= ~_WC_MODE_FLAG) 78 #define GET_WC_MODE(iop) ((iop)->_flag & _WC_MODE_FLAG) 79 #define GET_NO_MODE(iop) (!((iop)->_flag & \ 80 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 81 #define SET_SEEKABLE(iop) ((iop)->_flag |= _SEEKABLE) 82 #define CLEAR_SEEKABLE(iop) ((iop)->_flag &= ~_SEEKABLE) 83 #define GET_SEEKABLE(iop) ((iop)->_flag & _SEEKABLE) 84 #else 85 #define _BYTE_MODE_FLAG 0001 86 #define _WC_MODE_FLAG 0002 87 #define SET_IONOLOCK(iop) ((iop)->__ionolock = 1) 88 #define CLEAR_IONOLOCK(iop) ((iop)->__ionolock = 0) 89 #define GET_IONOLOCK(iop) ((iop)->__ionolock) 90 #define SET_BYTE_MODE(iop) ((iop)->__orientation |= _BYTE_MODE_FLAG) 91 #define CLEAR_BYTE_MODE(iop) ((iop)->__orientation &= ~_BYTE_MODE_FLAG) 92 #define GET_BYTE_MODE(iop) ((iop)->__orientation & _BYTE_MODE_FLAG) 93 #define SET_WC_MODE(iop) ((iop)->__orientation |= _WC_MODE_FLAG) 94 #define CLEAR_WC_MODE(iop) ((iop)->__orientation &= ~_WC_MODE_FLAG) 95 #define GET_WC_MODE(iop) ((iop)->__orientation & _WC_MODE_FLAG) 96 #define GET_NO_MODE(iop) (!((iop)->__orientation & \ 97 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 98 #define SET_SEEKABLE(iop) ((iop)->__seekable = 1) 99 #define CLEAR_SEEKABLE(iop) ((iop)->__seekable = 0) 100 #define GET_SEEKABLE(iop) ((iop)->__seekable) 101 102 /* Is iop a member of the _iob array? */ 103 #define STDIOP(iop) ((iop) >= &_iob[0] && (iop) < &_iob[_NFILE]) 104 105 /* Compute the index of an _iob array member */ 106 #define IOPIND(iop) ((iop) - &_iob[0]) 107 108 #endif 109 110 typedef unsigned char Uchar; 111 112 #define _flockrel(rl) cancel_safe_mutex_unlock(rl) 113 114 #define MAXVAL (MAXINT - (MAXINT % BUFSIZ)) 115 116 /* 117 * The number of actual pushback characters is the value 118 * of PUSHBACK plus the first byte of the buffer. The FILE buffer must, 119 * for performance reasons, start on a word aligned boundry so the value 120 * of PUSHBACK should be a multiple of word. 121 * At least 4 bytes of PUSHBACK are needed. If sizeof (int) = 1 this breaks. 122 */ 123 #define PUSHBACK (((3 + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 124 125 /* minimum buffer size must be at least 8 or shared library will break */ 126 #define _SMBFSZ (((PUSHBACK + 4) < 8) ? 8 : (PUSHBACK + 4)) 127 128 #if BUFSIZ == 1024 129 #define MULTIBFSZ(SZ) ((SZ) & ~0x3ff) 130 #elif BUFSIZ == 512 131 #define MULTIBFSZ(SZ) ((SZ) & ~0x1ff) 132 #else 133 #define MULTIBFSZ(SZ) ((SZ) - (SZ % BUFSIZ)) 134 #endif 135 136 #undef _bufend 137 #define _bufend(iop) _realbufend(iop) 138 139 /* 140 * Internal data 141 */ 142 extern Uchar _smbuf[][_SMBFSZ]; 143 144 145 /* 146 * Internal routines from flush.c 147 */ 148 extern void __cleanup(void); 149 extern void _flushlbf(void); 150 extern FILE *_findiop(void); 151 152 /* 153 * this is to be found in <stdio.h> for 32bit mode 154 */ 155 #ifdef _LP64 156 extern int __filbuf(FILE *); 157 extern int __flsbuf(int, FILE *); 158 159 /* 160 * Not needed as a function in 64 bit mode. 161 */ 162 #define _realbufend(iop) ((iop)->_end) 163 #else 164 extern Uchar *_realbufend(FILE *iop); 165 extern rmutex_t *_reallock(FILE *iop); 166 #endif /* _LP64 */ 167 168 extern void _setbufend(FILE *iop, Uchar *end); 169 extern rmutex_t *_flockget(FILE *iop); 170 extern int _xflsbuf(FILE *iop); 171 extern int _wrtchk(FILE *iop); 172 extern void _bufsync(FILE *iop, Uchar *bufend); 173 extern int _fflush_u(FILE *iop); 174 extern int close_fd(FILE *iop); 175 extern int _doscan(FILE *, const char *, va_list); 176 #ifdef _LP64 177 extern void close_pid(void); 178 #endif /* _LP64 */ 179 180 /* 181 * Internal routines from flush.c 182 */ 183 extern int _get_fd(FILE *); 184 extern int _file_set(FILE *, int, const char *); 185 186 /* 187 * Macros to aid the extended fd FILE work. 188 * This helps isolate the changes to only the 32-bit code 189 * since 64-bit Solaris is not affected by this. 190 */ 191 #ifdef _LP64 192 #define SET_FILE(iop, fd) ((iop)->_file = (fd)) 193 #else 194 #define SET_FILE(iop, fd) (iop)->_magic = (fd); (iop)->__extendedfd = 0 195 #endif 196 197 /* 198 * Maximum size of the file descriptor stored in the FILE structure. 199 */ 200 201 #ifdef _LP64 202 #define _FILE_FD_MAX INT_MAX 203 #else 204 #define _FILE_FD_MAX 255 205 #endif 206 207 /* 208 * Internal routines from fileno.c 209 */ 210 extern int _fileno(FILE *iop); 211 212 /* 213 * Internal routines from _findbuf.c 214 */ 215 extern Uchar *_findbuf(FILE *iop); 216 217 /* 218 * Internal routine used by fopen.c 219 */ 220 extern FILE *_endopen(const char *, const char *, FILE *, int); 221 222 /* 223 * Internal routine from fwrite.c 224 */ 225 extern size_t _fwrite_unlocked(const void *, size_t, size_t, FILE *); 226 227 /* 228 * Internal routine from getc.c 229 */ 230 int _getc_internal(FILE *); 231 232 /* 233 * Internal routine from put.c 234 */ 235 int _putc_internal(int, FILE *); 236 237 /* 238 * Internal routine from ungetc.c 239 */ 240 int _ungetc_unlocked(int, FILE *); 241 242 /* 243 * The following macros improve performance of the stdio by reducing the 244 * number of calls to _bufsync and _wrtchk. _needsync checks whether 245 * or not _bufsync needs to be called. _WRTCHK has the same effect as 246 * _wrtchk, but often these functions have no effect, and in those cases 247 * the macros avoid the expense of calling the functions. 248 */ 249 250 #define _needsync(p, bufend) ((bufend - (p)->_ptr) < \ 251 ((p)->_cnt < 0 ? 0 : (p)->_cnt)) 252 253 #define _WRTCHK(iop) ((((iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT) || \ 254 (iop->_base == 0) || \ 255 (iop->_ptr == iop->_base && iop->_cnt == 0 && \ 256 !(iop->_flag & (_IONBF | _IOLBF)))) \ 257 ? _wrtchk(iop) : 0) 258 259 #ifdef _LP64 260 #define IOB_LCK(iop) (&((iop)->_lock)) 261 #else 262 #define IOB_LCK(iop) (STDIOP(iop) ? &_xftab[IOPIND(iop)]._lock \ 263 : _reallock(iop)) 264 265 extern struct xFILEdata _xftab[]; 266 267 #endif /* _LP64 */ 268 269 /* 270 * A set of stdio routines to allow us to have alternate read, write, lseek, and 271 * close implementations. 272 */ 273 extern ssize_t _xread(FILE *iop, void *buf, size_t nbytes); 274 extern ssize_t _xwrite(FILE *iop, const void *buf, size_t nbytes); 275 extern off_t _xseek(FILE *iop, off_t off, int whence); 276 extern off64_t _xseek64(FILE *iop, off64_t off, int whence); 277 extern int _xclose(FILE *iop); 278 extern void *_xdata(FILE *iop); 279 extern int _xassoc(FILE *iop, fread_t readf, fwrite_t writef, 280 fseek_t seekf, fclose_t closef, void *data); 281 extern void _xunassoc(FILE *iop); 282 283 /* 284 * Internal functions from _stdio_flags.c. 285 */ 286 extern int _stdio_flags(const char *type, int *oflags, int *fflags); 287 288 /* 289 * Internal functions from open_memstream.c. 290 */ 291 extern boolean_t memstream_seek(size_t base, off_t off, size_t max, 292 size_t *nposp); 293 extern int memstream_newsize(size_t pos, size_t alloc, size_t nbytes, 294 size_t *nallocp); 295 296 /* 297 * Internal function from ftell.o. 298 */ 299 extern off64_t ftell_common(FILE *iop); 300 301 #endif /* _STDIOM_H */ 302