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