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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 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 32 /* 33 * stdiom.h - shared guts of stdio 34 */ 35 36 #ifndef _STDIOM_H 37 #define _STDIOM_H 38 39 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */ 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 differnt 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 #ifdef _LP64 59 #define _BYTE_MODE_FLAG 0400 60 #define _WC_MODE_FLAG 01000 61 #define _IONOLOCK 02000 62 #define _SEEKABLE 04000 /* is it seekable? */ 63 #define SET_IONOLOCK(iop) ((iop)->_flag |= _IONOLOCK) 64 #define CLEAR_IONOLOCK(iop) ((iop)->_flag &= ~_IONOLOCK) 65 #define GET_IONOLOCK(iop) ((iop)->_flag & _IONOLOCK) 66 #define SET_BYTE_MODE(iop) ((iop)->_flag |= _BYTE_MODE_FLAG) 67 #define CLEAR_BYTE_MODE(iop) ((iop)->_flag &= ~_BYTE_MODE_FLAG) 68 #define GET_BYTE_MODE(iop) ((iop)->_flag & _BYTE_MODE_FLAG) 69 #define SET_WC_MODE(iop) ((iop)->_flag |= _WC_MODE_FLAG) 70 #define CLEAR_WC_MODE(iop) ((iop)->_flag &= ~_WC_MODE_FLAG) 71 #define GET_WC_MODE(iop) ((iop)->_flag & _WC_MODE_FLAG) 72 #define GET_NO_MODE(iop) (!((iop)->_flag & \ 73 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 74 #define SET_SEEKABLE(iop) ((iop)->_flag |= _SEEKABLE) 75 #define CLEAR_SEEKABLE(iop) ((iop)->_flag &= ~_SEEKABLE) 76 #define GET_SEEKABLE(iop) ((iop)->_flag & _SEEKABLE) 77 #else 78 #define _BYTE_MODE_FLAG 0001 79 #define _WC_MODE_FLAG 0002 80 #define SET_IONOLOCK(iop) ((iop)->__ionolock = 1) 81 #define CLEAR_IONOLOCK(iop) ((iop)->__ionolock = 0) 82 #define GET_IONOLOCK(iop) ((iop)->__ionolock) 83 #define SET_BYTE_MODE(iop) ((iop)->__orientation |= _BYTE_MODE_FLAG) 84 #define CLEAR_BYTE_MODE(iop) ((iop)->__orientation &= ~_BYTE_MODE_FLAG) 85 #define GET_BYTE_MODE(iop) ((iop)->__orientation & _BYTE_MODE_FLAG) 86 #define SET_WC_MODE(iop) ((iop)->__orientation |= _WC_MODE_FLAG) 87 #define CLEAR_WC_MODE(iop) ((iop)->__orientation &= ~_WC_MODE_FLAG) 88 #define GET_WC_MODE(iop) ((iop)->__orientation & _WC_MODE_FLAG) 89 #define GET_NO_MODE(iop) (!((iop)->__orientation & \ 90 (_BYTE_MODE_FLAG | _WC_MODE_FLAG))) 91 #define SET_SEEKABLE(iop) ((iop)->__seekable = 1) 92 #define CLEAR_SEEKABLE(iop) ((iop)->__seekable = 0) 93 #define GET_SEEKABLE(iop) ((iop)->__seekable) 94 95 /* Is iop a member of the _iob array? */ 96 #define STDIOP(iop) ((iop) >= &_iob[0] && (iop) < &_iob[_NFILE]) 97 98 /* Compute the index of an _iob array member */ 99 #define IOPIND(iop) ((iop) - &_iob[0]) 100 101 #endif 102 103 typedef unsigned char Uchar; 104 105 #define _flockrel(rl) rmutex_unlock(rl) 106 107 #define MAXVAL (MAXINT - (MAXINT % BUFSIZ)) 108 109 /* 110 * The number of actual pushback characters is the value 111 * of PUSHBACK plus the first byte of the buffer. The FILE buffer must, 112 * for performance reasons, start on a word aligned boundry so the value 113 * of PUSHBACK should be a multiple of word. 114 * At least 4 bytes of PUSHBACK are needed. If sizeof (int) = 1 this breaks. 115 */ 116 #define PUSHBACK (((3 + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) 117 118 /* minimum buffer size must be at least 8 or shared library will break */ 119 #define _SMBFSZ (((PUSHBACK + 4) < 8) ? 8 : (PUSHBACK + 4)) 120 121 #if BUFSIZ == 1024 122 #define MULTIBFSZ(SZ) ((SZ) & ~0x3ff) 123 #elif BUFSIZ == 512 124 #define MULTIBFSZ(SZ) ((SZ) & ~0x1ff) 125 #else 126 #define MULTIBFSZ(SZ) ((SZ) - (SZ % BUFSIZ)) 127 #endif 128 129 #undef _bufend 130 #define _bufend(iop) _realbufend(iop) 131 132 /* 133 * Internal data 134 */ 135 extern Uchar _smbuf[][_SMBFSZ]; 136 137 138 /* 139 * Internal routines from flush.c 140 */ 141 extern void __cleanup(void); 142 extern void _flushlbf(void); 143 extern FILE *_findiop(void); 144 145 /* 146 * this is to be found in <stdio.h> for 32bit mode 147 */ 148 #ifdef _LP64 149 extern int __filbuf(FILE *); 150 extern int __flsbuf(int, FILE *); 151 152 /* 153 * Not needed as a function in 64 bit mode. 154 */ 155 #define _realbufend(iop) ((iop)->_end) 156 #else 157 extern Uchar *_realbufend(FILE *iop); 158 extern rmutex_t *_reallock(FILE *iop); 159 #endif /* _LP64 */ 160 161 extern void _setbufend(FILE *iop, Uchar *end); 162 extern rmutex_t *_flockget(FILE *iop); 163 extern int _xflsbuf(FILE *iop); 164 extern int _wrtchk(FILE *iop); 165 extern void _bufsync(FILE *iop, Uchar *bufend); 166 extern int _fflush_u(FILE *iop); 167 extern int close_fd(FILE *iop); 168 extern int _doscan(FILE *, const char *, va_list); 169 #ifdef _LP64 170 extern void close_pid(void); 171 #endif /* _LP64 */ 172 173 /* 174 * Internal routines from fileno.c 175 */ 176 extern int _fileno_unlocked(FILE *iop); 177 178 /* 179 * Internal routines from _findbuf.c 180 */ 181 extern Uchar *_findbuf(FILE *iop); 182 183 /* 184 * Internal routine used by fopen.c 185 */ 186 extern FILE *_endopen(const char *, const char *, FILE *, int); 187 188 /* 189 * Internal routine from ferror.c 190 */ 191 extern int _ferror_unlocked(FILE *); 192 193 /* 194 * Internal routine from ferror.c 195 */ 196 extern size_t _fwrite_unlocked(const void *, size_t, size_t, FILE *); 197 198 /* 199 * Internal routine from getc.c 200 */ 201 int _getc_unlocked(FILE *); 202 203 /* 204 * Internal routine from put.c 205 */ 206 int _putc_unlocked(int, FILE *); 207 208 /* 209 * Internal routine from ungetc.c 210 */ 211 int _ungetc_unlocked(int, FILE *); 212 213 /* 214 * The following macros improve performance of the stdio by reducing the 215 * number of calls to _bufsync and _wrtchk. _needsync checks whether 216 * or not _bufsync needs to be called. _WRTCHK has the same effect as 217 * _wrtchk, but often these functions have no effect, and in those cases 218 * the macros avoid the expense of calling the functions. 219 */ 220 221 #define _needsync(p, bufend) ((bufend - (p)->_ptr) < \ 222 ((p)->_cnt < 0 ? 0 : (p)->_cnt)) 223 224 #define _WRTCHK(iop) ((((iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT) || \ 225 (iop->_base == 0) || \ 226 (iop->_ptr == iop->_base && iop->_cnt == 0 && \ 227 !(iop->_flag & (_IONBF | _IOLBF)))) \ 228 ? _wrtchk(iop) : 0) 229 230 #ifdef _LP64 231 #define IOB_LCK(iop) (&((iop)->_lock)) 232 #else 233 #define IOB_LCK(iop) (STDIOP(iop) ? &_xftab[IOPIND(iop)]._lock \ 234 : _reallock(iop)) 235 236 extern struct xFILEdata _xftab[]; 237 238 #endif /* _LP64 */ 239 240 #endif /* _STDIOM_H */ 241