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 2006 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 * stdiom.h - shared guts of stdio 32 */ 33 34 #ifndef _STDIOM_H 35 #define _STDIOM_H 36 37 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 38 39 #include <thread.h> 40 #include <synch.h> 41 #include <mtlib.h> 42 #include <stdarg.h> 43 #include "file64.h" 44 #include <wchar.h> 45 #include "mse.h" 46 47 48 /* 49 * The following flags, and the macros that manipulate them, operate upon 50 * the FILE structure used by stdio. If new flags are required, they should 51 * be created in this file. The values of the flags must be differnt from 52 * the currently used values. New macros should be created to use the flags 53 * so that the compilation mode dependencies can be isolated here. 54 */ 55 56 #ifdef _LP64 57 #define _BYTE_MODE_FLAG 0400 58 #define _WC_MODE_FLAG 01000 59 #define _IONOLOCK 02000 60 #define _SEEKABLE 04000 /* is it seekable? */ 61 #define SET_IONOLOCK(iop) ((iop)->_flag |= _IONOLOCK) 62 #define CLEAR_IONOLOCK(iop) ((iop)->_flag &= ~_IONOLOCK) 63 #define GET_IONOLOCK(iop) ((iop)->_flag & _IONOLOCK) 64 #define SET_BYTE_MODE(iop) ((iop)->_flag |= _BYTE_MODE_FLAG) 65 #define CLEAR_BYTE_MODE(iop) ((iop)->_flag &= ~_BYTE_MODE_FLAG) 66 #define GET_BYTE_MODE(iop) ((iop)->_flag & _BYTE_MODE_FLAG) 67 #define SET_WC_MODE(iop) ((iop)->_flag |= _WC_MODE_FLAG) 68 #define CLEAR_WC_MODE(iop) ((iop)->_flag &= ~_WC_MODE_FLAG) 69 #define GET_WC_MODE(iop) ((iop)->_flag & _WC_MODE_FLAG) 70 #define GET_NO_MODE(iop) (!((iop)->_flag & \ 71 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 72 #define SET_SEEKABLE(iop) ((iop)->_flag |= _SEEKABLE) 73 #define CLEAR_SEEKABLE(iop) ((iop)->_flag &= ~_SEEKABLE) 74 #define GET_SEEKABLE(iop) ((iop)->_flag & _SEEKABLE) 75 #else 76 #define _BYTE_MODE_FLAG 0001 77 #define _WC_MODE_FLAG 0002 78 #define SET_IONOLOCK(iop) ((iop)->__ionolock = 1) 79 #define CLEAR_IONOLOCK(iop) ((iop)->__ionolock = 0) 80 #define GET_IONOLOCK(iop) ((iop)->__ionolock) 81 #define SET_BYTE_MODE(iop) ((iop)->__orientation |= _BYTE_MODE_FLAG) 82 #define CLEAR_BYTE_MODE(iop) ((iop)->__orientation &= ~_BYTE_MODE_FLAG) 83 #define GET_BYTE_MODE(iop) ((iop)->__orientation & _BYTE_MODE_FLAG) 84 #define SET_WC_MODE(iop) ((iop)->__orientation |= _WC_MODE_FLAG) 85 #define CLEAR_WC_MODE(iop) ((iop)->__orientation &= ~_WC_MODE_FLAG) 86 #define GET_WC_MODE(iop) ((iop)->__orientation & _WC_MODE_FLAG) 87 #define GET_NO_MODE(iop) (!((iop)->__orientation & \ 88 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 89 #define SET_SEEKABLE(iop) ((iop)->__seekable = 1) 90 #define CLEAR_SEEKABLE(iop) ((iop)->__seekable = 0) 91 #define GET_SEEKABLE(iop) ((iop)->__seekable) 92 93 /* Is iop a member of the _iob array? */ 94 #define STDIOP(iop) ((iop) >= &_iob[0] && (iop) < &_iob[_NFILE]) 95 96 /* Compute the index of an _iob array member */ 97 #define IOPIND(iop) ((iop) - &_iob[0]) 98 99 #endif 100 101 typedef unsigned char Uchar; 102 103 #define _flockrel(rl) rmutex_unlock(rl) 104 105 #define MAXVAL (MAXINT - (MAXINT % BUFSIZ)) 106 107 /* 108 * The number of actual pushback characters is the value 109 * of PUSHBACK plus the first byte of the buffer. The FILE buffer must, 110 * for performance reasons, start on a word aligned boundry so the value 111 * of PUSHBACK should be a multiple of word. 112 * At least 4 bytes of PUSHBACK are needed. If sizeof (int) = 1 this breaks. 113 */ 114 #define PUSHBACK (((3 + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 115 116 /* minimum buffer size must be at least 8 or shared library will break */ 117 #define _SMBFSZ (((PUSHBACK + 4) < 8) ? 8 : (PUSHBACK + 4)) 118 119 #if BUFSIZ == 1024 120 #define MULTIBFSZ(SZ) ((SZ) & ~0x3ff) 121 #elif BUFSIZ == 512 122 #define MULTIBFSZ(SZ) ((SZ) & ~0x1ff) 123 #else 124 #define MULTIBFSZ(SZ) ((SZ) - (SZ % BUFSIZ)) 125 #endif 126 127 #undef _bufend 128 #define _bufend(iop) _realbufend(iop) 129 130 /* 131 * Internal data 132 */ 133 extern Uchar _smbuf[][_SMBFSZ]; 134 135 136 /* 137 * Internal routines from flush.c 138 */ 139 extern void __cleanup(void); 140 extern void _flushlbf(void); 141 extern FILE *_findiop(void); 142 143 /* 144 * this is to be found in <stdio.h> for 32bit mode 145 */ 146 #ifdef _LP64 147 extern int __filbuf(FILE *); 148 extern int __flsbuf(int, FILE *); 149 150 /* 151 * Not needed as a function in 64 bit mode. 152 */ 153 #define _realbufend(iop) ((iop)->_end) 154 #else 155 extern Uchar *_realbufend(FILE *iop); 156 extern rmutex_t *_reallock(FILE *iop); 157 #endif /* _LP64 */ 158 159 extern void _setbufend(FILE *iop, Uchar *end); 160 extern rmutex_t *_flockget(FILE *iop); 161 extern int _xflsbuf(FILE *iop); 162 extern int _wrtchk(FILE *iop); 163 extern void _bufsync(FILE *iop, Uchar *bufend); 164 extern int _fflush_u(FILE *iop); 165 extern int close_fd(FILE *iop); 166 extern int _doscan(FILE *, const char *, va_list); 167 #ifdef _LP64 168 extern void close_pid(void); 169 #endif /* _LP64 */ 170 171 /* 172 * Internal routines from flush.c 173 */ 174 extern int _file_get(FILE *); 175 extern int _file_set(FILE *, int, const char *); 176 177 /* 178 * Macros to aid the extended fd FILE work. 179 * This helps isolate the changes to only the 32-bit code 180 * since 64-bit Solaris is not affected by this. 181 */ 182 #ifdef _LP64 183 #define GET_FD(iop) ((iop)->_file) 184 #define SET_FILE(iop, fd) ((iop)->_file = (fd)) 185 #else 186 #define GET_FD(iop) \ 187 (((iop)->__extendedfd) ? _file_get(iop) : (iop)->_magic) 188 #define SET_FILE(iop, fd) (iop)->_magic = (fd); (iop)->__extendedfd = 0 189 #endif 190 191 /* 192 * Maximum size of the file descriptor stored in the FILE structure. 193 */ 194 195 #ifdef _LP64 196 #define _FILE_FD_MAX INT_MAX 197 #else 198 #define _FILE_FD_MAX 255 199 #endif 200 201 /* 202 * Internal routines from fileno.c 203 */ 204 extern int _fileno(FILE *iop); 205 206 /* 207 * Internal routines from _findbuf.c 208 */ 209 extern Uchar *_findbuf(FILE *iop); 210 211 /* 212 * Internal routine used by fopen.c 213 */ 214 extern FILE *_endopen(const char *, const char *, FILE *, int); 215 216 /* 217 * Internal routine from fwrite.c 218 */ 219 extern size_t _fwrite_unlocked(const void *, size_t, size_t, FILE *); 220 221 /* 222 * Internal routine from getc.c 223 */ 224 int _getc_unlocked(FILE *); 225 226 /* 227 * Internal routine from put.c 228 */ 229 int _putc_unlocked(int, FILE *); 230 231 /* 232 * Internal routine from ungetc.c 233 */ 234 int _ungetc_unlocked(int, FILE *); 235 236 /* 237 * The following macros improve performance of the stdio by reducing the 238 * number of calls to _bufsync and _wrtchk. _needsync checks whether 239 * or not _bufsync needs to be called. _WRTCHK has the same effect as 240 * _wrtchk, but often these functions have no effect, and in those cases 241 * the macros avoid the expense of calling the functions. 242 */ 243 244 #define _needsync(p, bufend) ((bufend - (p)->_ptr) < \ 245 ((p)->_cnt < 0 ? 0 : (p)->_cnt)) 246 247 #define _WRTCHK(iop) ((((iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT) || \ 248 (iop->_base == 0) || \ 249 (iop->_ptr == iop->_base && iop->_cnt == 0 && \ 250 !(iop->_flag & (_IONBF | _IOLBF)))) \ 251 ? _wrtchk(iop) : 0) 252 253 #ifdef _LP64 254 #define IOB_LCK(iop) (&((iop)->_lock)) 255 #else 256 #define IOB_LCK(iop) (STDIOP(iop) ? &_xftab[IOPIND(iop)]._lock \ 257 : _reallock(iop)) 258 259 extern struct xFILEdata _xftab[]; 260 261 #endif /* _LP64 */ 262 263 #endif /* _STDIOM_H */ 264