1 /* @(#)schilyio.h	2.31 16/11/06 Copyright 1986, 1995-2016 J. Schilling */
2 /*
3  *	Copyright (c) 1986, 1995-2016 J. Schilling
4  */
5 /*
6  * The contents of this file are subject to the terms of the
7  * Common Development and Distribution License, Version 1.0 only
8  * (the "License").  You may not use this file except in compliance
9  * with the License.
10  *
11  * See the file CDDL.Schily.txt in this distribution for details.
12  * A copy of the CDDL is also available via the Internet at
13  * http://www.opensource.org/licenses/cddl1.txt
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file CDDL.Schily.txt from this distribution.
17  */
18 
19 #ifndef	_STDIO_SCHILYIO_H
20 #define	_STDIO_SCHILYIO_H
21 
22 #include <schily/mconfig.h>
23 #include <schily/stdio.h>
24 #include <schily/standard.h>
25 #include <schily/types.h>
26 #include <schily/unistd.h>
27 #include <schily/fcntl.h>
28 #include <schily/schily.h>
29 #include <schily/errno.h>
30 
31 #ifdef	NO_USG_STDIO
32 #	ifdef	HAVE_USG_STDIO
33 #		undef	HAVE_USG_STDIO
34 #	endif
35 #endif
36 
37 #ifdef	HAVE_LARGEFILES
38 /*
39  * XXX We may need to put this code to a more global place to allow all
40  * XXX users of fseek()/ftell() to automaticaly use fseeko()/ftello()
41  * XXX if the latter are available.
42  *
43  * If HAVE_LARGEFILES is defined, it is guaranteed that fseeko()/ftello()
44  * both are available.
45  */
46 #	define	fseek	fseeko
47 #	define	ftell	ftello
48 
49 #else	/* !HAVE_LARGEFILES */
50 /*
51  * If HAVE_LARGEFILES is not defined, we depend on specific tests for
52  * fseeko()/ftello() which must have been done before the tests for
53  * Large File support have been done.
54  * Note that this only works if the tests used below are really done before
55  * the Large File autoconf test is run. This is because autoconf does no
56  * clean testing but instead cumulatively modifes the envivonment used for
57  * testing.
58  */
59 #ifdef	HAVE_FSEEKO
60 #	define	fseek	fseeko
61 #endif
62 #ifdef	HAVE_FTELLO
63 #	define	ftell	ftello
64 #endif
65 
66 #endif
67 
68 /*
69  * speed things up...
70  */
71 #ifndef	_OPENFD_SRC
72 #ifdef	_openfd
73 #undef	_openfd
74 #endif
75 #define	_openfd(name, omode)	(open(name, omode, (mode_t)0666))
76 #endif
77 
78 #define	DO_MYFLAG		/* use local flags */
79 
80 /*
81  * Flags used during fileopen(), ... by _fcons()/ _cvmod()
82  */
83 #define	FI_NONE		0x0000	/* no flags defined */
84 
85 #define	FI_READ		0x0001	/* open for reading */
86 #define	FI_WRITE	0x0002	/* open for writing */
87 #define	FI_BINARY	0x0004	/* open in binary mode */
88 #define	FI_APPEND	0x0008	/* append on each write */
89 
90 #define	FI_CREATE	0x0010	/* create if nessecary */
91 #define	FI_TRUNC	0x0020	/* truncate file on open */
92 #define	FI_UNBUF	0x0080	/* dont't buffer io */
93 #define	FI_CLOSE	0x1000	/* close file on error */
94 
95 /*
96  * Additional Schily FILE * flags that are not present with the
97  * standard stdio implementation.
98  */
99 #define	_JS_IONORAISE	01	/* do no raisecond() on errors */
100 #define	_JS_IOUNBUF	02	/* do unbuffered i/o */
101 
102 
103 #ifdef	DO_MYFLAG
104 
105 struct _io_flags {
106 	FILE	*fl_io;		/* file pointer */
107 	struct _io_flags	/* pointer to next struct */
108 		*fl_next;	/* if more file pointer to same fd */
109 	int	fl_flags;	/* my flags */
110 };
111 
112 typedef	struct _io_flags _io_fl;
113 
114 extern	int	_io_glflag;	/* global default flag */
115 extern	_io_fl	*_io_myfl;	/* array of structs to hold my flags */
116 extern	int	_fl_max;	/* max fd currently in _io_myfl */
117 
118 /*
119  *	if fileno > max
120  *		expand
121  *	else if map[fileno].pointer == 0
122  *		return 0
123  *	else if map[fileno].pointer == p
124  *		return map[fileno].flags
125  *	else
126  *		search list
127  */
128 #define	flp(p)		(&_io_myfl[fileno(p)])
129 
130 #ifdef	MY_FLAG_IS_MACRO
131 #define	my_flag(p)	((int)fileno(p) >= _fl_max ?			\
132 				_io_get_my_flag(p) :			\
133 			((flp(p)->fl_io == 0 || flp(p)->fl_io == p) ?	\
134 				flp(p)->fl_flags :			\
135 				_io_get_my_flag(p)))
136 #else
137 #define	my_flag(p)	_io_get_my_flag(p)
138 #endif
139 
140 #define	set_my_flag(p, v) _io_set_my_flag(p, v)
141 #define	add_my_flag(p, v) _io_add_my_flag(p, v)
142 
143 extern	int	_io_get_my_flag __PR((FILE *));
144 extern	void	_io_set_my_flag __PR((FILE *, int));
145 extern	void	_io_add_my_flag __PR((FILE *, int));
146 
147 #else	/* DO_MYFLAG */
148 
149 #define	my_flag(p)		_JS_IONORAISE	/* Always noraise */
150 #define	set_my_flag(p, v)			/* Ignore */
151 #define	add_my_flag(p, v)			/* Ignore */
152 
153 #endif	/* DO_MYFLAG */
154 
155 #if	defined(HAVE_USG_STDIO) || defined(FAST_GETC_PUTC)
156 /*
157  * We are on a system with AT&T compatible stdio implementation
158  */
159 
160 /*
161  * Use the right filbuf()/flsbuf() function.
162  */
163 #ifdef	FAST_GETC_PUTC
164 
165 #define	__c	(struct SCHILY__FILE_TAG *)
166 
167 #ifndef	HAVE___FILBUF
168 #define	HAVE___FILBUF
169 #endif
170 #endif
171 #ifdef	HAVE___FILBUF
172 #	define	usg_filbuf(fp)		__filbuf(fp)
173 #	define	usg_flsbuf(c, fp)	__flsbuf(c, fp)
174 /*
175  * Define prototypes to verify if our interface is right
176  */
177 extern	int	__filbuf		__PR((FILE *));
178 #else	/* !HAVE___FILBUF */
179 #	ifdef	HAVE__FILBUF
180 #	define	usg_filbuf(fp)		_filbuf(fp)
181 #	define	usg_flsbuf(c, fp)	_flsbuf(c, fp)
182 /*
183  * Define prototypes to verify if our interface is right
184  */
185 extern	int	_filbuf			__PR((FILE *));
186 #	else
187 /*
188  * no filbuf() but this will not happen on USG_STDIO systems.
189  */
190 #	endif
191 #endif	/* !HAVE___FILBUF */
192 /*
193  * Do not check this because flsbuf()'s 1st parameter may be
194  * int			SunOS
195  * unsigned int		Apollo
196  * unsigned char	HP-UX-11
197  *
198  * Note that the interface is now checked by autoconf.
199  */
200 #else	/* !HAVE_USG_STDIO */
201 /*
202  * If we are on a non USG system we cannot down file pointers
203  * and we do not know about the internals of the FILE structure.
204  */
205 #undef	DO_DOWN
206 #endif	/* !HAVE_USG_STDIO */
207 
208 #ifndef	__c
209 #define	__c
210 #endif
211 
212 #ifndef	DO_DOWN
213 /*
214  *	No stream checking
215  */
216 #define	down(f)
217 #define	down1(f, fl1)
218 #define	down2(f, fl1, fl2)
219 #else
220 /*
221  *	Do stream checking (works only on USG stdio)
222  *
223  *	New version of USG stdio.
224  *	_iob[] holds only a small amount of pointers.
225  *	Aditional space is allocated.
226  *	We may check only if the file pointer is != NULL
227  *	and if iop->_flag refers to a stream with appropriate modes.
228  *	If _iob[] gets expanded by malloc() we cannot check upper bound.
229  */
230 #define	down(f)		((f) == 0 || (__c f)->_flag == 0 ? \
231 				(raisecond(_badfile, 0L), (FILE *)0) : (f))
232 
233 #define	down1(f, fl1)	((f) == 0 || (__c f)->_flag == 0 ? \
234 					(raisecond(_badfile, 0L), (FILE *)0) : \
235 				(((__c f)->_flag & fl1) != fl1 ? \
236 					(raisecond(_badop, 0L), (FILE *)0) : \
237 					(f)))
238 
239 #define	down2(f, fl1, fl2)	((f) == 0 || (__c f)->_flag == 0 ? \
240 				(raisecond(_badfile, 0L), (FILE *)0) : \
241 				    (((__c f)->_flag & fl1) != fl1 && \
242 				    ((__c f)->_flag & fl2)  != fl2 ? \
243 				(raisecond(_badop, 0L), (FILE *)0) : \
244 				(f)))
245 #endif	/* DO_DOWN */
246 
247 extern	char	_badfile[];
248 extern	char	_badmode[];
249 extern	char	_badop[];
250 
251 #endif	/* _STDIO_SCHILYIO_H */
252