xref: /illumos-gate/usr/src/lib/libc/inc/stdiom.h (revision 7c478bd9)
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