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