1 /* Copyright (C) 1993, 1995, 1997-2005, 2006, 2007, 2008, 2009, 2011-2012
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Per Bothner <bothner@cygnus.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>.
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. */
31 # define _POSIX_SOURCE
36 #include <sys/param.h>
37 #include <sys/types.h>
44 # include "../wcsmbs/wcsmbsload.h"
45 # include "../iconv/gconv_charset.h"
46 # include "../iconv/gconv_int.h"
47 # include <shlib-compat.h>
48 # include <not-cancel.h>
54 # define __set_errno(Val) errno = (Val)
59 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
60 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
61 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
62 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
63 # define _IO_do_write _IO_new_do_write /* For macro uses. */
64 # define _IO_file_close_it _IO_new_file_close_it
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
83 extern struct __gconv_trans_data __libio_translit attribute_hidden
;
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.
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().
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(). (?)
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.
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().
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().
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.
134 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
137 #define CLOSED_FILEBUF_FLAGS \
138 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
142 _IO_new_file_init (fp
)
143 struct _IO_FILE_plus
*fp
;
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
;
151 INTUSE(_IO_link_in
) (fp
);
152 fp
->file
._fileno
= -1;
154 INTDEF2(_IO_new_file_init
, _IO_file_init
)
157 _IO_new_file_close_it (fp
)
160 if (!_IO_file_is_open (fp
))
164 if (_IO_in_put_mode (fp
))
165 write_status
= _IO_do_flush (fp
);
166 else if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
167 && !_IO_in_backup (fp
))
169 off64_t o
= _IO_SEEKOFF (fp
, 0, _IO_seek_cur
, 0);
173 write_status
= _IO_SYSSEEK (fp
, o
, SEEK_SET
) < 0 ? EOF
: 0;
178 INTUSE(_IO_unsave_markers
) (fp
);
180 int close_status
= ((fp
->_flags2
& _IO_FLAGS2_NOCLOSE
) == 0
181 ? _IO_SYSCLOSE (fp
) : 0);
184 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
187 if (_IO_have_wbackup (fp
))
188 INTUSE(_IO_free_wbackup_area
) (fp
);
189 INTUSE(_IO_wsetb
) (fp
, NULL
, NULL
, 0);
190 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
191 _IO_wsetp (fp
, NULL
, NULL
);
194 INTUSE(_IO_setb
) (fp
, NULL
, NULL
, 0);
195 _IO_setg (fp
, NULL
, NULL
, NULL
);
196 _IO_setp (fp
, NULL
, NULL
);
198 INTUSE(_IO_un_link
) ((struct _IO_FILE_plus
*) fp
);
199 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
201 fp
->_offset
= _IO_pos_BAD
;
203 return close_status
? close_status
: write_status
;
205 INTDEF2(_IO_new_file_close_it
, _IO_file_close_it
)
208 _IO_new_file_finish (fp
, dummy
)
212 if (_IO_file_is_open (fp
))
215 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
218 INTUSE(_IO_default_finish
) (fp
, 0);
220 INTDEF2(_IO_new_file_finish
, _IO_file_finish
)
223 _IO_file_open (fp
, filename
, posix_mode
, prot
, read_write
, is32not64
)
225 const char *filename
;
233 if (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0))
234 fdesc
= open_not_cancel (filename
,
235 posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
237 fdesc
= open (filename
, posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
239 fdesc
= open (filename
, posix_mode
, prot
);
244 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
245 if ((read_write
& _IO_IS_APPENDING
) && (read_write
& _IO_NO_READS
))
246 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_end
, _IOS_INPUT
|_IOS_OUTPUT
)
247 == _IO_pos_BAD
&& errno
!= ESPIPE
)
249 close_not_cancel (fdesc
);
252 INTUSE(_IO_link_in
) ((struct _IO_FILE_plus
*) fp
);
255 libc_hidden_def (_IO_file_open
)
258 _IO_new_file_fopen (fp
, filename
, mode
, is32not64
)
260 const char *filename
;
264 int oflags
= 0, omode
;
271 const char *last_recognized
;
274 if (_IO_file_is_open (fp
))
280 read_write
= _IO_NO_WRITES
;
284 oflags
= O_CREAT
|O_TRUNC
;
285 read_write
= _IO_NO_READS
;
289 oflags
= O_CREAT
|O_APPEND
;
290 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
293 __set_errno (EINVAL
);
297 last_recognized
= mode
;
299 for (i
= 1; i
< 7; ++i
)
307 read_write
&= _IO_IS_APPENDING
;
309 last_recognized
= mode
;
315 last_recognized
= mode
;
320 last_recognized
= mode
;
324 fp
->_flags2
|= _IO_FLAGS2_MMAP
;
327 fp
->_flags2
|= _IO_FLAGS2_NOTCANCEL
;
333 fp
->_flags2
|= _IO_FLAGS2_CLOEXEC
;
342 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
347 #ifndef __ASSUME_O_CLOEXEC
348 if ((fp
->_flags2
& _IO_FLAGS2_CLOEXEC
) != 0 && __have_o_cloexec
<= 0)
350 int fd
= _IO_fileno (fp
);
351 if (__have_o_cloexec
== 0)
353 int flags
= __fcntl (fd
, F_GETFD
);
354 __have_o_cloexec
= (flags
& FD_CLOEXEC
) == 0 ? -1 : 1;
356 if (__have_o_cloexec
< 0)
357 __fcntl (fd
, F_SETFD
, FD_CLOEXEC
);
361 /* Test whether the mode string specifies the conversion. */
362 cs
= strstr (last_recognized
+ 1, ",ccs=");
365 /* Yep. Load the appropriate conversions and set the orientation
367 struct gconv_fcts fcts
;
368 struct _IO_codecvt
*cc
;
369 char *endp
= __strchrnul (cs
+ 5, ',');
370 char ccs
[endp
- (cs
+ 5) + 3];
372 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
375 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
376 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
378 /* Something went wrong, we cannot load the conversion modules.
379 This means we cannot proceed since the user explicitly asked
381 (void) INTUSE(_IO_file_close_it
) (fp
);
382 __set_errno (EINVAL
);
386 assert (fcts
.towc_nsteps
== 1);
387 assert (fcts
.tomb_nsteps
== 1);
389 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
390 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
392 /* Clear the state. We start all over again. */
393 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
394 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
396 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
398 /* The functions are always the same. */
399 *cc
= __libio_codecvt
;
401 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
402 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
404 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
405 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
406 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
407 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
409 /* XXX For now no transliteration. */
410 cc
->__cd_in
.__cd
.__data
[0].__trans
= NULL
;
412 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
413 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
415 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
416 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
417 cc
->__cd_out
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
418 cc
->__cd_out
.__cd
.__data
[0].__statep
=
419 &result
->_wide_data
->_IO_state
;
421 /* And now the transliteration. */
422 cc
->__cd_out
.__cd
.__data
[0].__trans
= &__libio_translit
;
424 /* From now on use the wide character callback functions. */
425 ((struct _IO_FILE_plus
*) fp
)->vtable
= fp
->_wide_data
->_wide_vtable
;
427 /* Set the mode now. */
434 INTDEF2(_IO_new_file_fopen
, _IO_file_fopen
)
437 _IO_new_file_attach (fp
, fd
)
441 if (_IO_file_is_open (fp
))
444 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
445 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
446 /* Get the current position of the file. */
447 /* We have to do that since that may be junk. */
448 fp
->_offset
= _IO_pos_BAD
;
449 int save_errno
= errno
;
450 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
451 == _IO_pos_BAD
&& errno
!= ESPIPE
)
453 __set_errno (save_errno
);
456 INTDEF2(_IO_new_file_attach
, _IO_file_attach
)
459 _IO_new_file_setbuf (fp
, p
, len
)
464 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
467 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
469 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
473 INTDEF2(_IO_new_file_setbuf
, _IO_file_setbuf
)
477 _IO_file_setbuf_mmap (fp
, p
, len
)
484 /* Change the function table. */
485 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
486 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
488 /* And perform the normal operation. */
489 result
= _IO_new_file_setbuf (fp
, p
, len
);
491 /* If the call failed, restore to using mmap. */
494 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps_mmap
;
495 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
501 static _IO_size_t
new_do_write (_IO_FILE
*, const char *, _IO_size_t
);
503 /* Write TO_DO bytes from DATA to FP.
504 Then mark FP as having empty buffers. */
507 _IO_new_do_write (fp
, data
, to_do
)
513 || (_IO_size_t
) new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
515 INTDEF2(_IO_new_do_write
, _IO_do_write
)
519 new_do_write (fp
, data
, to_do
)
525 if (fp
->_flags
& _IO_IS_APPENDING
)
526 /* On a system without a proper O_APPEND implementation,
527 you would need to sys_seek(0, SEEK_END) here, but is
528 not needed nor desirable for Unix- or Posix-like systems.
529 Instead, just indicate that offset (before and after) is
531 fp
->_offset
= _IO_pos_BAD
;
532 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
535 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
536 if (new_pos
== _IO_pos_BAD
)
538 fp
->_offset
= new_pos
;
540 count
= _IO_SYSWRITE (fp
, data
, to_do
);
541 if (fp
->_cur_column
&& count
)
542 fp
->_cur_column
= INTUSE(_IO_adjust_column
) (fp
->_cur_column
- 1, data
,
544 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
545 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
546 fp
->_IO_write_end
= (fp
->_mode
<= 0
547 && (fp
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
548 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
553 _IO_new_file_underflow (fp
)
558 /* SysV does not make this test; take it out for compatibility */
559 if (fp
->_flags
& _IO_EOF_SEEN
)
563 if (fp
->_flags
& _IO_NO_READS
)
565 fp
->_flags
|= _IO_ERR_SEEN
;
569 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
570 return *(unsigned char *) fp
->_IO_read_ptr
;
572 if (fp
->_IO_buf_base
== NULL
)
574 /* Maybe we already have a push back pointer. */
575 if (fp
->_IO_save_base
!= NULL
)
577 free (fp
->_IO_save_base
);
578 fp
->_flags
&= ~_IO_IN_BACKUP
;
580 INTUSE(_IO_doallocbuf
) (fp
);
583 /* Flush all line buffered files before reading. */
584 /* FIXME This can/should be moved to genops ?? */
585 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
588 INTUSE(_IO_flush_all_linebuffered
) ();
590 /* We used to flush all line-buffered stream. This really isn't
591 required by any standard. My recollection is that
592 traditional Unix systems did this for stdout. stderr better
593 not be line buffered. So we do just that here
594 explicitly. --drepper */
595 _IO_acquire_lock (_IO_stdout
);
597 if ((_IO_stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
598 == (_IO_LINKED
| _IO_LINE_BUF
))
599 _IO_OVERFLOW (_IO_stdout
, EOF
);
601 _IO_release_lock (_IO_stdout
);
605 INTUSE(_IO_switch_to_get_mode
) (fp
);
607 /* This is very tricky. We have to adjust those
608 pointers before we call _IO_SYSREAD () since
609 we may longjump () out while waiting for
610 input. Those pointers may be screwed up. H.J. */
611 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
612 fp
->_IO_read_end
= fp
->_IO_buf_base
;
613 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
616 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
617 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
621 fp
->_flags
|= _IO_EOF_SEEN
;
623 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
625 fp
->_IO_read_end
+= count
;
628 if (fp
->_offset
!= _IO_pos_BAD
)
629 _IO_pos_adjust (fp
->_offset
, count
);
630 return *(unsigned char *) fp
->_IO_read_ptr
;
632 INTDEF2(_IO_new_file_underflow
, _IO_file_underflow
)
634 /* Guts of underflow callback if we mmap the file. This stats the file and
635 updates the stream state to match. In the normal case we return zero.
636 If the file is no longer eligible for mmap, its jump tables are reset to
637 the vanilla ones and we return nonzero. */
639 mmap_remap_check (_IO_FILE
*fp
)
643 if (_IO_SYSSTAT (fp
, &st
) == 0
644 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
645 /* Limit the file size to 1MB for 32-bit machines. */
646 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024))
648 const size_t pagesize
= __getpagesize ();
649 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
650 if (ROUNDED (st
.st_size
) < ROUNDED (fp
->_IO_buf_end
653 /* We can trim off some pages past the end of the file. */
654 (void) __munmap (fp
->_IO_buf_base
+ ROUNDED (st
.st_size
),
655 ROUNDED (fp
->_IO_buf_end
- fp
->_IO_buf_base
)
656 - ROUNDED (st
.st_size
));
657 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
659 else if (ROUNDED (st
.st_size
) > ROUNDED (fp
->_IO_buf_end
662 /* The file added some pages. We need to remap it. */
664 #ifdef _G_HAVE_MREMAP
665 p
= __mremap (fp
->_IO_buf_base
, ROUNDED (fp
->_IO_buf_end
667 ROUNDED (st
.st_size
), MREMAP_MAYMOVE
);
670 (void) __munmap (fp
->_IO_buf_base
,
671 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
675 (void) __munmap (fp
->_IO_buf_base
,
676 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
678 p
= _G_MMAP64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
681 p
= __mmap (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
687 fp
->_IO_buf_base
= p
;
688 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
692 /* The number of pages didn't change. */
693 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
697 fp
->_offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
698 _IO_setg (fp
, fp
->_IO_buf_base
,
699 fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
700 ? fp
->_IO_buf_base
+ fp
->_offset
: fp
->_IO_buf_end
,
703 /* If we are already positioned at or past the end of the file, don't
704 change the current offset. If not, seek past what we have mapped,
705 mimicking the position left by a normal underflow reading into its
708 if (fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
716 (fp
->_fileno
, fp
->_IO_buf_end
- fp
->_IO_buf_base
, SEEK_SET
)
717 != fp
->_IO_buf_end
- fp
->_IO_buf_base
)
718 fp
->_flags
|= _IO_ERR_SEEN
;
720 fp
->_offset
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
727 /* Life is no longer good for mmap. Punt it. */
728 (void) __munmap (fp
->_IO_buf_base
,
729 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
731 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
732 _IO_setg (fp
, NULL
, NULL
, NULL
);
734 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
736 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
737 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
743 /* Special callback replacing the underflow callbacks if we mmap the file. */
745 _IO_file_underflow_mmap (_IO_FILE
*fp
)
747 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
748 return *(unsigned char *) fp
->_IO_read_ptr
;
750 if (__builtin_expect (mmap_remap_check (fp
), 0))
751 /* We punted to the regular file functions. */
752 return _IO_UNDERFLOW (fp
);
754 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
755 return *(unsigned char *) fp
->_IO_read_ptr
;
757 fp
->_flags
|= _IO_EOF_SEEN
;
762 decide_maybe_mmap (_IO_FILE
*fp
)
764 /* We use the file in read-only mode. This could mean we can
765 mmap the file and use it without any copying. But not all
766 file descriptors are for mmap-able objects and on 32-bit
767 machines we don't want to map files which are too large since
768 this would require too much virtual memory. */
771 if (_IO_SYSSTAT (fp
, &st
) == 0
772 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
773 /* Limit the file size to 1MB for 32-bit machines. */
774 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024)
776 && (fp
->_offset
== _IO_pos_BAD
|| fp
->_offset
<= st
.st_size
))
778 /* Try to map the file. */
782 p
= _G_MMAP64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
784 p
= __mmap (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
788 /* OK, we managed to map the file. Set the buffer up and use a
789 special jump table with simplified underflow functions which
790 never tries to read anything from the file. */
798 (fp
->_fileno
, st
.st_size
, SEEK_SET
) != st
.st_size
)
800 (void) __munmap (p
, st
.st_size
);
801 fp
->_offset
= _IO_pos_BAD
;
805 INTUSE(_IO_setb
) (fp
, p
, (char *) p
+ st
.st_size
, 0);
807 if (fp
->_offset
== _IO_pos_BAD
)
810 _IO_setg (fp
, p
, p
+ fp
->_offset
, p
+ st
.st_size
);
811 fp
->_offset
= st
.st_size
;
814 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_file_jumps_mmap
;
816 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_wfile_jumps_mmap
;
817 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
824 /* We couldn't use mmap, so revert to the vanilla file operations. */
827 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
829 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
830 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
834 _IO_file_underflow_maybe_mmap (_IO_FILE
*fp
)
836 /* This is the first read attempt. Choose mmap or vanilla operations
837 and then punt to the chosen underflow routine. */
838 decide_maybe_mmap (fp
);
839 return _IO_UNDERFLOW (fp
);
844 _IO_new_file_overflow (f
, ch
)
848 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
850 f
->_flags
|= _IO_ERR_SEEN
;
854 /* If currently reading or no buffer allocated. */
855 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== NULL
)
857 /* Allocate a buffer if needed. */
858 if (f
->_IO_write_base
== NULL
)
860 INTUSE(_IO_doallocbuf
) (f
);
861 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
863 /* Otherwise must be currently reading.
864 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
865 logically slide the buffer forwards one block (by setting the
866 read pointers to all point at the beginning of the block). This
867 makes room for subsequent output.
868 Otherwise, set the read pointers to _IO_read_end (leaving that
869 alone, so it can continue to correspond to the external position). */
870 if (__builtin_expect (_IO_in_backup (f
), 0))
872 size_t nbackup
= f
->_IO_read_end
- f
->_IO_read_ptr
;
873 INTUSE(_IO_free_backup_area
) (f
);
874 f
->_IO_read_base
-= MIN (nbackup
,
875 f
->_IO_read_base
- f
->_IO_buf_base
);
876 f
->_IO_read_ptr
= f
->_IO_read_base
;
879 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
880 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
881 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
882 f
->_IO_write_base
= f
->_IO_write_ptr
;
883 f
->_IO_write_end
= f
->_IO_buf_end
;
884 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
886 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
887 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
888 f
->_IO_write_end
= f
->_IO_write_ptr
;
891 return INTUSE(_IO_do_write
) (f
, f
->_IO_write_base
,
892 f
->_IO_write_ptr
- f
->_IO_write_base
);
893 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
894 if (_IO_do_flush (f
) == EOF
)
896 *f
->_IO_write_ptr
++ = ch
;
897 if ((f
->_flags
& _IO_UNBUFFERED
)
898 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
899 if (INTUSE(_IO_do_write
) (f
, f
->_IO_write_base
,
900 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
902 return (unsigned char) ch
;
904 INTDEF2(_IO_new_file_overflow
, _IO_file_overflow
)
907 _IO_new_file_sync (fp
)
913 /* char* ptr = cur_ptr(); */
914 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
915 if (_IO_do_flush(fp
)) return EOF
;
916 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
920 if (_IO_in_backup (fp
))
921 delta
-= eGptr () - Gbase ();
923 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
924 if (new_pos
!= (_IO_off64_t
) EOF
)
925 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
927 else if (errno
== ESPIPE
)
928 ; /* Ignore error from unseekable devices. */
934 fp
->_offset
= _IO_pos_BAD
;
935 /* FIXME: Cleanup - can this be shared? */
936 /* setg(base(), ptr, ptr); */
939 INTDEF2(_IO_new_file_sync
, _IO_file_sync
)
942 _IO_file_sync_mmap (_IO_FILE
*fp
)
944 if (fp
->_IO_read_ptr
!= fp
->_IO_read_end
)
947 if (_IO_in_backup (fp
))
948 delta
-= eGptr () - Gbase ();
956 (fp
->_fileno
, fp
->_IO_read_ptr
- fp
->_IO_buf_base
, SEEK_SET
)
957 != fp
->_IO_read_ptr
- fp
->_IO_buf_base
)
959 fp
->_flags
|= _IO_ERR_SEEN
;
963 fp
->_offset
= fp
->_IO_read_ptr
- fp
->_IO_buf_base
;
964 fp
->_IO_read_end
= fp
->_IO_read_ptr
= fp
->_IO_read_base
;
970 _IO_new_file_seekoff (fp
, offset
, dir
, mode
)
977 _IO_off64_t delta
, new_offset
;
979 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
980 offset of the underlying file must be exact. */
981 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
982 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
985 dir
= _IO_seek_cur
, offset
= 0; /* Don't move any pointers. */
987 /* Flush unwritten characters.
988 (This may do an unneeded write if we seek within the buffer.
989 But to be able to switch to reading, we would need to set
990 egptr to ptr. That can't be done in the current design,
991 which assumes file_ptr() is eGptr. Anyway, since we probably
992 end up flushing when we close(), it doesn't make much difference.)
993 FIXME: simulate mem-papped files. */
995 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
|| _IO_in_put_mode (fp
))
996 if (INTUSE(_IO_switch_to_get_mode
) (fp
))
999 if (fp
->_IO_buf_base
== NULL
)
1001 /* It could be that we already have a pushback buffer. */
1002 if (fp
->_IO_read_base
!= NULL
)
1004 free (fp
->_IO_read_base
);
1005 fp
->_flags
&= ~_IO_IN_BACKUP
;
1007 INTUSE(_IO_doallocbuf
) (fp
);
1008 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1009 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1015 /* Adjust for read-ahead (bytes is buffer). */
1016 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1017 if (fp
->_offset
== _IO_pos_BAD
)
1023 result
= _IO_SYSSEEK (fp
, 0, dir
);
1027 fp
->_offset
= result
;
1030 /* Make offset absolute, assuming current pointer is file_ptr(). */
1031 offset
+= fp
->_offset
;
1034 __set_errno (EINVAL
);
1044 struct _G_stat64 st
;
1045 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
1047 offset
+= st
.st_size
;
1054 /* At this point, dir==_IO_seek_set. */
1056 /* If we are only interested in the current position we've found it now. */
1060 /* If destination is within current buffer, optimize: */
1061 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
1062 && !_IO_in_backup (fp
))
1064 _IO_off64_t start_offset
= (fp
->_offset
1065 - (fp
->_IO_read_end
- fp
->_IO_buf_base
));
1066 if (offset
>= start_offset
&& offset
< fp
->_offset
)
1068 _IO_setg (fp
, fp
->_IO_buf_base
,
1069 fp
->_IO_buf_base
+ (offset
- start_offset
),
1071 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1073 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1078 if (fp
->_flags
& _IO_NO_READS
)
1081 /* Try to seek to a block boundary, to improve kernel page management. */
1082 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
1083 delta
= offset
- new_offset
;
1084 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1086 new_offset
= offset
;
1089 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
1096 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
1098 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
1101 /* We weren't allowed to read, but try to seek the remainder. */
1102 offset
= count
== EOF
? delta
: delta
-count
;
1107 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
1108 fp
->_IO_buf_base
+ count
);
1109 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1110 fp
->_offset
= result
+ count
;
1111 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1115 INTUSE(_IO_unsave_markers
) (fp
);
1116 result
= _IO_SYSSEEK (fp
, offset
, dir
);
1119 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1120 fp
->_offset
= result
;
1121 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1122 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1127 /* We need to do it since it is possible that the file offset in
1128 the kernel may be changed behind our back. It may happen when
1129 we fopen a file and then do a fork. One process may access the
1130 file and the kernel file offset will be changed. */
1131 if (fp
->_offset
>= 0)
1132 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
1136 INTDEF2(_IO_new_file_seekoff
, _IO_file_seekoff
)
1139 _IO_file_seekoff_mmap (fp
, offset
, dir
, mode
)
1147 /* If we are only interested in the current position, calculate it and
1148 return right now. This calculation does the right thing when we are
1149 using a pushback buffer, but in the usual case has the same value as
1150 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1152 return fp
->_offset
- (fp
->_IO_read_end
- fp
->_IO_read_ptr
);
1157 /* Adjust for read-ahead (bytes is buffer). */
1158 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1163 offset
+= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1166 /* At this point, dir==_IO_seek_set. */
1170 /* No negative offsets are valid. */
1171 __set_errno (EINVAL
);
1175 result
= _IO_SYSSEEK (fp
, offset
, 0);
1179 if (offset
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1180 /* One can fseek arbitrarily past the end of the file
1181 and it is meaningless until one attempts to read.
1182 Leave the buffer pointers in EOF state until underflow. */
1183 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_end
, fp
->_IO_buf_end
);
1185 /* Adjust the read pointers to match the file position,
1186 but so the next read attempt will call underflow. */
1187 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ offset
,
1188 fp
->_IO_buf_base
+ offset
);
1190 fp
->_offset
= result
;
1192 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1198 _IO_file_seekoff_maybe_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
,
1201 /* We only get here when we haven't tried to read anything yet.
1202 So there is nothing more useful for us to do here than just
1203 the underlying lseek call. */
1205 _IO_off64_t result
= _IO_SYSSEEK (fp
, offset
, dir
);
1209 fp
->_offset
= result
;
1214 _IO_file_read (fp
, buf
, size
)
1219 return (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0)
1220 ? read_not_cancel (fp
->_fileno
, buf
, size
)
1221 : read (fp
->_fileno
, buf
, size
));
1223 INTDEF(_IO_file_read
)
1226 _IO_file_seek (fp
, offset
, dir
)
1232 return _G_LSEEK64 (fp
->_fileno
, offset
, dir
);
1234 return lseek (fp
->_fileno
, offset
, dir
);
1237 INTDEF(_IO_file_seek
)
1240 _IO_file_stat (fp
, st
)
1245 return _G_FSTAT64 (fp
->_fileno
, (struct _G_stat64
*) st
);
1247 return fstat (fp
->_fileno
, (struct stat
*) st
);
1250 INTDEF(_IO_file_stat
)
1253 _IO_file_close_mmap (fp
)
1256 /* In addition to closing the file descriptor we have to unmap the file. */
1257 (void) __munmap (fp
->_IO_buf_base
, fp
->_IO_buf_end
- fp
->_IO_buf_base
);
1258 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
1259 /* Cancelling close should be avoided if possible since it leaves an
1260 unrecoverable state behind. */
1261 return close_not_cancel (fp
->_fileno
);
1268 /* Cancelling close should be avoided if possible since it leaves an
1269 unrecoverable state behind. */
1270 return close_not_cancel (fp
->_fileno
);
1272 INTDEF(_IO_file_close
)
1275 _IO_new_file_write (f
, data
, n
)
1280 _IO_ssize_t to_do
= n
;
1283 _IO_ssize_t count
= (__builtin_expect (f
->_flags2
1284 & _IO_FLAGS2_NOTCANCEL
, 0)
1285 ? write_not_cancel (f
->_fileno
, data
, to_do
)
1286 : write (f
->_fileno
, data
, to_do
));
1289 f
->_flags
|= _IO_ERR_SEEN
;
1293 data
= (void *) ((char *) data
+ count
);
1296 if (f
->_offset
>= 0)
1302 _IO_new_file_xsputn (f
, data
, n
)
1307 register const char *s
= (const char *) data
;
1308 _IO_size_t to_do
= n
;
1310 _IO_size_t count
= 0;
1314 /* This is an optimized implementation.
1315 If the amount to be written straddles a block boundary
1316 (or the filebuf is unbuffered), use sys_write directly. */
1318 /* First figure out how much space is available in the buffer. */
1319 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
1321 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
1324 register const char *p
;
1325 for (p
= s
+ n
; p
> s
; )
1336 else if (f
->_IO_write_end
> f
->_IO_write_ptr
)
1337 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
1339 /* Then fill the buffer. */
1345 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
1347 memcpy (f
->_IO_write_ptr
, s
, count
);
1348 f
->_IO_write_ptr
+= count
;
1353 if (to_do
+ must_flush
> 0)
1355 _IO_size_t block_size
, do_write
;
1356 /* Next flush the (full) buffer. */
1357 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
1358 /* If nothing else has to be written we must not signal the
1359 caller that everything has been written. */
1360 return to_do
== 0 ? EOF
: n
- to_do
;
1362 /* Try to maintain alignment: write a whole number of blocks.
1363 dont_write is what gets left over. */
1364 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
1365 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
1369 count
= new_do_write (f
, s
, do_write
);
1371 if (count
< do_write
)
1375 /* Now write out the remainder. Normally, this will fit in the
1376 buffer, but it's somewhat messier for line-buffered files,
1377 so we let _IO_default_xsputn handle the general case. */
1379 to_do
-= INTUSE(_IO_default_xsputn
) (f
, s
+do_write
, to_do
);
1383 INTDEF2(_IO_new_file_xsputn
, _IO_file_xsputn
)
1386 _IO_file_xsgetn (fp
, data
, n
)
1391 register _IO_size_t want
, have
;
1392 register _IO_ssize_t count
;
1393 register char *s
= data
;
1397 if (fp
->_IO_buf_base
== NULL
)
1399 /* Maybe we already have a push back pointer. */
1400 if (fp
->_IO_save_base
!= NULL
)
1402 free (fp
->_IO_save_base
);
1403 fp
->_flags
&= ~_IO_IN_BACKUP
;
1405 INTUSE(_IO_doallocbuf
) (fp
);
1410 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1413 memcpy (s
, fp
->_IO_read_ptr
, want
);
1414 fp
->_IO_read_ptr
+= want
;
1422 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1424 memcpy (s
, fp
->_IO_read_ptr
, have
);
1428 fp
->_IO_read_ptr
+= have
;
1431 /* Check for backup and repeat */
1432 if (_IO_in_backup (fp
))
1434 _IO_switch_to_main_get_area (fp
);
1438 /* If we now want less than a buffer, underflow and repeat
1439 the copy. Otherwise, _IO_SYSREAD directly to
1441 if (fp
->_IO_buf_base
1442 && want
< (size_t) (fp
->_IO_buf_end
- fp
->_IO_buf_base
))
1444 if (__underflow (fp
) == EOF
)
1450 /* These must be set before the sysread as we might longjmp out
1451 waiting for input. */
1452 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1453 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1455 /* Try to maintain alignment: read a whole number of blocks. */
1457 if (fp
->_IO_buf_base
)
1459 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1460 if (block_size
>= 128)
1461 count
-= want
% block_size
;
1464 count
= _IO_SYSREAD (fp
, s
, count
);
1468 fp
->_flags
|= _IO_EOF_SEEN
;
1470 fp
->_flags
|= _IO_ERR_SEEN
;
1477 if (fp
->_offset
!= _IO_pos_BAD
)
1478 _IO_pos_adjust (fp
->_offset
, count
);
1484 INTDEF(_IO_file_xsgetn
)
1486 static _IO_size_t
_IO_file_xsgetn_mmap (_IO_FILE
*, void *, _IO_size_t
);
1488 _IO_file_xsgetn_mmap (fp
, data
, n
)
1493 register _IO_size_t have
;
1494 char *read_ptr
= fp
->_IO_read_ptr
;
1495 register char *s
= (char *) data
;
1497 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1501 if (__builtin_expect (_IO_in_backup (fp
), 0))
1504 s
= __mempcpy (s
, read_ptr
, have
);
1506 memcpy (s
, read_ptr
, have
);
1510 _IO_switch_to_main_get_area (fp
);
1511 read_ptr
= fp
->_IO_read_ptr
;
1512 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1517 /* Check that we are mapping all of the file, in case it grew. */
1518 if (__builtin_expect (mmap_remap_check (fp
), 0))
1519 /* We punted mmap, so complete with the vanilla code. */
1520 return s
- (char *) data
+ _IO_XSGETN (fp
, data
, n
);
1522 read_ptr
= fp
->_IO_read_ptr
;
1523 have
= fp
->_IO_read_end
- read_ptr
;
1528 fp
->_flags
|= _IO_EOF_SEEN
;
1532 have
= MIN (have
, n
);
1534 s
= __mempcpy (s
, read_ptr
, have
);
1536 memcpy (s
, read_ptr
, have
);
1539 fp
->_IO_read_ptr
= read_ptr
+ have
;
1542 return s
- (char *) data
;
1545 static _IO_size_t
_IO_file_xsgetn_maybe_mmap (_IO_FILE
*, void *, _IO_size_t
);
1547 _IO_file_xsgetn_maybe_mmap (fp
, data
, n
)
1552 /* We only get here if this is the first attempt to read something.
1553 Decide which operations to use and then punt to the chosen one. */
1555 decide_maybe_mmap (fp
);
1556 return _IO_XSGETN (fp
, data
, n
);
1560 # undef _IO_do_write
1561 # undef _IO_file_close_it
1562 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1563 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1564 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1565 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1566 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1567 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1568 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1569 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1570 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1571 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1572 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1573 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1574 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);
1577 const struct _IO_jump_t _IO_file_jumps
=
1580 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1581 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1582 JUMP_INIT(underflow
, INTUSE(_IO_file_underflow
)),
1583 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1584 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1585 JUMP_INIT(xsputn
, INTUSE(_IO_file_xsputn
)),
1586 JUMP_INIT(xsgetn
, INTUSE(_IO_file_xsgetn
)),
1587 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1588 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1589 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1590 JUMP_INIT(sync
, _IO_new_file_sync
),
1591 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1592 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1593 JUMP_INIT(write
, _IO_new_file_write
),
1594 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1595 JUMP_INIT(close
, INTUSE(_IO_file_close
)),
1596 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1597 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1598 JUMP_INIT(imbue
, _IO_default_imbue
)
1600 libc_hidden_data_def (_IO_file_jumps
)
1602 const struct _IO_jump_t _IO_file_jumps_mmap
=
1605 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1606 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1607 JUMP_INIT(underflow
, _IO_file_underflow_mmap
),
1608 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1609 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1610 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1611 JUMP_INIT(xsgetn
, _IO_file_xsgetn_mmap
),
1612 JUMP_INIT(seekoff
, _IO_file_seekoff_mmap
),
1613 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1614 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1615 JUMP_INIT(sync
, _IO_file_sync_mmap
),
1616 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1617 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1618 JUMP_INIT(write
, _IO_new_file_write
),
1619 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1620 JUMP_INIT(close
, _IO_file_close_mmap
),
1621 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1622 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1623 JUMP_INIT(imbue
, _IO_default_imbue
)
1626 const struct _IO_jump_t _IO_file_jumps_maybe_mmap
=
1629 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1630 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1631 JUMP_INIT(underflow
, _IO_file_underflow_maybe_mmap
),
1632 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1633 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1634 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1635 JUMP_INIT(xsgetn
, _IO_file_xsgetn_maybe_mmap
),
1636 JUMP_INIT(seekoff
, _IO_file_seekoff_maybe_mmap
),
1637 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1638 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1639 JUMP_INIT(sync
, _IO_new_file_sync
),
1640 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1641 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1642 JUMP_INIT(write
, _IO_new_file_write
),
1643 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1644 JUMP_INIT(close
, _IO_file_close
),
1645 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1646 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1647 JUMP_INIT(imbue
, _IO_default_imbue
)