1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12 
13 /* @(#)schilyio.h	2.22 04/09/04 Copyright 1986, 1995-2003 J. Schilling */
14 /*
15  *	Copyright (c) 1986, 1995-2003 J. Schilling
16  */
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License version 2
20  * as published by the Free Software Foundation.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License along with
28  * this program; see the file COPYING.  If not, write to the Free Software
29  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30  */
31 
32 #ifndef	_STDIO_SCHILYIO_H
33 #define	_STDIO_SCHILYIO_H
34 
35 #include <mconfig.h>
36 #include <stdio.h>
37 #include <standard.h>
38 #include <unixstd.h>
39 #include <fctldefs.h>
40 #include <schily.h>
41 
42 #ifdef	NO_USG_STDIO
43 #	ifdef	HAVE_USG_STDIO
44 #		undef	HAVE_USG_STDIO
45 #	endif
46 #endif
47 
48 /*#if	_LFS_LARGEFILE*/
49 #ifdef	HAVE_LARGEFILES
50 /*
51  * XXX We may need to put this code to a more global place to allow all
52  * XXX users of fseek()/ftell() to automaticaly use fseeko()/ftello()
53  * XXX if the latter are available.
54  *
55  * If HAVE_LARGEFILES is defined, it is guaranteed that fseeko()/ftello()
56  * both are available.
57  */
58 #	define	fseek	fseeko
59 #	define	ftell	ftello
60 
61 #else	/* !HAVE_LARGEFILES */
62 /*
63  * If HAVE_LARGEFILES is not defined, we depend on specific tests for
64  * fseeko()/ftello() which must have been done before the tests for
65  * Large File support have been done.
66  * Note that this only works if the tests used below are really done before
67  * the Large File autoconf test is run. This is because autoconf does no
68  * clean testing but instead cumulatively modifes the envivonment used for
69  * testing.
70  */
71 #ifdef	HAVE_FSEEKO
72 #	define	fseek	fseeko
73 #endif
74 #ifdef	HAVE_FTELLO
75 #	define	ftell	ftello
76 #endif
77 
78 #endif
79 
80 /*
81  * speed things up...
82  */
83 #ifndef	_OPENFD_SRC
84 #ifdef	_openfd
85 #undef	_openfd
86 #endif
87 #define	_openfd(name, omode)	(open(name, omode, 0666))
88 #endif
89 
90 #define	DO_MYFLAG		/* use local flags */
91 
92 /*
93  * Flags used during fileopen(), ... by _fcons()/ _cvmod()
94  */
95 #define	FI_NONE		0x0000	/* no flags defined */
96 
97 #define	FI_READ		0x0001	/* open for reading */
98 #define	FI_WRITE	0x0002	/* open for writing */
99 #define	FI_BINARY	0x0004	/* open in binary mode */
100 #define	FI_APPEND	0x0008	/* append on each write */
101 
102 #define	FI_CREATE	0x0010	/* create if nessecary */
103 #define	FI_TRUNC	0x0020	/* truncate file on open */
104 #define	FI_UNBUF	0x0080	/* dont't buffer io */
105 #define	FI_CLOSE	0x1000	/* close file on error */
106 
107 /*
108  * local flags
109  */
110 #define	_IONORAISE	01	/* do no raisecond() on errors */
111 #define	_IOUNBUF	02	/* do unbuffered i/o */
112 
113 #ifdef	DO_MYFLAG
114 
115 struct _io_flags {
116 	FILE	*fl_io;		/* file pointer */
117 	struct _io_flags	/* pointer to next struct */
118 		*fl_next;	/* if more file pointer to same fd */
119 	int	fl_flags;	/* my flags */
120 };
121 
122 typedef	struct _io_flags _io_fl;
123 
124 extern	int	_io_glflag;	/* global default flag */
125 extern	_io_fl	*_io_myfl;	/* array of structs to hold my flags */
126 extern	int	_fl_max;	/* max fd currently in _io_myfl */
127 
128 /*
129  *	if fileno > max
130  *		expand
131  *	else if map[fileno].pointer == 0
132  *		return 0
133  *	else if map[fileno].pointer == p
134  *		return map[fileno].flags
135  *	else
136  *		search list
137  */
138 #define	flp(p)		(&_io_myfl[fileno(p)])
139 
140 #ifdef	MY_FLAG_IS_MACRO
141 #define	my_flag(p)	((int)fileno(p) >= _fl_max ?			\
142 				_io_get_my_flag(p) :			\
143 			((flp(p)->fl_io == 0 || flp(p)->fl_io == p) ?	\
144 				flp(p)->fl_flags :			\
145 				_io_get_my_flag(p)))
146 #else
147 #define	my_flag(p)	_io_get_my_flag(p)
148 #endif
149 
150 #define	set_my_flag(p, v) _io_set_my_flag(p, v)
151 #define	add_my_flag(p, v) _io_add_my_flag(p, v)
152 
153 extern	int	_io_get_my_flag __PR((FILE *));
154 extern	void	_io_set_my_flag __PR((FILE *, int));
155 extern	void	_io_add_my_flag __PR((FILE *, int));
156 
157 #else	/* DO_MYFLAG */
158 
159 #define	my_flag(p)		_IONORAISE	/* Always noraise */
160 #define	set_my_flag(p, v)			/* Ignore */
161 #define	add_my_flag(p, v)			/* Ignore */
162 
163 #endif	/* DO_MYFLAG */
164 
165 #ifdef	HAVE_USG_STDIO
166 
167 /*
168  * Use the right filbuf()/flsbuf() function.
169  */
170 #ifdef	HAVE___FILBUF
171 #	define	usg_filbuf(fp)		__filbuf(fp)
172 #	define	usg_flsbuf(c, fp)	__flsbuf(c, fp)
173 /*
174  * Define prototypes to verify if our interface is right
175  */
176 extern	int	__filbuf		__PR((FILE *));
177 /*extern	int	__flsbuf		__PR(());*/
178 #else
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 /*extern	int	_flsbuf			__PR(());*/
187 #	else
188 /*
189  * no filbuf() but this will not happen on USG_STDIO systems.
190  */
191 #	endif
192 #endif
193 /*
194  * Do not check this because flsbuf()'s 1st parameter may be
195  * int			SunOS
196  * unsigned int		Apollo
197  * unsigned char	HP-UX-11
198  *
199  * Note that the interface is now checked by autoconf.
200  */
201 /*extern	int	_flsbuf	__PR((int, FILE *));*/
202 #else
203 /*
204  * If we are on a non USG system we cannot down file pointers
205  */
206 #undef	DO_DOWN
207 #endif
208 
209 #ifndef	DO_DOWN
210 /*
211  *	No stream checking
212  */
213 #define	down(f)
214 #define	down1(f, fl1)
215 #define	down2(f, fl1, fl2)
216 #else
217 /*
218  *	Do stream checking (works only on USG stdio)
219  *
220  *	New version of USG stdio.
221  *	_iob[] holds only a small amount of pointers.
222  *	Aditional space is allocated.
223  *	We may check only if the file pointer is != NULL
224  *	and if iop->_flag refers to a stream with appropriate modes.
225  *	If _iob[] gets expanded by malloc() we cannot check upper bound.
226  */
227 #define	down(f)		((f) == 0 || (f)->_flag == 0 ? \
228 				(raisecond(_badfile, 0L), (FILE *)0) : (f))
229 
230 #define	down1(f, fl1)	((f) == 0 || (f)->_flag == 0 ? \
231 					(raisecond(_badfile, 0L), (FILE *)0) : \
232 				(((f)->_flag & fl1) != fl1 ? \
233 					(raisecond(_badop, 0L), (FILE *)0) : \
234 					(f)))
235 
236 #define	down2(f, fl1, fl2)	((f) == 0 || (f)->_flag == 0 ? \
237 				(raisecond(_badfile, 0L), (FILE *)0) : \
238 				    (((f)->_flag & fl1) != fl1 && \
239 				    ((f)->_flag & fl2)  != fl2 ? \
240 				(raisecond(_badop, 0L), (FILE *)0) : \
241 				(f)))
242 #endif	/* DO_DOWN */
243 
244 extern	char	_badfile[];
245 extern	char	_badmode[];
246 extern	char	_badop[];
247 
248 #endif	/* _STDIO_SCHILYIO_H */
249