stdiom.h revision 5891:0d5c6468bb04
1160814Ssimon/*
2160814Ssimon * CDDL HEADER START
3160814Ssimon *
4160814Ssimon * The contents of this file are subject to the terms of the
5160814Ssimon * Common Development and Distribution License (the "License").
6160814Ssimon * You may not use this file except in compliance with the License.
7160814Ssimon *
8160814Ssimon * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9160814Ssimon * or http://www.opensolaris.org/os/licensing.
10160814Ssimon * See the License for the specific language governing permissions
11160814Ssimon * and limitations under the License.
12160814Ssimon *
13160814Ssimon * When distributing Covered Code, include this CDDL HEADER in each
14160814Ssimon * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15160814Ssimon * If applicable, add the following below this CDDL HEADER, with the
16160814Ssimon * fields enclosed by brackets "[]" replaced with your own identifying
17160814Ssimon * information: Portions Copyright [yyyy] [name of copyright owner]
18160814Ssimon *
19160814Ssimon * CDDL HEADER END
20160814Ssimon */
21160814Ssimon
22160814Ssimon/*
23160814Ssimon * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24160814Ssimon * Use is subject to license terms.
25160814Ssimon */
26160814Ssimon
27160814Ssimon/*	Copyright (c) 1988 AT&T	*/
28160814Ssimon/*	  All Rights Reserved  	*/
29160814Ssimon
30160814Ssimon/*
31160814Ssimon * stdiom.h - shared guts of stdio
32160814Ssimon */
33160814Ssimon
34160814Ssimon#ifndef	_STDIOM_H
35160814Ssimon#define	_STDIOM_H
36160814Ssimon
37238405Sjkim#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.9 */
38160814Ssimon
39160814Ssimon#include <thread.h>
40160814Ssimon#include <synch.h>
41160814Ssimon#include <mtlib.h>
42160814Ssimon#include <stdarg.h>
43160814Ssimon#include "file64.h"
44160814Ssimon#include <wchar.h>
45160814Ssimon#include "mse.h"
46160814Ssimon
47160814Ssimon
48160814Ssimon/*
49160814Ssimon * The following flags, and the macros that manipulate them, operate upon
50160814Ssimon * the FILE structure used by stdio. If new flags are required, they should
51160814Ssimon * be created in this file. The values of the flags must be differnt from
52160814Ssimon * the currently used values. New macros should be created to use the flags
53160814Ssimon * so that the compilation mode dependencies can be isolated here.
54160814Ssimon */
55160814Ssimon
56160814Ssimon#ifdef _LP64
57160814Ssimon#define	_BYTE_MODE_FLAG	0400
58160814Ssimon#define	_WC_MODE_FLAG	01000
59160814Ssimon#define	_IONOLOCK	02000
60160814Ssimon#define	_SEEKABLE	04000	/* is it seekable? */
61160814Ssimon#define	SET_IONOLOCK(iop)	((iop)->_flag |= _IONOLOCK)
62160814Ssimon#define	CLEAR_IONOLOCK(iop)	((iop)->_flag &= ~_IONOLOCK)
63160814Ssimon#define	GET_IONOLOCK(iop)	((iop)->_flag & _IONOLOCK)
64160814Ssimon#define	SET_BYTE_MODE(iop)	((iop)->_flag |= _BYTE_MODE_FLAG)
65284283Sjkim#define	CLEAR_BYTE_MODE(iop)	((iop)->_flag &= ~_BYTE_MODE_FLAG)
66284283Sjkim#define	GET_BYTE_MODE(iop)	((iop)->_flag & _BYTE_MODE_FLAG)
67160814Ssimon#define	SET_WC_MODE(iop)	((iop)->_flag |= _WC_MODE_FLAG)
68160814Ssimon#define	CLEAR_WC_MODE(iop)	((iop)->_flag &= ~_WC_MODE_FLAG)
69160814Ssimon#define	GET_WC_MODE(iop)	((iop)->_flag & _WC_MODE_FLAG)
70160814Ssimon#define	GET_NO_MODE(iop)	(!((iop)->_flag & \
71160814Ssimon					(_BYTE_MODE_FLAG | _WC_MODE_FLAG)))
72160814Ssimon#define	SET_SEEKABLE(iop)	((iop)->_flag |=  _SEEKABLE)
73160814Ssimon#define	CLEAR_SEEKABLE(iop)	((iop)->_flag &= ~_SEEKABLE)
74160814Ssimon#define	GET_SEEKABLE(iop)	((iop)->_flag &   _SEEKABLE)
75160814Ssimon#else
76160814Ssimon#define	_BYTE_MODE_FLAG	0001
77160814Ssimon#define	_WC_MODE_FLAG	0002
78160814Ssimon#define	SET_IONOLOCK(iop)	((iop)->__ionolock = 1)
79160814Ssimon#define	CLEAR_IONOLOCK(iop)	((iop)->__ionolock = 0)
80160814Ssimon#define	GET_IONOLOCK(iop)	((iop)->__ionolock)
81160814Ssimon#define	SET_BYTE_MODE(iop)	((iop)->__orientation |= _BYTE_MODE_FLAG)
82160814Ssimon#define	CLEAR_BYTE_MODE(iop)	((iop)->__orientation &= ~_BYTE_MODE_FLAG)
83160814Ssimon#define	GET_BYTE_MODE(iop)	((iop)->__orientation & _BYTE_MODE_FLAG)
84160814Ssimon#define	SET_WC_MODE(iop)	((iop)->__orientation |= _WC_MODE_FLAG)
85160814Ssimon#define	CLEAR_WC_MODE(iop)	((iop)->__orientation &= ~_WC_MODE_FLAG)
86160814Ssimon#define	GET_WC_MODE(iop)	((iop)->__orientation & _WC_MODE_FLAG)
87160814Ssimon#define	GET_NO_MODE(iop)	(!((iop)->__orientation & \
88160814Ssimon					(_BYTE_MODE_FLAG | _WC_MODE_FLAG)))
89160814Ssimon#define	SET_SEEKABLE(iop)	((iop)->__seekable = 1)
90160814Ssimon#define	CLEAR_SEEKABLE(iop)	((iop)->__seekable = 0)
91160814Ssimon#define	GET_SEEKABLE(iop)	((iop)->__seekable)
92160814Ssimon
93160814Ssimon/* Is iop a member of the _iob array? */
94160814Ssimon#define	STDIOP(iop)		((iop) >= &_iob[0] && (iop) < &_iob[_NFILE])
95160814Ssimon
96160814Ssimon/* Compute the index of an _iob array member */
97194206Ssimon#define	IOPIND(iop)		((iop) - &_iob[0])
98194206Ssimon
99194206Ssimon#endif
100160814Ssimon
101194206Ssimontypedef unsigned char	Uchar;
102238405Sjkim
103238405Sjkim#define	_flockrel(rl)		cancel_safe_mutex_unlock(rl)
104238405Sjkim
105238405Sjkim#define	MAXVAL	(MAXINT - (MAXINT % BUFSIZ))
106238405Sjkim
107238405Sjkim/*
108238405Sjkim * The number of actual pushback characters is the value
109160814Ssimon * of PUSHBACK plus the first byte of the buffer. The FILE buffer must,
110160814Ssimon * for performance reasons, start on a word aligned boundry so the value
111160814Ssimon * of PUSHBACK should be a multiple of word.
112160814Ssimon * At least 4 bytes of PUSHBACK are needed. If sizeof (int) = 1 this breaks.
113160814Ssimon */
114160814Ssimon#define	PUSHBACK	(((3 + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
115160814Ssimon
116160814Ssimon/* minimum buffer size must be at least 8 or shared library will break */
117337982Sjkim#define	_SMBFSZ	(((PUSHBACK + 4) < 8) ? 8 : (PUSHBACK + 4))
118160814Ssimon
119194206Ssimon#if BUFSIZ == 1024
120194206Ssimon#define	MULTIBFSZ(SZ)	((SZ) & ~0x3ff)
121194206Ssimon#elif BUFSIZ == 512
122194206Ssimon#define	MULTIBFSZ(SZ)    ((SZ) & ~0x1ff)
123238405Sjkim#else
124238405Sjkim#define	MULTIBFSZ(SZ)    ((SZ) - (SZ % BUFSIZ))
125160814Ssimon#endif
126205128Ssimon
127205128Ssimon#undef _bufend
128205128Ssimon#define	_bufend(iop)	_realbufend(iop)
129205128Ssimon
130205128Ssimon/*
131277270Sjkim * Internal data
132277270Sjkim */
133277270Sjkimextern Uchar _smbuf[][_SMBFSZ];
134277270Sjkim
135277270Sjkim
136238405Sjkim/*
137238405Sjkim * Internal routines from flush.c
138238405Sjkim */
139238405Sjkimextern void	__cleanup(void);
140238405Sjkimextern void	_flushlbf(void);
141238405Sjkimextern FILE	*_findiop(void);
142277270Sjkim
143/*
144 * this is to be found in <stdio.h> for 32bit mode
145 */
146#ifdef	_LP64
147extern int	__filbuf(FILE *);
148extern 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
155extern Uchar 	*_realbufend(FILE *iop);
156extern rmutex_t	*_reallock(FILE *iop);
157#endif	/*	_LP64	*/
158
159extern void	_setbufend(FILE *iop, Uchar *end);
160extern rmutex_t *_flockget(FILE *iop);
161extern int	_xflsbuf(FILE *iop);
162extern int	_wrtchk(FILE *iop);
163extern void	_bufsync(FILE *iop, Uchar *bufend);
164extern int	_fflush_u(FILE *iop);
165extern int	close_fd(FILE *iop);
166extern int	_doscan(FILE *, const char *, va_list);
167#ifdef	_LP64
168extern void	close_pid(void);
169#endif	/*	_LP64	*/
170
171/*
172 * Internal routines from flush.c
173 */
174extern int _file_get(FILE *);
175extern 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 */
204extern int _fileno(FILE *iop);
205
206/*
207 * Internal routines from _findbuf.c
208 */
209extern Uchar 	*_findbuf(FILE *iop);
210
211/*
212 * Internal routine used by fopen.c
213 */
214extern	FILE	*_endopen(const char *, const char *, FILE *, int);
215
216/*
217 * Internal routine from fwrite.c
218 */
219extern size_t _fwrite_unlocked(const void *, size_t, size_t, FILE *);
220
221/*
222 * Internal routine from getc.c
223 */
224int _getc_unlocked(FILE *);
225
226/*
227 * Internal routine from put.c
228 */
229int _putc_unlocked(int, FILE *);
230
231/*
232 * Internal routine from ungetc.c
233 */
234int _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
259extern struct xFILEdata	_xftab[];
260
261#endif	/*	_LP64	*/
262
263#endif	/* _STDIOM_H */
264