66acb93bf45656c747f6ae0d70ea26973b92d974
[kopensolaris-gnu/glibc.git] / libio / libioP.h
1 /* Copyright (C) 1993, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU IO Library.
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License as
6    published by the Free Software Foundation; either version 2, or (at
7    your option) any later version.
8
9    This library is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this library; see the file COPYING.  If not, write to
16    the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17    MA 02111-1307, USA.
18
19    As a special exception, if you link this library with files
20    compiled with a GNU compiler to produce an executable, this does
21    not cause the resulting executable to be covered by the GNU General
22    Public License.  This exception does not however invalidate any
23    other reasons why the executable file might be covered by the GNU
24    General Public License.  */
25
26 #include <errno.h>
27 #include <bits/libc-lock.h>
28
29 #include "iolibio.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #define _IO_seek_set 0
36 #define _IO_seek_cur 1
37 #define _IO_seek_end 2
38
39 /* THE JUMPTABLE FUNCTIONS.
40
41  * The _IO_FILE type is used to implement the FILE type in GNU libc,
42  * as well as the streambuf class in GNU iostreams for C++.
43  * These are all the same, just used differently.
44  * An _IO_FILE (or FILE) object is allows followed by a pointer to
45  * a jump table (of pointers to functions).  The pointer is accessed
46  * with the _IO_JUMPS macro.  The jump table has a eccentric format,
47  * so as to be compatible with the layout of a C++ virtual function table.
48  * (as implemented by g++).  When a pointer to a streambuf object is
49  * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just
50  * happens to point to the virtual function table of the streambuf.
51  * Thus the _IO_JUMPS function table used for C stdio/libio does
52  * double duty as the virtual function table for C++ streambuf.
53  *
54  * The entries in the _IO_JUMPS function table (and hence also the
55  * virtual functions of a streambuf) are described below.
56  * The first parameter of each function entry is the _IO_FILE/streambuf
57  * object being acted on (i.e. the 'this' parameter).
58  */
59
60 #define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable
61 #ifdef _G_USING_THUNKS
62 # define JUMP_FIELD(TYPE, NAME) TYPE NAME
63 # define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC (THIS)
64 # define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC (THIS, X1)
65 # define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC (THIS, X1, X2)
66 # define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC (THIS, X1,X2, X3)
67 # define JUMP_INIT(NAME, VALUE) VALUE
68 # define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0)
69 #else
70 /* These macros will change when we re-implement vtables to use "thunks"! */
71 # define JUMP_FIELD(TYPE, NAME) struct { short delta1, delta2; TYPE pfn; } NAME
72 # define JUMP0(FUNC, THIS) _IO_JUMPS(THIS)->FUNC.pfn (THIS)
73 # define JUMP1(FUNC, THIS, X1) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1)
74 # define JUMP2(FUNC, THIS, X1, X2) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1, X2)
75 # define JUMP3(FUNC, THIS, X1,X2,X3) _IO_JUMPS(THIS)->FUNC.pfn (THIS, X1,X2,X3)
76 # define JUMP_INIT(NAME, VALUE) {0, 0, VALUE}
77 # define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0)
78 #endif
79
80 /* The 'finish' function does any final cleaning up of an _IO_FILE object.
81    It does not delete (free) it, but does everything else to finalize it/
82    It matches the streambuf::~streambuf virtual destructor.  */
83 typedef void (*_IO_finish_t) __P ((_IO_FILE *, int)); /* finalize */
84 #define _IO_FINISH(FP) JUMP1 (__finish, FP, 0)
85
86 /* The 'overflow' hook flushes the buffer.
87    The second argument is a character, or EOF.
88    It matches the streambuf::overflow virtual function. */
89 typedef int (*_IO_overflow_t) __P ((_IO_FILE *, int));
90 #define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH)
91
92 /* The 'underflow' hook tries to fills the get buffer.
93    It returns the next character (as an unsigned char) or EOF.  The next
94    character remains in the get buffer, and the get position is not changed.
95    It matches the streambuf::underflow virtual function. */
96 typedef int (*_IO_underflow_t) __P ((_IO_FILE *));
97 #define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP)
98
99 /* The 'uflow' hook returns the next character in the input stream
100    (cast to unsigned char), and increments the read position;
101    EOF is returned on failure.
102    It matches the streambuf::uflow virtual function, which is not in the
103    cfront implementation, but was added to C++ by the ANSI/ISO committee. */
104 #define _IO_UFLOW(FP) JUMP0 (__uflow, FP)
105
106 /* The 'pbackfail' hook handles backing up.
107    It matches the streambuf::pbackfail virtual function. */
108 typedef int (*_IO_pbackfail_t) __P ((_IO_FILE *, int));
109 #define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH)
110
111 /* The 'xsputn' hook writes upto N characters from buffer DATA.
112    Returns the number of character actually written.
113    It matches the streambuf::xsputn virtual function. */
114 typedef _IO_size_t (*_IO_xsputn_t) __P ((_IO_FILE *FP, const void *DATA,
115                                          _IO_size_t N));
116 #define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N)
117
118 /* The 'xsgetn' hook reads upto N characters into buffer DATA.
119    Returns the number of character actually read.
120    It matches the streambuf::xsgetn virtual function. */
121 typedef _IO_size_t (*_IO_xsgetn_t) __P ((_IO_FILE *FP, void *DATA,
122                                          _IO_size_t N));
123 #define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N)
124
125 /* The 'seekoff' hook moves the stream position to a new position
126    relative to the start of the file (if DIR==0), the current position
127    (MODE==1), or the end of the file (MODE==2).
128    It matches the streambuf::seekoff virtual function.
129    It is also used for the ANSI fseek function. */
130 typedef _IO_fpos_t (*_IO_seekoff_t) __P ((_IO_FILE *FP, _IO_off_t OFF,
131                                           int DIR, int MODE));
132 #define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE)
133
134 /* The 'seekpos' hook also moves the stream position,
135    but to an absolute position given by a fpos_t (seekpos).
136    It matches the streambuf::seekpos virtual function.
137    It is also used for the ANSI fgetpos and fsetpos functions.  */
138 /* The _IO_seek_cur and _IO_seek_end options are not allowed. */
139 typedef _IO_fpos_t (*_IO_seekpos_t) __P ((_IO_FILE *, _IO_fpos_t, int));
140 #define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS)
141
142 /* The 'setbuf' hook gives a buffer to the file.
143    It matches the streambuf::setbuf virtual function. */
144 typedef _IO_FILE* (*_IO_setbuf_t) __P ((_IO_FILE *, char *, _IO_ssize_t));
145 #define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH)
146
147 /* The 'sync' hook attempts to synchronize the internal data structures
148    of the file with the external state.
149    It matches the streambuf::sync virtual function. */
150 typedef int (*_IO_sync_t) __P ((_IO_FILE *));
151 #define _IO_SYNC(FP) JUMP0 (__sync, FP)
152
153 /* The 'doallocate' hook is used to tell the file to allocate a buffer.
154    It matches the streambuf::doallocate virtual function, which is not
155    in the ANSI/ISO C++ standard, but is part traditional implementations. */
156 typedef int (*_IO_doallocate_t) __P ((_IO_FILE *));
157 #define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP)
158
159 /* The following four hooks (sysread, syswrite, sysclose, sysseek, and
160    sysstat) are low-level hooks specific to this implementation.
161    There is no correspondence in the ANSI/ISO C++ standard library.
162    The hooks basically correspond to the Unix system functions
163    (read, write, close, lseek, and stat) except that a _IO_FILE*
164    parameter is used instead of a integer file descriptor;  the default
165    implementation used for normal files just calls those functions.
166    The advantage of overriding these functions instead of the higher-level
167    ones (underflow, overflow etc) is that you can leave all the buffering
168    higher-level functions.  */
169
170 /* The 'sysread' hook is used to read data from the external file into
171    an existing buffer.  It generalizes the Unix read(2) function.
172    It matches the streambuf::sys_read virtual function, which is
173    specific to this implementation. */
174 typedef _IO_ssize_t (*_IO_read_t) __P ((_IO_FILE *, void *, _IO_ssize_t));
175 #define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN)
176
177 /* The 'syswrite' hook is used to write data from an existing buffer
178    to an external file.  It generalizes the Unix write(2) function.
179    It matches the streambuf::sys_write virtual function, which is
180    specific to this implementation. */
181 typedef _IO_ssize_t (*_IO_write_t) __P ((_IO_FILE *,const void *,_IO_ssize_t));
182 #define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN)
183
184 /* The 'sysseek' hook is used to re-position an external file.
185    It generalizes the Unix lseek(2) function.
186    It matches the streambuf::sys_seek virtual function, which is
187    specific to this implementation. */
188 typedef _IO_fpos_t (*_IO_seek_t) __P ((_IO_FILE *, _IO_off_t, int));
189 #define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE)
190
191 /* The 'sysclose' hook is used to finalize (close, finish up) an
192    external file.  It generalizes the Unix close(2) function.
193    It matches the streambuf::sys_close virtual function, which is
194    specific to this implementation. */
195 typedef int (*_IO_close_t) __P ((_IO_FILE *)); /* finalize */
196 #define _IO_SYSCLOSE(FP) JUMP0 (__close, FP)
197
198 /* The 'sysstat' hook is used to get information about an external file
199    into a struct stat buffer.  It generalizes the Unix fstat(2) call.
200    It matches the streambuf::sys_stat virtual function, which is
201    specific to this implementation. */
202 typedef int (*_IO_stat_t) __P ((_IO_FILE *, void *));
203 #define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF)
204
205
206 #define _IO_CHAR_TYPE char /* unsigned char ? */
207 #define _IO_INT_TYPE int
208
209 struct _IO_jump_t
210 {
211     JUMP_FIELD(_G_size_t, __dummy);
212 #ifdef _G_USING_THUNKS
213     JUMP_FIELD(_G_size_t, __dummy2);
214 #endif
215     JUMP_FIELD(_IO_finish_t, __finish);
216     JUMP_FIELD(_IO_overflow_t, __overflow);
217     JUMP_FIELD(_IO_underflow_t, __underflow);
218     JUMP_FIELD(_IO_underflow_t, __uflow);
219     JUMP_FIELD(_IO_pbackfail_t, __pbackfail);
220     /* showmany */
221     JUMP_FIELD(_IO_xsputn_t, __xsputn);
222     JUMP_FIELD(_IO_xsgetn_t, __xsgetn);
223     JUMP_FIELD(_IO_seekoff_t, __seekoff);
224     JUMP_FIELD(_IO_seekpos_t, __seekpos);
225     JUMP_FIELD(_IO_setbuf_t, __setbuf);
226     JUMP_FIELD(_IO_sync_t, __sync);
227     JUMP_FIELD(_IO_doallocate_t, __doallocate);
228     JUMP_FIELD(_IO_read_t, __read);
229     JUMP_FIELD(_IO_write_t, __write);
230     JUMP_FIELD(_IO_seek_t, __seek);
231     JUMP_FIELD(_IO_close_t, __close);
232     JUMP_FIELD(_IO_stat_t, __stat);
233 #if 0
234     get_column;
235     set_column;
236 #endif
237 };
238
239 /* We always allocate an extra word following an _IO_FILE.
240    This contains a pointer to the function jump table used.
241    This is for compatibility with C++ streambuf; the word can
242    be used to smash to a pointer to a virtual function table. */
243
244 struct _IO_FILE_plus
245 {
246   _IO_FILE file;
247   const struct _IO_jump_t *vtable;
248 };
249
250 /* Generic functions */
251
252 extern _IO_fpos_t _IO_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
253 extern _IO_fpos_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
254
255 extern void _IO_switch_to_main_get_area __P ((_IO_FILE *));
256 extern void _IO_switch_to_backup_area __P ((_IO_FILE *));
257 extern int _IO_switch_to_get_mode __P ((_IO_FILE *));
258 extern void _IO_init __P ((_IO_FILE *, int));
259 extern int _IO_sputbackc __P ((_IO_FILE *, int));
260 extern int _IO_sungetc __P ((_IO_FILE *));
261 extern void _IO_un_link __P ((_IO_FILE *));
262 extern void _IO_link_in __P ((_IO_FILE *));
263 extern void _IO_doallocbuf __P ((_IO_FILE *));
264 extern void _IO_unsave_markers __P ((_IO_FILE *));
265 extern void _IO_setb __P ((_IO_FILE *, char *, char *, int));
266 extern unsigned _IO_adjust_column __P ((unsigned, const char *, int));
267 #define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n)
268
269 /* Marker-related function. */
270
271 extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *));
272 extern void _IO_remove_marker __P ((struct _IO_marker *));
273 extern int _IO_marker_difference __P ((struct _IO_marker *,
274                                        struct _IO_marker *));
275 extern int _IO_marker_delta __P ((struct _IO_marker *));
276 extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int));
277
278 /* Default jumptable functions. */
279
280 extern int _IO_default_underflow __P ((_IO_FILE *));
281 extern int _IO_default_uflow __P ((_IO_FILE *));
282 extern int _IO_default_doallocate __P ((_IO_FILE *));
283 extern void _IO_default_finish __P ((_IO_FILE *, int));
284 extern int _IO_default_pbackfail __P ((_IO_FILE *, int));
285 extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
286 extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *,
287                                            _IO_size_t));
288 extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
289 extern _IO_fpos_t _IO_default_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
290 extern _IO_fpos_t _IO_default_seekpos __P ((_IO_FILE *, _IO_fpos_t, int));
291 extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *,
292                                            _IO_ssize_t));
293 extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t));
294 extern int _IO_default_stat __P ((_IO_FILE *, void *));
295 extern _IO_fpos_t _IO_default_seek __P ((_IO_FILE *, _IO_off_t, int));
296 extern int _IO_default_sync __P ((_IO_FILE *));
297 #define _IO_default_close ((_IO_close_t) _IO_default_sync)
298
299 extern struct _IO_jump_t _IO_file_jumps;
300 extern struct _IO_jump_t _IO_streambuf_jumps;
301 extern struct _IO_jump_t _IO_proc_jumps;
302 extern struct _IO_jump_t _IO_str_jumps;
303 extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
304 extern int _IO_flush_all __P ((void));
305 extern void _IO_cleanup __P ((void));
306 extern void _IO_flush_all_linebuffered __P ((void));
307
308 #define _IO_do_flush(_f) \
309   _IO_do_write(_f, (_f)->_IO_write_base, \
310                (_f)->_IO_write_ptr-(_f)->_IO_write_base)
311 #define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING)
312 #define _IO_mask_flags(fp, f, mask) \
313        ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
314 #define _IO_setg(fp, eb, g, eg)  ((fp)->_IO_read_base = (eb),\
315         (fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg))
316 #define _IO_setp(__fp, __p, __ep) \
317        ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep))
318 #define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
319 #define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
320 #define _IO_have_markers(fp) ((fp)->_markers != NULL)
321 #define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
322
323 /* Jumptable functions for files. */
324
325 extern int _IO_file_doallocate __P ((_IO_FILE *));
326 extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
327 extern _IO_fpos_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
328 extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
329 extern int _IO_file_stat __P ((_IO_FILE *, void *));
330 extern int _IO_file_close __P ((_IO_FILE *));
331 extern int _IO_file_underflow __P ((_IO_FILE *));
332 extern int _IO_file_overflow __P ((_IO_FILE *, int));
333 #define _IO_file_is_open(__fp) ((__fp)->_fileno >= 0)
334 extern void _IO_file_init __P ((_IO_FILE *));
335 extern _IO_FILE* _IO_file_attach __P ((_IO_FILE *, int));
336 extern _IO_FILE* _IO_file_fopen __P ((_IO_FILE *, const char *, const char *));
337 extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *,
338                                         _IO_ssize_t));
339 extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t));
340 extern int _IO_file_sync __P ((_IO_FILE *));
341 extern int _IO_file_close_it __P ((_IO_FILE *));
342 extern _IO_fpos_t _IO_file_seek __P ((_IO_FILE *, _IO_off_t, int));
343 extern void _IO_file_finish __P ((_IO_FILE *, int));
344
345 /* Jumptable functions for proc_files. */
346 extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *));
347 extern int _IO_proc_close __P ((_IO_FILE *));
348
349 /* Jumptable functions for strfiles. */
350 extern int _IO_str_underflow __P ((_IO_FILE *));
351 extern int _IO_str_overflow __P ((_IO_FILE *, int));
352 extern int _IO_str_pbackfail __P ((_IO_FILE *, int));
353 extern _IO_fpos_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off_t, int, int));
354 extern void _IO_str_finish __P ((_IO_FILE *, int));
355
356 /* Other strfile functions */
357 extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *));
358 extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int));
359 extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *));
360
361 extern int _IO_vasprintf __P ((char **result_ptr, __const char *format,
362                                _IO_va_list args));
363 extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg));
364 extern int _IO_vsnprintf __P ((char *string, _IO_size_t maxlen,
365                                __const char *format, _IO_va_list args));
366
367
368 extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int));
369 extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *));
370 extern double _IO_strtod __P ((const char *, char **));
371 extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits,
372                             int *__decpt, int *__sign, char **__rve));
373 extern int _IO_outfloat __P ((double __value, _IO_FILE *__sb, int __type,
374                               int __width, int __precision, int __flags,
375                               int __sign_mode, int __fill));
376
377 extern _IO_FILE *_IO_list_all;
378 extern void (*_IO_cleanup_registration_needed) __P ((void));
379
380 #ifndef EOF
381 # define EOF (-1)
382 #endif
383 #ifndef NULL
384 # if defined __GNUG__ && \
385     (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8))
386 #  define NULL (__null)
387 # else
388 #  if !defined(__cplusplus)
389 #   define NULL ((void*)0)
390 #  else
391 #   define NULL (0)
392 #  endif
393 # endif
394 #endif
395
396 #if _G_HAVE_MMAP
397
398 # include <unistd.h>
399 # include <fcntl.h>
400 # include <sys/mman.h>
401 # include <sys/param.h>
402
403 # if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
404 #  define MAP_ANONYMOUS MAP_ANON
405 # endif
406
407 # if !defined(MAP_ANONYMOUS) || !defined(EXEC_PAGESIZE)
408 #  undef _G_HAVE_MMAP
409 #  define _G_HAVE_MMAP 0
410 # endif
411
412 #endif /* _G_HAVE_MMAP */
413
414 #if _G_HAVE_MMAP
415
416 # ifdef _LIBC
417 /* When using this code in the GNU libc we must not pollute the name space.  */
418 #  define mmap __mmap
419 #  define munmap __munmap
420 # endif
421
422 # define ROUND_TO_PAGE(_S) \
423        (((_S) + EXEC_PAGESIZE - 1) & ~(EXEC_PAGESIZE - 1))
424
425 # define FREE_BUF(_B, _S) \
426        munmap ((_B), ROUND_TO_PAGE (_S))
427 # define ALLOC_BUF(_B, _S, _R) \
428        do {                                                                   \
429           (_B) = (char *) mmap (0, ROUND_TO_PAGE (_S),                        \
430                                 PROT_READ | PROT_WRITE,                       \
431                                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);          \
432           if ((_B) == (char *) -1)                                            \
433             return (_R);                                                      \
434        } while (0)
435
436 #else /* _G_HAVE_MMAP */
437
438 # define FREE_BUF(_B, _S) \
439        free(_B)
440 # define ALLOC_BUF(_B, _S, _R) \
441        do {                                                                   \
442           (_B) = (char*)malloc(_S);                                           \
443           if ((_B) == NULL)                                                   \
444             return (_R);                                                      \
445        } while (0)
446
447 #endif /* _G_HAVE_MMAP */
448
449 #ifndef OS_FSTAT
450 # define OS_FSTAT fstat
451 #endif
452 struct stat;
453 extern _IO_ssize_t _IO_read __P ((int, void *, _IO_size_t));
454 extern _IO_ssize_t _IO_write __P ((int, const void *, _IO_size_t));
455 extern _IO_off_t _IO_lseek __P ((int, _IO_off_t, int));
456 extern int _IO_close __P ((int));
457 extern int _IO_fstat __P ((int, struct stat *));
458 extern int _IO_vscanf __P ((const char *, _IO_va_list));
459
460 /* Operations on _IO_fpos_t.
461    Normally, these are trivial, but we provide hooks for configurations
462    where an _IO_fpos_t is a struct.
463    Note that _IO_off_t must be an integral type. */
464
465 /* _IO_pos_BAD is an _IO_fpos_t value indicating error, unknown, or EOF. */
466 #ifndef _IO_pos_BAD
467 # define _IO_pos_BAD ((_IO_fpos_t) -1)
468 #endif
469 /* _IO_pos_as_off converts an _IO_fpos_t value to an _IO_off_t value. */
470 #ifndef _IO_pos_as_off
471 # define _IO_pos_as_off(__pos) ((_IO_off_t) (__pos))
472 #endif
473 /* _IO_pos_adjust adjust an _IO_fpos_t by some number of bytes. */
474 #ifndef _IO_pos_adjust
475 # define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta))
476 #endif
477 /* _IO_pos_0 is an _IO_fpos_t value indicating beginning of file. */
478 #ifndef _IO_pos_0
479 # define _IO_pos_0 ((_IO_fpos_t) 0)
480 #endif
481
482 #ifdef __cplusplus
483 }
484 #endif
485
486 #ifdef _IO_MTSAFE_IO
487 /* check following! */
488 # define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
489        { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
490          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
491            0, 0, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
492 #else
493 /* check following! */
494 # define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
495        { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
496            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD }
497 #endif
498
499 /* VTABLE_LABEL defines NAME as of the CLASS class.
500    CNLENGTH is strlen(#CLASS).  */
501 #ifdef __GNUC__
502 # if _G_VTABLE_LABEL_HAS_LENGTH
503 #  define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
504   extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CNLENGTH #CLASS);
505 # else
506 #  define VTABLE_LABEL(NAME, CLASS, CNLENGTH) \
507   extern char NAME[] asm (_G_VTABLE_LABEL_PREFIX #CLASS);
508 # endif
509 #endif /* __GNUC__ */
510
511 #if !defined(builtinbuf_vtable) && defined(__cplusplus)
512 # ifdef __GNUC__
513 VTABLE_LABEL(builtinbuf_vtable, builtinbuf, 10)
514 # else
515 #  if _G_VTABLE_LABEL_HAS_LENGTH
516 #   define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##10builtinbuf
517 #  else
518 #   define builtinbuf_vtable _G_VTABLE_LABEL_PREFIX_ID##builtinbuf
519 #  endif
520 # endif
521 #endif /* !defined(builtinbuf_vtable) && defined(__cplusplus) */
522
523 #if defined(__STDC__) || defined(__cplusplus)
524 # define _IO_va_start(args, last) va_start(args, last)
525 #else
526 # define _IO_va_start(args, last) va_start(args)
527 #endif
528
529 extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
530
531 #if 1
532 # define COERCE_FILE(FILE) /* Nothing */
533 #else
534 /* This is part of the kludge for binary compatibility with old stdio. */
535 # define COERCE_FILE(FILE) \
536   (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \
537     && (FILE) = *(FILE**)&((int*)fp)[1])
538 #endif
539
540 #ifdef EINVAL
541 # define MAYBE_SET_EINVAL __set_errno (EINVAL)
542 #else
543 # define MAYBE_SET_EINVAL /* nothing */
544 #endif
545
546 #ifdef IO_DEBUG
547 # define CHECK_FILE(FILE, RET) \
548         if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \
549         else { COERCE_FILE(FILE); \
550                if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \
551           { MAYBE_SET_EINVAL; return RET; }}
552 #else
553 # define CHECK_FILE(FILE, RET) COERCE_FILE (FILE)
554 #endif