xref: /illumos-gate/usr/src/lib/libc/inc/stdiom.h (revision cd62a92d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5a5f69788Scraigm  * Common Development and Distribution License (the "License").
6a5f69788Scraigm  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23a574db85Sraf  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
28d7269947SRobert Mustacchi /*	  All Rights Reserved	*/
30*cd62a92dSRobert Mustacchi /*
31*cd62a92dSRobert Mustacchi  * Copyright 2020 Robert Mustacchi
32*cd62a92dSRobert Mustacchi  */
33*cd62a92dSRobert Mustacchi 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * stdiom.h - shared guts of stdio
367c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate #ifndef	_STDIOM_H
397c478bd9Sstevel@tonic-gate #define	_STDIOM_H
417c478bd9Sstevel@tonic-gate #include <thread.h>
427c478bd9Sstevel@tonic-gate #include <synch.h>
437c478bd9Sstevel@tonic-gate #include <mtlib.h>
447c478bd9Sstevel@tonic-gate #include <stdarg.h>
457c478bd9Sstevel@tonic-gate #include "file64.h"
467c478bd9Sstevel@tonic-gate #include <wchar.h>
477c478bd9Sstevel@tonic-gate #include "mse.h"
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * The following flags, and the macros that manipulate them, operate upon
527c478bd9Sstevel@tonic-gate  * the FILE structure used by stdio. If new flags are required, they should
53*cd62a92dSRobert Mustacchi  * be created in this file. The values of the flags must be different from
547c478bd9Sstevel@tonic-gate  * the currently used values. New macros should be created to use the flags
557c478bd9Sstevel@tonic-gate  * so that the compilation mode dependencies can be isolated here.
567c478bd9Sstevel@tonic-gate  */
58*cd62a92dSRobert Mustacchi /*
59*cd62a92dSRobert Mustacchi  * The 32-bit version of the stdio FILE has 8 bits for its flags (see
60*cd62a92dSRobert Mustacchi  * lib/libc/port/stdio/README.design). These 8 bits are used to determine if the
61*cd62a92dSRobert Mustacchi  * FILE structure is allocated. We define '_DEF_FLAG_MASK' as a means to
62*cd62a92dSRobert Mustacchi  * indicate this.
63*cd62a92dSRobert Mustacchi  */
64*cd62a92dSRobert Mustacchi #define	_DEF_FLAG_MASK	0377
657c478bd9Sstevel@tonic-gate #ifdef _LP64
667c478bd9Sstevel@tonic-gate #define	_BYTE_MODE_FLAG	0400
677c478bd9Sstevel@tonic-gate #define	_WC_MODE_FLAG	01000
687c478bd9Sstevel@tonic-gate #define	_IONOLOCK	02000
697c478bd9Sstevel@tonic-gate #define	_SEEKABLE	04000	/* is it seekable? */
707c478bd9Sstevel@tonic-gate #define	SET_IONOLOCK(iop)	((iop)->_flag |= _IONOLOCK)
717c478bd9Sstevel@tonic-gate #define	CLEAR_IONOLOCK(iop)	((iop)->_flag &= ~_IONOLOCK)
727c478bd9Sstevel@tonic-gate #define	GET_IONOLOCK(iop)	((iop)->_flag & _IONOLOCK)
737c478bd9Sstevel@tonic-gate #define	SET_BYTE_MODE(iop)	((iop)->_flag |= _BYTE_MODE_FLAG)
747c478bd9Sstevel@tonic-gate #define	CLEAR_BYTE_MODE(iop)	((iop)->_flag &= ~_BYTE_MODE_FLAG)
757c478bd9Sstevel@tonic-gate #define	GET_BYTE_MODE(iop)	((iop)->_flag & _BYTE_MODE_FLAG)
767c478bd9Sstevel@tonic-gate #define	SET_WC_MODE(iop)	((iop)->_flag |= _WC_MODE_FLAG)
777c478bd9Sstevel@tonic-gate #define	CLEAR_WC_MODE(iop)	((iop)->_flag &= ~_WC_MODE_FLAG)
787c478bd9Sstevel@tonic-gate #define	GET_WC_MODE(iop)	((iop)->_flag & _WC_MODE_FLAG)
797c478bd9Sstevel@tonic-gate #define	GET_NO_MODE(iop)	(!((iop)->_flag & \
807c478bd9Sstevel@tonic-gate 					(_BYTE_MODE_FLAG | _WC_MODE_FLAG)))
817c478bd9Sstevel@tonic-gate #define	SET_SEEKABLE(iop)	((iop)->_flag |=  _SEEKABLE)
827c478bd9Sstevel@tonic-gate #define	CLEAR_SEEKABLE(iop)	((iop)->_flag &= ~_SEEKABLE)
837c478bd9Sstevel@tonic-gate #define	GET_SEEKABLE(iop)	((iop)->_flag &   _SEEKABLE)
847c478bd9Sstevel@tonic-gate #else
857c478bd9Sstevel@tonic-gate #define	_BYTE_MODE_FLAG	0001
867c478bd9Sstevel@tonic-gate #define	_WC_MODE_FLAG	0002
877c478bd9Sstevel@tonic-gate #define	SET_IONOLOCK(iop)	((iop)->__ionolock = 1)
887c478bd9Sstevel@tonic-gate #define	CLEAR_IONOLOCK(iop)	((iop)->__ionolock = 0)
897c478bd9Sstevel@tonic-gate #define	GET_IONOLOCK(iop)	((iop)->__ionolock)
907c478bd9Sstevel@tonic-gate #define	SET_BYTE_MODE(iop)	((iop)->__orientation |= _BYTE_MODE_FLAG)
917c478bd9Sstevel@tonic-gate #define	CLEAR_BYTE_MODE(iop)	((iop)->__orientation &= ~_BYTE_MODE_FLAG)
927c478bd9Sstevel@tonic-gate #define	GET_BYTE_MODE(iop)	((iop)->__orientation & _BYTE_MODE_FLAG)
937c478bd9Sstevel@tonic-gate #define	SET_WC_MODE(iop)	((iop)->__orientation |= _WC_MODE_FLAG)
947c478bd9Sstevel@tonic-gate #define	CLEAR_WC_MODE(iop)	((iop)->__orientation &= ~_WC_MODE_FLAG)
957c478bd9Sstevel@tonic-gate #define	GET_WC_MODE(iop)	((iop)->__orientation & _WC_MODE_FLAG)
967c478bd9Sstevel@tonic-gate #define	GET_NO_MODE(iop)	(!((iop)->__orientation & \
977c478bd9Sstevel@tonic-gate 					(_BYTE_MODE_FLAG | _WC_MODE_FLAG)))
987c478bd9Sstevel@tonic-gate #define	SET_SEEKABLE(iop)	((iop)->__seekable = 1)
997c478bd9Sstevel@tonic-gate #define	CLEAR_SEEKABLE(iop)	((iop)->__seekable = 0)
1007c478bd9Sstevel@tonic-gate #define	GET_SEEKABLE(iop)	((iop)->__seekable)
1027c478bd9Sstevel@tonic-gate /* Is iop a member of the _iob array? */
1037c478bd9Sstevel@tonic-gate #define	STDIOP(iop)		((iop) >= &_iob[0] && (iop) < &_iob[_NFILE])
1057c478bd9Sstevel@tonic-gate /* Compute the index of an _iob array member */
1067c478bd9Sstevel@tonic-gate #define	IOPIND(iop)		((iop) - &_iob[0])
1087c478bd9Sstevel@tonic-gate #endif
1107c478bd9Sstevel@tonic-gate typedef unsigned char	Uchar;
112a574db85Sraf #define	_flockrel(rl)		cancel_safe_mutex_unlock(rl)
1147c478bd9Sstevel@tonic-gate #define	MAXVAL	(MAXINT - (MAXINT % BUFSIZ))
1167c478bd9Sstevel@tonic-gate /*
1177c478bd9Sstevel@tonic-gate  * The number of actual pushback characters is the value
1187c478bd9Sstevel@tonic-gate  * of PUSHBACK plus the first byte of the buffer. The FILE buffer must,
1197c478bd9Sstevel@tonic-gate  * for performance reasons, start on a word aligned boundry so the value
1207c478bd9Sstevel@tonic-gate  * of PUSHBACK should be a multiple of word.
1217c478bd9Sstevel@tonic-gate  * At least 4 bytes of PUSHBACK are needed. If sizeof (int) = 1 this breaks.
1227c478bd9Sstevel@tonic-gate  */
1237c478bd9Sstevel@tonic-gate #define	PUSHBACK	(((3 + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
1257c478bd9Sstevel@tonic-gate /* minimum buffer size must be at least 8 or shared library will break */
1267c478bd9Sstevel@tonic-gate #define	_SMBFSZ	(((PUSHBACK + 4) < 8) ? 8 : (PUSHBACK + 4))
1287c478bd9Sstevel@tonic-gate #if BUFSIZ == 1024
1297c478bd9Sstevel@tonic-gate #define	MULTIBFSZ(SZ)	((SZ) & ~0x3ff)
1307c478bd9Sstevel@tonic-gate #elif BUFSIZ == 512
1317c478bd9Sstevel@tonic-gate #define	MULTIBFSZ(SZ)    ((SZ) & ~0x1ff)
1327c478bd9Sstevel@tonic-gate #else
1337c478bd9Sstevel@tonic-gate #define	MULTIBFSZ(SZ)    ((SZ) - (SZ % BUFSIZ))
1347c478bd9Sstevel@tonic-gate #endif
1367c478bd9Sstevel@tonic-gate #undef _bufend
1377c478bd9Sstevel@tonic-gate #define	_bufend(iop)	_realbufend(iop)
1397c478bd9Sstevel@tonic-gate /*
1407c478bd9Sstevel@tonic-gate  * Internal data
1417c478bd9Sstevel@tonic-gate  */
1427c478bd9Sstevel@tonic-gate extern Uchar _smbuf[][_SMBFSZ];
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate  * Internal routines from flush.c
1477c478bd9Sstevel@tonic-gate  */
1487c478bd9Sstevel@tonic-gate extern void	__cleanup(void);
1497c478bd9Sstevel@tonic-gate extern void	_flushlbf(void);
1507c478bd9Sstevel@tonic-gate extern FILE	*_findiop(void);
1527c478bd9Sstevel@tonic-gate /*
1537c478bd9Sstevel@tonic-gate  * this is to be found in <stdio.h> for 32bit mode
1547c478bd9Sstevel@tonic-gate  */
1557c478bd9Sstevel@tonic-gate #ifdef	_LP64
1567c478bd9Sstevel@tonic-gate extern int	__filbuf(FILE *);
1577c478bd9Sstevel@tonic-gate extern int	__flsbuf(int, FILE *);
1597c478bd9Sstevel@tonic-gate /*
1607c478bd9Sstevel@tonic-gate  * Not needed as a function in 64 bit mode.
1617c478bd9Sstevel@tonic-gate  */
1627c478bd9Sstevel@tonic-gate #define	_realbufend(iop)	((iop)->_end)
1637c478bd9Sstevel@tonic-gate #else
164d7269947SRobert Mustacchi extern Uchar	*_realbufend(FILE *iop);
1657c478bd9Sstevel@tonic-gate extern rmutex_t	*_reallock(FILE *iop);
1667c478bd9Sstevel@tonic-gate #endif	/*	_LP64	*/
1687c478bd9Sstevel@tonic-gate extern void	_setbufend(FILE *iop, Uchar *end);
1697c478bd9Sstevel@tonic-gate extern rmutex_t *_flockget(FILE *iop);
1707c478bd9Sstevel@tonic-gate extern int	_xflsbuf(FILE *iop);
1717c478bd9Sstevel@tonic-gate extern int	_wrtchk(FILE *iop);
1727c478bd9Sstevel@tonic-gate extern void	_bufsync(FILE *iop, Uchar *bufend);
1737c478bd9Sstevel@tonic-gate extern int	_fflush_u(FILE *iop);
1747c478bd9Sstevel@tonic-gate extern int	close_fd(FILE *iop);
1757c478bd9Sstevel@tonic-gate extern int	_doscan(FILE *, const char *, va_list);
1767c478bd9Sstevel@tonic-gate #ifdef	_LP64
1777c478bd9Sstevel@tonic-gate extern void	close_pid(void);
1787c478bd9Sstevel@tonic-gate #endif	/*	_LP64	*/
180a5f69788Scraigm /*
181a5f69788Scraigm  * Internal routines from flush.c
182a5f69788Scraigm  */
183*cd62a92dSRobert Mustacchi extern int _get_fd(FILE *);
184a5f69788Scraigm extern int _file_set(FILE *, int, const char *);
186a5f69788Scraigm /*
187a5f69788Scraigm  * Macros to aid the extended fd FILE work.
188a5f69788Scraigm  * This helps isolate the changes to only the 32-bit code
189a5f69788Scraigm  * since 64-bit Solaris is not affected by this.
190a5f69788Scraigm  */
191a5f69788Scraigm #ifdef  _LP64
192a5f69788Scraigm #define	SET_FILE(iop, fd)	((iop)->_file = (fd))
193a5f69788Scraigm #else
194a5f69788Scraigm #define	SET_FILE(iop, fd)	(iop)->_magic = (fd); (iop)->__extendedfd = 0
195a5f69788Scraigm #endif
197a5f69788Scraigm /*
198a5f69788Scraigm  * Maximum size of the file descriptor stored in the FILE structure.
199a5f69788Scraigm  */
201a5f69788Scraigm #ifdef _LP64
202a5f69788Scraigm #define	_FILE_FD_MAX	INT_MAX
203a5f69788Scraigm #else
204a5f69788Scraigm #define	_FILE_FD_MAX	255
205a5f69788Scraigm #endif
2077c478bd9Sstevel@tonic-gate /*
2087c478bd9Sstevel@tonic-gate  * Internal routines from fileno.c
2097c478bd9Sstevel@tonic-gate  */
21059e63b6eSraf extern int _fileno(FILE *iop);
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate  * Internal routines from _findbuf.c
2147c478bd9Sstevel@tonic-gate  */
215d7269947SRobert Mustacchi extern Uchar	*_findbuf(FILE *iop);
2177c478bd9Sstevel@tonic-gate /*
2187c478bd9Sstevel@tonic-gate  * Internal routine used by fopen.c
2197c478bd9Sstevel@tonic-gate  */
2207c478bd9Sstevel@tonic-gate extern	FILE	*_endopen(const char *, const char *, FILE *, int);
2227c478bd9Sstevel@tonic-gate /*
22359e63b6eSraf  * Internal routine from fwrite.c
2247c478bd9Sstevel@tonic-gate  */
2257c478bd9Sstevel@tonic-gate extern size_t _fwrite_unlocked(const void *, size_t, size_t, FILE *);
2277c478bd9Sstevel@tonic-gate /*
2287c478bd9Sstevel@tonic-gate  * Internal routine from getc.c
2297c478bd9Sstevel@tonic-gate  */
230d7269947SRobert Mustacchi int _getc_internal(FILE *);
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate  * Internal routine from put.c
2347c478bd9Sstevel@tonic-gate  */
235d7269947SRobert Mustacchi int _putc_internal(int, FILE *);
2377c478bd9Sstevel@tonic-gate /*
2387c478bd9Sstevel@tonic-gate  * Internal routine from ungetc.c
2397c478bd9Sstevel@tonic-gate  */
2407c478bd9Sstevel@tonic-gate int _ungetc_unlocked(int, FILE *);
2427c478bd9Sstevel@tonic-gate /*
2437c478bd9Sstevel@tonic-gate  * The following macros improve performance of the stdio by reducing the
2447c478bd9Sstevel@tonic-gate  * number of calls to _bufsync and _wrtchk.  _needsync checks whether
2457c478bd9Sstevel@tonic-gate  * or not _bufsync needs to be called.  _WRTCHK has the same effect as
2467c478bd9Sstevel@tonic-gate  * _wrtchk, but often these functions have no effect, and in those cases
2477c478bd9Sstevel@tonic-gate  * the macros avoid the expense of calling the functions.
2487c478bd9Sstevel@tonic-gate  */
2507c478bd9Sstevel@tonic-gate #define	_needsync(p, bufend)	((bufend - (p)->_ptr) < \
2517c478bd9Sstevel@tonic-gate 				    ((p)->_cnt < 0 ? 0 : (p)->_cnt))
2537c478bd9Sstevel@tonic-gate #define	_WRTCHK(iop)	((((iop->_flag & (_IOWRT | _IOEOF)) != _IOWRT) || \
2547c478bd9Sstevel@tonic-gate 			    (iop->_base == 0) ||  \
2557c478bd9Sstevel@tonic-gate 			    (iop->_ptr == iop->_base && iop->_cnt == 0 && \
2567c478bd9Sstevel@tonic-gate 			    !(iop->_flag & (_IONBF | _IOLBF)))) \
2577c478bd9Sstevel@tonic-gate 			? _wrtchk(iop) : 0)
2597c478bd9Sstevel@tonic-gate #ifdef	_LP64
2607c478bd9Sstevel@tonic-gate #define	IOB_LCK(iop)	(&((iop)->_lock))
2617c478bd9Sstevel@tonic-gate #else
2627c478bd9Sstevel@tonic-gate #define	IOB_LCK(iop)	(STDIOP(iop) ? &_xftab[IOPIND(iop)]._lock \
2637c478bd9Sstevel@tonic-gate 					: _reallock(iop))
2657c478bd9Sstevel@tonic-gate extern struct xFILEdata	_xftab[];
2677c478bd9Sstevel@tonic-gate #endif	/*	_LP64	*/
269*cd62a92dSRobert Mustacchi /*
270*cd62a92dSRobert Mustacchi  * A set of stdio routines to allow us to have alternate read, write, lseek, and
271*cd62a92dSRobert Mustacchi  * close implementations.
272*cd62a92dSRobert Mustacchi  */
273*cd62a92dSRobert Mustacchi extern ssize_t	_xread(FILE *iop, void *buf, size_t nbytes);
274*cd62a92dSRobert Mustacchi extern ssize_t	_xwrite(FILE *iop, const void *buf, size_t nbytes);
275*cd62a92dSRobert Mustacchi extern off_t	_xseek(FILE *iop, off_t off, int whence);
276*cd62a92dSRobert Mustacchi extern off64_t	_xseek64(FILE *iop, off64_t off, int whence);
277*cd62a92dSRobert Mustacchi extern int	_xclose(FILE *iop);
278*cd62a92dSRobert Mustacchi extern void	*_xdata(FILE *iop);
279*cd62a92dSRobert Mustacchi extern int	_xassoc(FILE *iop, fread_t readf, fwrite_t writef,
280*cd62a92dSRobert Mustacchi     fseek_t seekf, fclose_t closef, void *data);
281*cd62a92dSRobert Mustacchi extern void	_xunassoc(FILE *iop);
282*cd62a92dSRobert Mustacchi 
283*cd62a92dSRobert Mustacchi /*
284*cd62a92dSRobert Mustacchi  * Internal functions from _stdio_flags.c.
285*cd62a92dSRobert Mustacchi  */
286*cd62a92dSRobert Mustacchi extern int	_stdio_flags(const char *type, int *oflags, int *fflags);
287*cd62a92dSRobert Mustacchi 
288*cd62a92dSRobert Mustacchi /*
289*cd62a92dSRobert Mustacchi  * Internal functions from open_memstream.c.
290*cd62a92dSRobert Mustacchi  */
291*cd62a92dSRobert Mustacchi extern boolean_t	memstream_seek(size_t base, off_t off, size_t max,
292*cd62a92dSRobert Mustacchi     size_t *nposp);
293*cd62a92dSRobert Mustacchi extern int	memstream_newsize(size_t pos, size_t alloc, size_t nbytes,
294*cd62a92dSRobert Mustacchi     size_t *nallocp);
295*cd62a92dSRobert Mustacchi 
296*cd62a92dSRobert Mustacchi /*
297*cd62a92dSRobert Mustacchi  * Internal function from ftell.o.
298*cd62a92dSRobert Mustacchi  */
299*cd62a92dSRobert Mustacchi extern off64_t	ftell_common(FILE *iop);
300*cd62a92dSRobert Mustacchi 
3017c478bd9Sstevel@tonic-gate #endif	/* _STDIOM_H */