]> git.ipfire.org Git - thirdparty/glibc.git/blob - libio/fileops.c
fa4c8e0fa812092e131d076a68b1313d2d4fc559
[thirdparty/glibc.git] / libio / fileops.c
1 /* Copyright (C) 1993, 1995, 1997-2001, 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA.
19
20 As a special exception, if you link the code in this file with
21 files compiled with a GNU compiler to produce an executable,
22 that does not cause the resulting executable to be covered by
23 the GNU Lesser General Public License. This exception does not
24 however invalidate any other reasons why the executable file
25 might be covered by the GNU Lesser General Public License.
26 This exception applies to code released by its copyright holders
27 in files containing the exception. */
28
29
30 #ifndef _POSIX_SOURCE
31 # define _POSIX_SOURCE
32 #endif
33 #include "libioP.h"
34 #include <assert.h>
35 #include <fcntl.h>
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #ifdef __STDC__
43 #include <stdlib.h>
44 #endif
45 #if _LIBC
46 # include "../wcsmbs/wcsmbsload.h"
47 # include "../iconv/gconv_charset.h"
48 # include "../iconv/gconv_int.h"
49 # include <shlib-compat.h>
50 #endif
51 #ifndef errno
52 extern int errno;
53 #endif
54 #ifndef __set_errno
55 # define __set_errno(Val) errno = (Val)
56 #endif
57
58
59 #ifdef _LIBC
60 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
61 # define close(FD) __close (FD)
62 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
63 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
64 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
65 #else
66 # define _IO_new_do_write _IO_do_write
67 # define _IO_new_file_attach _IO_file_attach
68 # define _IO_new_file_close_it _IO_file_close_it
69 # define _IO_new_file_finish _IO_file_finish
70 # define _IO_new_file_fopen _IO_file_fopen
71 # define _IO_new_file_init _IO_file_init
72 # define _IO_new_file_setbuf _IO_file_setbuf
73 # define _IO_new_file_sync _IO_file_sync
74 # define _IO_new_file_overflow _IO_file_overflow
75 # define _IO_new_file_seekoff _IO_file_seekoff
76 # define _IO_new_file_underflow _IO_file_underflow
77 # define _IO_new_file_write _IO_file_write
78 # define _IO_new_file_xsputn _IO_file_xsputn
79 #endif
80
81
82 #ifdef _LIBC
83 extern struct __gconv_trans_data __libio_translit attribute_hidden;
84 #endif
85
86
87 /* An fstream can be in at most one of put mode, get mode, or putback mode.
88 Putback mode is a variant of get mode.
89
90 In a filebuf, there is only one current position, instead of two
91 separate get and put pointers. In get mode, the current position
92 is that of gptr(); in put mode that of pptr().
93
94 The position in the buffer that corresponds to the position
95 in external file system is normally _IO_read_end, except in putback
96 mode, when it is _IO_save_end.
97 If the field _fb._offset is >= 0, it gives the offset in
98 the file as a whole corresponding to eGptr(). (?)
99
100 PUT MODE:
101 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
102 and _IO_read_base are equal to each other. These are usually equal
103 to _IO_buf_base, though not necessarily if we have switched from
104 get mode to put mode. (The reason is to maintain the invariant
105 that _IO_read_end corresponds to the external file position.)
106 _IO_write_base is non-NULL and usually equal to _IO_base_base.
107 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
108 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
109
110 GET MODE:
111 If a filebuf is in get or putback mode, eback() != egptr().
112 In get mode, the unread characters are between gptr() and egptr().
113 The OS file position corresponds to that of egptr().
114
115 PUTBACK MODE:
116 Putback mode is used to remember "excess" characters that have
117 been sputbackc'd in a separate putback buffer.
118 In putback mode, the get buffer points to the special putback buffer.
119 The unread characters are the characters between gptr() and egptr()
120 in the putback buffer, as well as the area between save_gptr()
121 and save_egptr(), which point into the original reserve buffer.
122 (The pointers save_gptr() and save_egptr() are the values
123 of gptr() and egptr() at the time putback mode was entered.)
124 The OS position corresponds to that of save_egptr().
125
126 LINE BUFFERED OUTPUT:
127 During line buffered output, _IO_write_base==base() && epptr()==base().
128 However, ptr() may be anywhere between base() and ebuf().
129 This forces a call to filebuf::overflow(int C) on every put.
130 If there is more space in the buffer, and C is not a '\n',
131 then C is inserted, and pptr() incremented.
132
133 UNBUFFERED STREAMS:
134 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
135 */
136
137 #define CLOSED_FILEBUF_FLAGS \
138 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
139
140
141 void
142 _IO_new_file_init (fp)
143 struct _IO_FILE_plus *fp;
144 {
145 /* POSIX.1 allows another file handle to be used to change the position
146 of our file descriptor. Hence we actually don't know the actual
147 position before we do the first fseek (and until a following fflush). */
148 fp->file._offset = _IO_pos_BAD;
149 fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
150
151 INTUSE(_IO_link_in) (fp);
152 fp->file._fileno = -1;
153 }
154 INTDEF2(_IO_new_file_init, _IO_file_init)
155
156 int
157 _IO_new_file_close_it (fp)
158 _IO_FILE *fp;
159 {
160 int write_status, close_status;
161 if (!_IO_file_is_open (fp))
162 return EOF;
163
164 if ((fp->_flags & _IO_NO_WRITES) == 0
165 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
166 write_status = _IO_do_flush (fp);
167 else
168 write_status = 0;
169
170 INTUSE(_IO_unsave_markers) (fp);
171
172 close_status = _IO_SYSCLOSE (fp);
173
174 /* Free buffer. */
175 if (fp->_mode <= 0)
176 {
177 INTUSE(_IO_setb) (fp, NULL, NULL, 0);
178 _IO_setg (fp, NULL, NULL, NULL);
179 _IO_setp (fp, NULL, NULL);
180 }
181 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
182 else
183 {
184 if (_IO_have_wbackup (fp))
185 INTUSE(_IO_free_wbackup_area) (fp);
186 INTUSE(_IO_wsetb) (fp, NULL, NULL, 0);
187 _IO_wsetg (fp, NULL, NULL, NULL);
188 _IO_wsetp (fp, NULL, NULL);
189 }
190 #endif
191
192 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
193 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
194 fp->_fileno = -1;
195 fp->_offset = _IO_pos_BAD;
196
197 return close_status ? close_status : write_status;
198 }
199 INTDEF2(_IO_new_file_close_it, _IO_file_close_it)
200
201 void
202 _IO_new_file_finish (fp, dummy)
203 _IO_FILE *fp;
204 int dummy;
205 {
206 if (_IO_file_is_open (fp))
207 {
208 _IO_do_flush (fp);
209 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
210 _IO_SYSCLOSE (fp);
211 }
212 INTUSE(_IO_default_finish) (fp, 0);
213 }
214 INTDEF2(_IO_new_file_finish, _IO_file_finish)
215
216 #if defined __GNUC__ && __GNUC__ >= 2
217 __inline__
218 #endif
219 _IO_FILE *
220 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
221 _IO_FILE *fp;
222 const char *filename;
223 int posix_mode;
224 int prot;
225 int read_write;
226 int is32not64;
227 {
228 int fdesc;
229 #ifdef _G_OPEN64
230 fdesc = (is32not64
231 ? open (filename, posix_mode, prot)
232 : _G_OPEN64 (filename, posix_mode, prot));
233 #else
234 fdesc = open (filename, posix_mode, prot);
235 #endif
236 if (fdesc < 0)
237 return NULL;
238 fp->_fileno = fdesc;
239 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
240 if (read_write & _IO_IS_APPENDING)
241 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
242 == _IO_pos_BAD && errno != ESPIPE)
243 {
244 close (fdesc);
245 return NULL;
246 }
247 INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp);
248 return fp;
249 }
250
251 _IO_FILE *
252 _IO_new_file_fopen (fp, filename, mode, is32not64)
253 _IO_FILE *fp;
254 const char *filename;
255 const char *mode;
256 int is32not64;
257 {
258 int oflags = 0, omode;
259 int read_write;
260 int oprot = 0666;
261 int i;
262 _IO_FILE *result;
263 #ifdef _LIBC
264 const char *cs;
265 const char *last_recognized;
266 #endif
267
268 if (_IO_file_is_open (fp))
269 return 0;
270 switch (*mode)
271 {
272 case 'r':
273 omode = O_RDONLY;
274 read_write = _IO_NO_WRITES;
275 break;
276 case 'w':
277 omode = O_WRONLY;
278 oflags = O_CREAT|O_TRUNC;
279 read_write = _IO_NO_READS;
280 break;
281 case 'a':
282 omode = O_WRONLY;
283 oflags = O_CREAT|O_APPEND;
284 read_write = _IO_NO_READS|_IO_IS_APPENDING;
285 break;
286 default:
287 __set_errno (EINVAL);
288 return NULL;
289 }
290 #ifdef _LIBC
291 last_recognized = mode;
292 #endif
293 for (i = 1; i < 4; ++i)
294 {
295 switch (*++mode)
296 {
297 case '\0':
298 break;
299 case '+':
300 omode = O_RDWR;
301 read_write &= _IO_IS_APPENDING;
302 #ifdef _LIBC
303 last_recognized = mode;
304 #endif
305 continue;
306 case 'x':
307 oflags |= O_EXCL;
308 #ifdef _LIBC
309 last_recognized = mode;
310 #endif
311 continue;
312 case 'b':
313 #ifdef _LIBC
314 last_recognized = mode;
315 #endif
316 default:
317 /* Ignore. */
318 continue;
319 }
320 break;
321 }
322
323 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
324 is32not64);
325
326
327 #ifdef _LIBC
328 if (result != NULL)
329 {
330 /* Test whether the mode string specifies the conversion. */
331 cs = strstr (last_recognized + 1, ",ccs=");
332 if (cs != NULL)
333 {
334 /* Yep. Load the appropriate conversions and set the orientation
335 to wide. */
336 struct gconv_fcts fcts;
337 struct _IO_codecvt *cc;
338 char *endp = __strchrnul (cs + 5, ',');
339 char ccs[endp - (cs + 5) + 3];
340
341 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
342 strip (ccs, ccs);
343
344 if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
345 ? upstr (ccs, cs + 5) : ccs) != 0)
346 {
347 /* Something went wrong, we cannot load the conversion modules.
348 This means we cannot proceed since the user explicitly asked
349 for these. */
350 __set_errno (EINVAL);
351 return NULL;
352 }
353
354 assert (fcts.towc_nsteps == 1);
355 assert (fcts.tomb_nsteps == 1);
356
357 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
358 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
359
360 /* Clear the state. We start all over again. */
361 memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
362 memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
363
364 cc = fp->_codecvt = &fp->_wide_data->_codecvt;
365
366 /* The functions are always the same. */
367 *cc = __libio_codecvt;
368
369 cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
370 cc->__cd_in.__cd.__steps = fcts.towc;
371
372 cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
373 cc->__cd_in.__cd.__data[0].__internal_use = 1;
374 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
375 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
376
377 /* XXX For now no transliteration. */
378 cc->__cd_in.__cd.__data[0].__trans = NULL;
379
380 cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
381 cc->__cd_out.__cd.__steps = fcts.tomb;
382
383 cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
384 cc->__cd_out.__cd.__data[0].__internal_use = 1;
385 cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
386 cc->__cd_out.__cd.__data[0].__statep =
387 &result->_wide_data->_IO_state;
388
389 /* And now the transliteration. */
390 cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
391
392 /* Set the mode now. */
393 result->_mode = 1;
394
395 /* We don't need the step data structure anymore. */
396 __gconv_release_cache (fcts.towc, fcts.towc_nsteps);
397 __gconv_release_cache (fcts.tomb, fcts.tomb_nsteps);
398 }
399 }
400 #endif /* GNU libc */
401
402 return result;
403 }
404 INTDEF2(_IO_new_file_fopen, _IO_file_fopen)
405
406 _IO_FILE *
407 _IO_new_file_attach (fp, fd)
408 _IO_FILE *fp;
409 int fd;
410 {
411 if (_IO_file_is_open (fp))
412 return NULL;
413 fp->_fileno = fd;
414 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
415 fp->_flags |= _IO_DELETE_DONT_CLOSE;
416 /* Get the current position of the file. */
417 /* We have to do that since that may be junk. */
418 fp->_offset = _IO_pos_BAD;
419 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
420 == _IO_pos_BAD && errno != ESPIPE)
421 return NULL;
422 return fp;
423 }
424 INTDEF2(_IO_new_file_attach, _IO_file_attach)
425
426 _IO_FILE *
427 _IO_new_file_setbuf (fp, p, len)
428 _IO_FILE *fp;
429 char *p;
430 _IO_ssize_t len;
431 {
432 if (_IO_default_setbuf (fp, p, len) == NULL)
433 return NULL;
434
435 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
436 = fp->_IO_buf_base;
437 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
438
439 return fp;
440 }
441 INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf)
442
443
444 _IO_FILE *
445 _IO_file_setbuf_mmap (fp, p, len)
446 _IO_FILE *fp;
447 char *p;
448 _IO_ssize_t len;
449 {
450 _IO_FILE *result;
451
452 /* Change the function table. */
453 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
454 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
455
456 /* And perform the normal operation. */
457 result = _IO_new_file_setbuf (fp, p, len);
458
459 /* If the call failed, restore to using mmap. */
460 if (result == NULL)
461 {
462 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
463 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
464 }
465
466 return result;
467 }
468
469 static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
470
471 /* Write TO_DO bytes from DATA to FP.
472 Then mark FP as having empty buffers. */
473
474 int
475 _IO_new_do_write (fp, data, to_do)
476 _IO_FILE *fp;
477 const char *data;
478 _IO_size_t to_do;
479 {
480 return (to_do == 0 || new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
481 }
482 INTDEF2(_IO_new_do_write, _IO_do_write)
483
484 static
485 int
486 new_do_write (fp, data, to_do)
487 _IO_FILE *fp;
488 const char *data;
489 _IO_size_t to_do;
490 {
491 _IO_size_t count;
492 if (fp->_flags & _IO_IS_APPENDING)
493 /* On a system without a proper O_APPEND implementation,
494 you would need to sys_seek(0, SEEK_END) here, but is
495 is not needed nor desirable for Unix- or Posix-like systems.
496 Instead, just indicate that offset (before and after) is
497 unpredictable. */
498 fp->_offset = _IO_pos_BAD;
499 else if (fp->_IO_read_end != fp->_IO_write_base)
500 {
501 _IO_off64_t new_pos
502 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
503 if (new_pos == _IO_pos_BAD)
504 return 0;
505 fp->_offset = new_pos;
506 }
507 count = _IO_SYSWRITE (fp, data, to_do);
508 if (fp->_cur_column && count)
509 fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
510 count) + 1;
511 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
512 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
513 fp->_IO_write_end = (fp->_mode <= 0
514 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
515 ? fp->_IO_buf_base : fp->_IO_buf_end);
516 return count;
517 }
518
519 int
520 _IO_new_file_underflow (fp)
521 _IO_FILE *fp;
522 {
523 _IO_ssize_t count;
524 #if 0
525 /* SysV does not make this test; take it out for compatibility */
526 if (fp->_flags & _IO_EOF_SEEN)
527 return (EOF);
528 #endif
529
530 if (fp->_flags & _IO_NO_READS)
531 {
532 fp->_flags |= _IO_ERR_SEEN;
533 __set_errno (EBADF);
534 return EOF;
535 }
536 if (fp->_IO_read_ptr < fp->_IO_read_end)
537 return *(unsigned char *) fp->_IO_read_ptr;
538
539 if (fp->_IO_buf_base == NULL)
540 {
541 /* Maybe we already have a push back pointer. */
542 if (fp->_IO_save_base != NULL)
543 {
544 free (fp->_IO_save_base);
545 fp->_flags &= ~_IO_IN_BACKUP;
546 }
547 INTUSE(_IO_doallocbuf) (fp);
548 }
549
550 /* Flush all line buffered files before reading. */
551 /* FIXME This can/should be moved to genops ?? */
552 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
553 {
554 #if 0
555 INTUSE(_IO_flush_all_linebuffered) ();
556 #else
557 /* We used to flush all line-buffered stream. This really isn't
558 required by any standard. My recollection is that
559 traditional Unix systems did this for stdout. stderr better
560 not be line buffered. So we do just that here
561 explicitly. --drepper */
562 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
563 _IO_stdout);
564 _IO_flockfile (_IO_stdout);
565
566 if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
567 == (_IO_LINKED | _IO_LINE_BUF))
568 _IO_OVERFLOW (_IO_stdout, EOF);
569
570 _IO_funlockfile (_IO_stdout);
571 _IO_cleanup_region_end (0);
572 #endif
573 }
574
575 INTUSE(_IO_switch_to_get_mode) (fp);
576
577 /* This is very tricky. We have to adjust those
578 pointers before we call _IO_SYSREAD () since
579 we may longjump () out while waiting for
580 input. Those pointers may be screwed up. H.J. */
581 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
582 fp->_IO_read_end = fp->_IO_buf_base;
583 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
584 = fp->_IO_buf_base;
585
586 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
587 fp->_IO_buf_end - fp->_IO_buf_base);
588 if (count <= 0)
589 {
590 if (count == 0)
591 fp->_flags |= _IO_EOF_SEEN;
592 else
593 fp->_flags |= _IO_ERR_SEEN, count = 0;
594 }
595 fp->_IO_read_end += count;
596 if (count == 0)
597 return EOF;
598 if (fp->_offset != _IO_pos_BAD)
599 _IO_pos_adjust (fp->_offset, count);
600 return *(unsigned char *) fp->_IO_read_ptr;
601 }
602 INTDEF2(_IO_new_file_underflow, _IO_file_underflow)
603
604 /* Special callback replacing the underflow callbacks if we mmap the
605 file. */
606 int
607 _IO_file_underflow_mmap (_IO_FILE *fp)
608 {
609 if (fp->_IO_read_end < fp->_IO_buf_end)
610 {
611 /* A stupid requirement in POSIX says that the first read on a
612 stream must update the atime. Just read a single byte. We
613 don't have to worry about repositioning the file descriptor
614 since the following seek defines its position anyway. */
615 char ignore[1];
616 read (fp->_fileno, ignore, 1);
617
618 if (
619 # ifdef _G_LSEEK64
620 _G_LSEEK64 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base,
621 SEEK_SET)
622 # else
623 __lseek (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET)
624 # endif
625 != fp->_IO_buf_end - fp->_IO_buf_base)
626 {
627 fp->_flags |= _IO_ERR_SEEN;
628 return EOF;
629 }
630
631 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
632 fp->_IO_read_end = fp->_IO_buf_end;
633 return *(unsigned char *) fp->_IO_read_ptr;
634 }
635
636 fp->_flags |= _IO_EOF_SEEN;
637 return EOF;
638 }
639
640 int
641 _IO_new_file_overflow (f, ch)
642 _IO_FILE *f;
643 int ch;
644 {
645 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
646 {
647 f->_flags |= _IO_ERR_SEEN;
648 __set_errno (EBADF);
649 return EOF;
650 }
651 /* If currently reading or no buffer allocated. */
652 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0)
653 {
654 /* Allocate a buffer if needed. */
655 if (f->_IO_write_base == 0)
656 {
657 INTUSE(_IO_doallocbuf) (f);
658 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
659 }
660 /* Otherwise must be currently reading.
661 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
662 logically slide the buffer forwards one block (by setting the
663 read pointers to all point at the beginning of the block). This
664 makes room for subsequent output.
665 Otherwise, set the read pointers to _IO_read_end (leaving that
666 alone, so it can continue to correspond to the external position). */
667 if (f->_IO_read_ptr == f->_IO_buf_end)
668 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
669 f->_IO_write_ptr = f->_IO_read_ptr;
670 f->_IO_write_base = f->_IO_write_ptr;
671 f->_IO_write_end = f->_IO_buf_end;
672 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
673
674 f->_flags |= _IO_CURRENTLY_PUTTING;
675 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
676 f->_IO_write_end = f->_IO_write_ptr;
677 }
678 if (ch == EOF)
679 return _IO_new_do_write(f, f->_IO_write_base,
680 f->_IO_write_ptr - f->_IO_write_base);
681 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
682 if (_IO_do_flush (f) == EOF)
683 return EOF;
684 *f->_IO_write_ptr++ = ch;
685 if ((f->_flags & _IO_UNBUFFERED)
686 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
687 if (_IO_new_do_write(f, f->_IO_write_base,
688 f->_IO_write_ptr - f->_IO_write_base) == EOF)
689 return EOF;
690 return (unsigned char) ch;
691 }
692 INTDEF2(_IO_new_file_overflow, _IO_file_overflow)
693
694 int
695 _IO_new_file_sync (fp)
696 _IO_FILE *fp;
697 {
698 _IO_ssize_t delta;
699 int retval = 0;
700
701 /* char* ptr = cur_ptr(); */
702 if (fp->_IO_write_ptr > fp->_IO_write_base)
703 if (_IO_do_flush(fp)) return EOF;
704 delta = fp->_IO_read_ptr - fp->_IO_read_end;
705 if (delta != 0)
706 {
707 #ifdef TODO
708 if (_IO_in_backup (fp))
709 delta -= eGptr () - Gbase ();
710 #endif
711 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
712 if (new_pos != (_IO_off64_t) EOF)
713 fp->_IO_read_end = fp->_IO_read_ptr;
714 #ifdef ESPIPE
715 else if (errno == ESPIPE)
716 ; /* Ignore error from unseekable devices. */
717 #endif
718 else
719 retval = EOF;
720 }
721 if (retval != EOF)
722 fp->_offset = _IO_pos_BAD;
723 /* FIXME: Cleanup - can this be shared? */
724 /* setg(base(), ptr, ptr); */
725 return retval;
726 }
727 INTDEF2(_IO_new_file_sync, _IO_file_sync)
728
729 _IO_off64_t
730 _IO_new_file_seekoff (fp, offset, dir, mode)
731 _IO_FILE *fp;
732 _IO_off64_t offset;
733 int dir;
734 int mode;
735 {
736 _IO_off64_t result;
737 _IO_off64_t delta, new_offset;
738 long count;
739 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
740 offset of the underlying file must be exact. */
741 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
742 && fp->_IO_write_base == fp->_IO_write_ptr);
743
744 if (mode == 0)
745 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
746
747 /* Flush unwritten characters.
748 (This may do an unneeded write if we seek within the buffer.
749 But to be able to switch to reading, we would need to set
750 egptr to ptr. That can't be done in the current design,
751 which assumes file_ptr() is eGptr. Anyway, since we probably
752 end up flushing when we close(), it doesn't make much difference.)
753 FIXME: simulate mem-papped files. */
754
755 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
756 if (INTUSE(_IO_switch_to_get_mode) (fp))
757 return EOF;
758
759 if (fp->_IO_buf_base == NULL)
760 {
761 /* It could be that we already have a pushback buffer. */
762 if (fp->_IO_read_base != NULL)
763 {
764 free (fp->_IO_read_base);
765 fp->_flags &= ~_IO_IN_BACKUP;
766 }
767 INTUSE(_IO_doallocbuf) (fp);
768 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
769 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
770 }
771
772 switch (dir)
773 {
774 case _IO_seek_cur:
775 /* Adjust for read-ahead (bytes is buffer). */
776 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
777 if (fp->_offset == _IO_pos_BAD)
778 goto dumb;
779 /* Make offset absolute, assuming current pointer is file_ptr(). */
780 offset += fp->_offset;
781
782 dir = _IO_seek_set;
783 break;
784 case _IO_seek_set:
785 break;
786 case _IO_seek_end:
787 {
788 struct _G_stat64 st;
789 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
790 {
791 offset += st.st_size;
792 dir = _IO_seek_set;
793 }
794 else
795 goto dumb;
796 }
797 }
798 /* At this point, dir==_IO_seek_set. */
799
800 /* If we are only interested in the current position we've found it now. */
801 if (mode == 0)
802 return offset;
803
804 /* If destination is within current buffer, optimize: */
805 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
806 && !_IO_in_backup (fp))
807 {
808 /* Offset relative to start of main get area. */
809 _IO_off64_t rel_offset = (offset - fp->_offset
810 + (fp->_IO_read_end - fp->_IO_read_base));
811 if (rel_offset >= 0)
812 {
813 #if 0
814 if (_IO_in_backup (fp))
815 _IO_switch_to_main_get_area (fp);
816 #endif
817 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
818 {
819 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
820 fp->_IO_read_end);
821 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
822 {
823 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
824 goto resync;
825 }
826 }
827 #ifdef TODO
828 /* If we have streammarkers, seek forward by reading ahead. */
829 if (_IO_have_markers (fp))
830 {
831 int to_skip = rel_offset
832 - (fp->_IO_read_ptr - fp->_IO_read_base);
833 if (ignore (to_skip) != to_skip)
834 goto dumb;
835 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
836 goto resync;
837 }
838 #endif
839 }
840 #ifdef TODO
841 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
842 {
843 if (!_IO_in_backup (fp))
844 _IO_switch_to_backup_area (fp);
845 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
846 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
847 goto resync;
848 }
849 #endif
850 }
851
852 #ifdef TODO
853 INTUSE(_IO_unsave_markers) (fp);
854 #endif
855
856 if (fp->_flags & _IO_NO_READS)
857 goto dumb;
858
859 /* Try to seek to a block boundary, to improve kernel page management. */
860 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
861 delta = offset - new_offset;
862 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
863 {
864 new_offset = offset;
865 delta = 0;
866 }
867 result = _IO_SYSSEEK (fp, new_offset, 0);
868 if (result < 0)
869 return EOF;
870 if (delta == 0)
871 count = 0;
872 else
873 {
874 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
875 (must_be_exact
876 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
877 if (count < delta)
878 {
879 /* We weren't allowed to read, but try to seek the remainder. */
880 offset = count == EOF ? delta : delta-count;
881 dir = _IO_seek_cur;
882 goto dumb;
883 }
884 }
885 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
886 fp->_IO_buf_base + count);
887 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
888 fp->_offset = result + count;
889 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
890 return offset;
891 dumb:
892
893 INTUSE(_IO_unsave_markers) (fp);
894 result = _IO_SYSSEEK (fp, offset, dir);
895 if (result != EOF)
896 {
897 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
898 fp->_offset = result;
899 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
900 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
901 }
902 return result;
903
904 resync:
905 /* We need to do it since it is possible that the file offset in
906 the kernel may be changed behind our back. It may happen when
907 we fopen a file and then do a fork. One process may access the
908 the file and the kernel file offset will be changed. */
909 if (fp->_offset >= 0)
910 _IO_SYSSEEK (fp, fp->_offset, 0);
911
912 return offset;
913 }
914 INTDEF2(_IO_new_file_seekoff, _IO_file_seekoff)
915
916 _IO_off64_t
917 _IO_file_seekoff_mmap (fp, offset, dir, mode)
918 _IO_FILE *fp;
919 _IO_off64_t offset;
920 int dir;
921 int mode;
922 {
923 _IO_off64_t result;
924
925 /* If we are only interested in the current position, calculate it and
926 return right now. This calculation does the right thing when we are
927 using a pushback buffer, but in the usual case has the same value as
928 (fp->_IO_read_ptr - fp->_IO_buf_base). */
929 if (mode == 0)
930 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
931
932 switch (dir)
933 {
934 case _IO_seek_cur:
935 /* Adjust for read-ahead (bytes is buffer). */
936 offset += fp->_IO_read_ptr - fp->_IO_read_base;
937 break;
938 case _IO_seek_set:
939 break;
940 case _IO_seek_end:
941 offset += fp->_IO_buf_end - fp->_IO_buf_base;
942 break;
943 }
944 /* At this point, dir==_IO_seek_set. */
945
946 if (offset < 0)
947 /* No negative offsets are valid. */
948 return EOF;
949
950 result = _IO_SYSSEEK (fp, offset, 0);
951 if (result < 0)
952 return EOF;
953
954 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
955 fp->_IO_buf_base + offset);
956
957 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
958
959 return offset;
960 }
961
962 _IO_ssize_t
963 _IO_file_read (fp, buf, size)
964 _IO_FILE *fp;
965 void *buf;
966 _IO_ssize_t size;
967 {
968 return read (fp->_fileno, buf, size);
969 }
970 INTDEF(_IO_file_read)
971
972 _IO_off64_t
973 _IO_file_seek (fp, offset, dir)
974 _IO_FILE *fp;
975 _IO_off64_t offset;
976 int dir;
977 {
978 #ifdef _G_LSEEK64
979 return _G_LSEEK64 (fp->_fileno, offset, dir);
980 #else
981 return lseek (fp->_fileno, offset, dir);
982 #endif
983 }
984 INTDEF(_IO_file_seek)
985
986 int
987 _IO_file_stat (fp, st)
988 _IO_FILE *fp;
989 void *st;
990 {
991 #ifdef _G_FSTAT64
992 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
993 #else
994 return fstat (fp->_fileno, (struct stat *) st);
995 #endif
996 }
997 INTDEF(_IO_file_stat)
998
999 int
1000 _IO_file_close_mmap (fp)
1001 _IO_FILE *fp;
1002 {
1003 /* In addition to closing the file descriptor we have to unmap the
1004 file. */
1005 (void) munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
1006 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
1007 return close (fp->_fileno);
1008 }
1009
1010 int
1011 _IO_file_close (fp)
1012 _IO_FILE *fp;
1013 {
1014 return close (fp->_fileno);
1015 }
1016 INTDEF(_IO_file_close)
1017
1018 _IO_ssize_t
1019 _IO_new_file_write (f, data, n)
1020 _IO_FILE *f;
1021 const void *data;
1022 _IO_ssize_t n;
1023 {
1024 _IO_ssize_t to_do = n;
1025 while (to_do > 0)
1026 {
1027 _IO_ssize_t count = write (f->_fileno, data, to_do);
1028 if (count < 0)
1029 {
1030 f->_flags |= _IO_ERR_SEEN;
1031 break;
1032 }
1033 to_do -= count;
1034 data = (void *) ((char *) data + count);
1035 }
1036 n -= to_do;
1037 if (f->_offset >= 0)
1038 f->_offset += n;
1039 return n;
1040 }
1041
1042 _IO_size_t
1043 _IO_new_file_xsputn (f, data, n)
1044 _IO_FILE *f;
1045 const void *data;
1046 _IO_size_t n;
1047 {
1048 register const char *s = (const char *) data;
1049 _IO_size_t to_do = n;
1050 int must_flush = 0;
1051 _IO_size_t count;
1052
1053 if (n <= 0)
1054 return 0;
1055 /* This is an optimized implementation.
1056 If the amount to be written straddles a block boundary
1057 (or the filebuf is unbuffered), use sys_write directly. */
1058
1059 /* First figure out how much space is available in the buffer. */
1060 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1061 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1062 {
1063 count = f->_IO_buf_end - f->_IO_write_ptr;
1064 if (count >= n)
1065 {
1066 register const char *p;
1067 for (p = s + n; p > s; )
1068 {
1069 if (*--p == '\n')
1070 {
1071 count = p - s + 1;
1072 must_flush = 1;
1073 break;
1074 }
1075 }
1076 }
1077 }
1078 /* Then fill the buffer. */
1079 if (count > 0)
1080 {
1081 if (count > to_do)
1082 count = to_do;
1083 if (count > 20)
1084 {
1085 #ifdef _LIBC
1086 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1087 #else
1088 memcpy (f->_IO_write_ptr, s, count);
1089 f->_IO_write_ptr += count;
1090 #endif
1091 s += count;
1092 }
1093 else
1094 {
1095 register char *p = f->_IO_write_ptr;
1096 register int i = (int) count;
1097 while (--i >= 0)
1098 *p++ = *s++;
1099 f->_IO_write_ptr = p;
1100 }
1101 to_do -= count;
1102 }
1103 if (to_do + must_flush > 0)
1104 {
1105 _IO_size_t block_size, do_write;
1106 /* Next flush the (full) buffer. */
1107 if (_IO_OVERFLOW (f, EOF) == EOF)
1108 return n - to_do;
1109
1110 /* Try to maintain alignment: write a whole number of blocks.
1111 dont_write is what gets left over. */
1112 block_size = f->_IO_buf_end - f->_IO_buf_base;
1113 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
1114
1115 if (do_write)
1116 {
1117 count = new_do_write (f, s, do_write);
1118 to_do -= count;
1119 if (count < do_write)
1120 return n - to_do;
1121 }
1122
1123 /* Now write out the remainder. Normally, this will fit in the
1124 buffer, but it's somewhat messier for line-buffered files,
1125 so we let _IO_default_xsputn handle the general case. */
1126 if (to_do)
1127 to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do);
1128 }
1129 return n - to_do;
1130 }
1131 INTDEF2(_IO_new_file_xsputn, _IO_file_xsputn)
1132
1133 _IO_size_t
1134 _IO_file_xsgetn (fp, data, n)
1135 _IO_FILE *fp;
1136 void *data;
1137 _IO_size_t n;
1138 {
1139 register _IO_size_t want, have;
1140 register _IO_ssize_t count;
1141 register char *s = data;
1142
1143 want = n;
1144
1145 if (fp->_IO_buf_base == NULL)
1146 {
1147 /* Maybe we already have a push back pointer. */
1148 if (fp->_IO_save_base != NULL)
1149 {
1150 free (fp->_IO_save_base);
1151 fp->_flags &= ~_IO_IN_BACKUP;
1152 }
1153 INTUSE(_IO_doallocbuf) (fp);
1154 }
1155
1156 while (want > 0)
1157 {
1158 have = fp->_IO_read_end - fp->_IO_read_ptr;
1159 if (want <= have)
1160 {
1161 memcpy (s, fp->_IO_read_ptr, want);
1162 fp->_IO_read_ptr += want;
1163 want = 0;
1164 }
1165 else
1166 {
1167 if (have > 0)
1168 {
1169 #ifdef _LIBC
1170 s = __mempcpy (s, fp->_IO_read_ptr, have);
1171 #else
1172 memcpy (s, fp->_IO_read_ptr, have);
1173 s += have;
1174 #endif
1175 want -= have;
1176 fp->_IO_read_ptr += have;
1177 }
1178
1179 /* Check for backup and repeat */
1180 if (_IO_in_backup (fp))
1181 {
1182 _IO_switch_to_main_get_area (fp);
1183 continue;
1184 }
1185
1186 /* If we now want less than a buffer, underflow and repeat
1187 the copy. Otherwise, _IO_SYSREAD directly to
1188 the user buffer. */
1189 if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
1190 {
1191 if (__underflow (fp) == EOF)
1192 break;
1193
1194 continue;
1195 }
1196
1197 /* These must be set before the sysread as we might longjmp out
1198 waiting for input. */
1199 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1200 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1201
1202 /* Try to maintain alignment: read a whole number of blocks. */
1203 count = want;
1204 if (fp->_IO_buf_base)
1205 {
1206 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1207 if (block_size >= 128)
1208 count -= want % block_size;
1209 }
1210
1211 count = _IO_SYSREAD (fp, s, count);
1212 if (count <= 0)
1213 {
1214 if (count == 0)
1215 fp->_flags |= _IO_EOF_SEEN;
1216 else
1217 fp->_flags |= _IO_ERR_SEEN;
1218
1219 break;
1220 }
1221
1222 s += count;
1223 want -= count;
1224 if (fp->_offset != _IO_pos_BAD)
1225 _IO_pos_adjust (fp->_offset, count);
1226 }
1227 }
1228
1229 return n - want;
1230 }
1231 INTDEF(_IO_file_xsgetn)
1232
1233 static _IO_size_t _IO_file_xsgetn_mmap __P ((_IO_FILE *, void *, _IO_size_t));
1234 static _IO_size_t
1235 _IO_file_xsgetn_mmap (fp, data, n)
1236 _IO_FILE *fp;
1237 void *data;
1238 _IO_size_t n;
1239 {
1240 register _IO_size_t have;
1241 char *read_ptr = fp->_IO_read_ptr;
1242 register char *s = (char *) data;
1243
1244 have = fp->_IO_read_end - fp->_IO_read_ptr;
1245
1246 if (have < n)
1247 {
1248 if (__builtin_expect (_IO_in_backup (fp), 0))
1249 {
1250 #ifdef _LIBC
1251 s = __mempcpy (s, read_ptr, have);
1252 #else
1253 memcpy (s, read_ptr, have);
1254 s += have;
1255 #endif
1256 n -= have;
1257 _IO_switch_to_main_get_area (fp);
1258 read_ptr = fp->_IO_read_ptr;
1259 have = fp->_IO_read_end - fp->_IO_read_ptr;
1260 }
1261
1262 if (have < n)
1263 {
1264 /* Maybe the read buffer is not yet fully set up. */
1265 fp->_IO_read_ptr = fp->_IO_read_end;
1266 if (fp->_IO_read_end < fp->_IO_buf_end
1267 && _IO_file_underflow_mmap (fp) != EOF)
1268 have = fp->_IO_read_end - read_ptr;
1269 }
1270 }
1271
1272 if (have < n)
1273 fp->_flags |= _IO_EOF_SEEN;
1274
1275 if (have != 0)
1276 {
1277 have = MIN (have, n);
1278 #ifdef _LIBC
1279 s = __mempcpy (s, read_ptr, have);
1280 #else
1281 memcpy (s, read_ptr, have);
1282 s += have;
1283 #endif
1284 fp->_IO_read_ptr = read_ptr + have;
1285 }
1286
1287 return s - (char *) data;
1288 }
1289
1290 struct _IO_jump_t _IO_file_jumps =
1291 {
1292 JUMP_INIT_DUMMY,
1293 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1294 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1295 JUMP_INIT(underflow, INTUSE(_IO_file_underflow)),
1296 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1297 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1298 JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
1299 JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)),
1300 JUMP_INIT(seekoff, _IO_new_file_seekoff),
1301 JUMP_INIT(seekpos, _IO_default_seekpos),
1302 JUMP_INIT(setbuf, _IO_new_file_setbuf),
1303 JUMP_INIT(sync, _IO_new_file_sync),
1304 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1305 JUMP_INIT(read, INTUSE(_IO_file_read)),
1306 JUMP_INIT(write, _IO_new_file_write),
1307 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1308 JUMP_INIT(close, INTUSE(_IO_file_close)),
1309 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1310 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1311 JUMP_INIT(imbue, _IO_default_imbue)
1312 };
1313 INTVARDEF(_IO_file_jumps)
1314
1315 struct _IO_jump_t _IO_file_jumps_mmap =
1316 {
1317 JUMP_INIT_DUMMY,
1318 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1319 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1320 JUMP_INIT(underflow, _IO_file_underflow_mmap),
1321 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1322 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1323 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1324 JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
1325 JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
1326 JUMP_INIT(seekpos, _IO_default_seekpos),
1327 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1328 JUMP_INIT(sync, _IO_new_file_sync),
1329 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1330 JUMP_INIT(read, INTUSE(_IO_file_read)),
1331 JUMP_INIT(write, _IO_new_file_write),
1332 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1333 JUMP_INIT(close, _IO_file_close_mmap),
1334 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1335 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1336 JUMP_INIT(imbue, _IO_default_imbue)
1337 };
1338
1339 #ifdef _LIBC
1340 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1341 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1342 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1343 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1344 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1345 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1346 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1347 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1348 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1349 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1350 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1351 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1352 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1353 #endif