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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
32 # define _POSIX_SOURCE
37 #include <sys/param.h>
38 #include <sys/types.h>
45 # include "../wcsmbs/wcsmbsload.h"
46 # include "../iconv/gconv_charset.h"
47 # include "../iconv/gconv_int.h"
48 # include <shlib-compat.h>
49 # include <not-cancel.h>
55 # define __set_errno(Val) errno = (Val)
60 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
61 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
62 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
63 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
64 # define _IO_do_write _IO_new_do_write /* For macro uses. */
65 # define _IO_file_close_it _IO_new_file_close_it
67 # define _IO_new_do_write _IO_do_write
68 # define _IO_new_file_attach _IO_file_attach
69 # define _IO_new_file_close_it _IO_file_close_it
70 # define _IO_new_file_finish _IO_file_finish
71 # define _IO_new_file_fopen _IO_file_fopen
72 # define _IO_new_file_init _IO_file_init
73 # define _IO_new_file_setbuf _IO_file_setbuf
74 # define _IO_new_file_sync _IO_file_sync
75 # define _IO_new_file_overflow _IO_file_overflow
76 # define _IO_new_file_seekoff _IO_file_seekoff
77 # define _IO_new_file_underflow _IO_file_underflow
78 # define _IO_new_file_write _IO_file_write
79 # define _IO_new_file_xsputn _IO_file_xsputn
84 extern struct __gconv_trans_data __libio_translit attribute_hidden
;
88 /* An fstream can be in at most one of put mode, get mode, or putback mode.
89 Putback mode is a variant of get mode.
91 In a filebuf, there is only one current position, instead of two
92 separate get and put pointers. In get mode, the current position
93 is that of gptr(); in put mode that of pptr().
95 The position in the buffer that corresponds to the position
96 in external file system is normally _IO_read_end, except in putback
97 mode, when it is _IO_save_end.
98 If the field _fb._offset is >= 0, it gives the offset in
99 the file as a whole corresponding to eGptr(). (?)
102 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
103 and _IO_read_base are equal to each other. These are usually equal
104 to _IO_buf_base, though not necessarily if we have switched from
105 get mode to put mode. (The reason is to maintain the invariant
106 that _IO_read_end corresponds to the external file position.)
107 _IO_write_base is non-NULL and usually equal to _IO_base_base.
108 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
109 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
112 If a filebuf is in get or putback mode, eback() != egptr().
113 In get mode, the unread characters are between gptr() and egptr().
114 The OS file position corresponds to that of egptr().
117 Putback mode is used to remember "excess" characters that have
118 been sputbackc'd in a separate putback buffer.
119 In putback mode, the get buffer points to the special putback buffer.
120 The unread characters are the characters between gptr() and egptr()
121 in the putback buffer, as well as the area between save_gptr()
122 and save_egptr(), which point into the original reserve buffer.
123 (The pointers save_gptr() and save_egptr() are the values
124 of gptr() and egptr() at the time putback mode was entered.)
125 The OS position corresponds to that of save_egptr().
127 LINE BUFFERED OUTPUT:
128 During line buffered output, _IO_write_base==base() && epptr()==base().
129 However, ptr() may be anywhere between base() and ebuf().
130 This forces a call to filebuf::overflow(int C) on every put.
131 If there is more space in the buffer, and C is not a '\n',
132 then C is inserted, and pptr() incremented.
135 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
138 #define CLOSED_FILEBUF_FLAGS \
139 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
143 _IO_new_file_init (fp
)
144 struct _IO_FILE_plus
*fp
;
146 /* POSIX.1 allows another file handle to be used to change the position
147 of our file descriptor. Hence we actually don't know the actual
148 position before we do the first fseek (and until a following fflush). */
149 fp
->file
._offset
= _IO_pos_BAD
;
150 fp
->file
._IO_file_flags
|= CLOSED_FILEBUF_FLAGS
;
152 INTUSE(_IO_link_in
) (fp
);
153 fp
->file
._fileno
= -1;
155 INTDEF2(_IO_new_file_init
, _IO_file_init
)
158 _IO_new_file_close_it (fp
)
161 if (!_IO_file_is_open (fp
))
165 if (_IO_in_put_mode (fp
))
166 write_status
= _IO_do_flush (fp
);
167 else if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
168 && !_IO_in_backup (fp
))
170 off64_t o
= _IO_SEEKOFF (fp
, 0, _IO_seek_cur
, 0);
174 write_status
= _IO_SYSSEEK (fp
, o
, SEEK_SET
) < 0 ? EOF
: 0;
179 INTUSE(_IO_unsave_markers
) (fp
);
181 int close_status
= ((fp
->_flags2
& _IO_FLAGS2_NOCLOSE
) == 0
182 ? _IO_SYSCLOSE (fp
) : 0);
185 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
188 if (_IO_have_wbackup (fp
))
189 INTUSE(_IO_free_wbackup_area
) (fp
);
190 INTUSE(_IO_wsetb
) (fp
, NULL
, NULL
, 0);
191 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
192 _IO_wsetp (fp
, NULL
, NULL
);
195 INTUSE(_IO_setb
) (fp
, NULL
, NULL
, 0);
196 _IO_setg (fp
, NULL
, NULL
, NULL
);
197 _IO_setp (fp
, NULL
, NULL
);
199 INTUSE(_IO_un_link
) ((struct _IO_FILE_plus
*) fp
);
200 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
202 fp
->_offset
= _IO_pos_BAD
;
204 return close_status
? close_status
: write_status
;
206 INTDEF2(_IO_new_file_close_it
, _IO_file_close_it
)
209 _IO_new_file_finish (fp
, dummy
)
213 if (_IO_file_is_open (fp
))
216 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
219 INTUSE(_IO_default_finish
) (fp
, 0);
221 INTDEF2(_IO_new_file_finish
, _IO_file_finish
)
224 _IO_file_open (fp
, filename
, posix_mode
, prot
, read_write
, is32not64
)
226 const char *filename
;
234 if (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0))
235 fdesc
= open_not_cancel (filename
,
236 posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
238 fdesc
= open (filename
, posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
240 fdesc
= open (filename
, posix_mode
, prot
);
245 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
246 if ((read_write
& _IO_IS_APPENDING
) && (read_write
& _IO_NO_READS
))
247 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_end
, _IOS_INPUT
|_IOS_OUTPUT
)
248 == _IO_pos_BAD
&& errno
!= ESPIPE
)
250 close_not_cancel (fdesc
);
253 INTUSE(_IO_link_in
) ((struct _IO_FILE_plus
*) fp
);
256 libc_hidden_def (_IO_file_open
)
259 _IO_new_file_fopen (fp
, filename
, mode
, is32not64
)
261 const char *filename
;
265 int oflags
= 0, omode
;
272 const char *last_recognized
;
275 if (_IO_file_is_open (fp
))
281 read_write
= _IO_NO_WRITES
;
285 oflags
= O_CREAT
|O_TRUNC
;
286 read_write
= _IO_NO_READS
;
290 oflags
= O_CREAT
|O_APPEND
;
291 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
294 __set_errno (EINVAL
);
298 last_recognized
= mode
;
300 for (i
= 1; i
< 7; ++i
)
308 read_write
&= _IO_IS_APPENDING
;
310 last_recognized
= mode
;
316 last_recognized
= mode
;
321 last_recognized
= mode
;
325 fp
->_flags2
|= _IO_FLAGS2_MMAP
;
328 fp
->_flags2
|= _IO_FLAGS2_NOTCANCEL
;
334 fp
->_flags2
|= _IO_FLAGS2_CLOEXEC
;
343 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
348 #ifndef __ASSUME_O_CLOEXEC
349 if ((fp
->_flags2
& _IO_FLAGS2_CLOEXEC
) != 0 && __have_o_cloexec
<= 0)
351 int fd
= _IO_fileno (fp
);
352 if (__have_o_cloexec
== 0)
354 int flags
= __fcntl (fd
, F_GETFD
);
355 __have_o_cloexec
= (flags
& FD_CLOEXEC
) == 0 ? -1 : 1;
357 if (__have_o_cloexec
< 0)
358 __fcntl (fd
, F_SETFD
, FD_CLOEXEC
);
362 /* Test whether the mode string specifies the conversion. */
363 cs
= strstr (last_recognized
+ 1, ",ccs=");
366 /* Yep. Load the appropriate conversions and set the orientation
368 struct gconv_fcts fcts
;
369 struct _IO_codecvt
*cc
;
370 char *endp
= __strchrnul (cs
+ 5, ',');
371 char ccs
[endp
- (cs
+ 5) + 3];
373 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
376 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
377 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
379 /* Something went wrong, we cannot load the conversion modules.
380 This means we cannot proceed since the user explicitly asked
382 (void) INTUSE(_IO_file_close_it
) (fp
);
383 __set_errno (EINVAL
);
387 assert (fcts
.towc_nsteps
== 1);
388 assert (fcts
.tomb_nsteps
== 1);
390 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
391 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
393 /* Clear the state. We start all over again. */
394 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
395 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
397 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
399 /* The functions are always the same. */
400 *cc
= __libio_codecvt
;
402 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
403 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
405 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
406 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
407 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
408 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
410 /* XXX For now no transliteration. */
411 cc
->__cd_in
.__cd
.__data
[0].__trans
= NULL
;
413 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
414 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
416 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
417 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
418 cc
->__cd_out
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
419 cc
->__cd_out
.__cd
.__data
[0].__statep
=
420 &result
->_wide_data
->_IO_state
;
422 /* And now the transliteration. */
423 cc
->__cd_out
.__cd
.__data
[0].__trans
= &__libio_translit
;
425 /* From now on use the wide character callback functions. */
426 ((struct _IO_FILE_plus
*) fp
)->vtable
= fp
->_wide_data
->_wide_vtable
;
428 /* Set the mode now. */
435 INTDEF2(_IO_new_file_fopen
, _IO_file_fopen
)
438 _IO_new_file_attach (fp
, fd
)
442 if (_IO_file_is_open (fp
))
445 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
446 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
447 /* Get the current position of the file. */
448 /* We have to do that since that may be junk. */
449 fp
->_offset
= _IO_pos_BAD
;
450 int save_errno
= errno
;
451 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
452 == _IO_pos_BAD
&& errno
!= ESPIPE
)
454 __set_errno (save_errno
);
457 INTDEF2(_IO_new_file_attach
, _IO_file_attach
)
460 _IO_new_file_setbuf (fp
, p
, len
)
465 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
468 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
470 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
474 INTDEF2(_IO_new_file_setbuf
, _IO_file_setbuf
)
478 _IO_file_setbuf_mmap (fp
, p
, len
)
485 /* Change the function table. */
486 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
487 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
489 /* And perform the normal operation. */
490 result
= _IO_new_file_setbuf (fp
, p
, len
);
492 /* If the call failed, restore to using mmap. */
495 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps_mmap
;
496 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
502 static _IO_size_t
new_do_write (_IO_FILE
*, const char *, _IO_size_t
);
504 /* Write TO_DO bytes from DATA to FP.
505 Then mark FP as having empty buffers. */
508 _IO_new_do_write (fp
, data
, to_do
)
514 || (_IO_size_t
) new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
516 INTDEF2(_IO_new_do_write
, _IO_do_write
)
520 new_do_write (fp
, data
, to_do
)
526 if (fp
->_flags
& _IO_IS_APPENDING
)
527 /* On a system without a proper O_APPEND implementation,
528 you would need to sys_seek(0, SEEK_END) here, but is
529 not needed nor desirable for Unix- or Posix-like systems.
530 Instead, just indicate that offset (before and after) is
532 fp
->_offset
= _IO_pos_BAD
;
533 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
536 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
537 if (new_pos
== _IO_pos_BAD
)
539 fp
->_offset
= new_pos
;
541 count
= _IO_SYSWRITE (fp
, data
, to_do
);
542 if (fp
->_cur_column
&& count
)
543 fp
->_cur_column
= INTUSE(_IO_adjust_column
) (fp
->_cur_column
- 1, data
,
545 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
546 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
547 fp
->_IO_write_end
= (fp
->_mode
<= 0
548 && (fp
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
549 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
554 _IO_new_file_underflow (fp
)
559 /* SysV does not make this test; take it out for compatibility */
560 if (fp
->_flags
& _IO_EOF_SEEN
)
564 if (fp
->_flags
& _IO_NO_READS
)
566 fp
->_flags
|= _IO_ERR_SEEN
;
570 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
571 return *(unsigned char *) fp
->_IO_read_ptr
;
573 if (fp
->_IO_buf_base
== NULL
)
575 /* Maybe we already have a push back pointer. */
576 if (fp
->_IO_save_base
!= NULL
)
578 free (fp
->_IO_save_base
);
579 fp
->_flags
&= ~_IO_IN_BACKUP
;
581 INTUSE(_IO_doallocbuf
) (fp
);
584 /* Flush all line buffered files before reading. */
585 /* FIXME This can/should be moved to genops ?? */
586 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
589 INTUSE(_IO_flush_all_linebuffered
) ();
591 /* We used to flush all line-buffered stream. This really isn't
592 required by any standard. My recollection is that
593 traditional Unix systems did this for stdout. stderr better
594 not be line buffered. So we do just that here
595 explicitly. --drepper */
596 _IO_acquire_lock (_IO_stdout
);
598 if ((_IO_stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
599 == (_IO_LINKED
| _IO_LINE_BUF
))
600 _IO_OVERFLOW (_IO_stdout
, EOF
);
602 _IO_release_lock (_IO_stdout
);
606 INTUSE(_IO_switch_to_get_mode
) (fp
);
608 /* This is very tricky. We have to adjust those
609 pointers before we call _IO_SYSREAD () since
610 we may longjump () out while waiting for
611 input. Those pointers may be screwed up. H.J. */
612 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
613 fp
->_IO_read_end
= fp
->_IO_buf_base
;
614 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
617 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
618 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
622 fp
->_flags
|= _IO_EOF_SEEN
;
624 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
626 fp
->_IO_read_end
+= count
;
629 if (fp
->_offset
!= _IO_pos_BAD
)
630 _IO_pos_adjust (fp
->_offset
, count
);
631 return *(unsigned char *) fp
->_IO_read_ptr
;
633 INTDEF2(_IO_new_file_underflow
, _IO_file_underflow
)
635 /* Guts of underflow callback if we mmap the file. This stats the file and
636 updates the stream state to match. In the normal case we return zero.
637 If the file is no longer eligible for mmap, its jump tables are reset to
638 the vanilla ones and we return nonzero. */
640 mmap_remap_check (_IO_FILE
*fp
)
644 if (_IO_SYSSTAT (fp
, &st
) == 0
645 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
646 /* Limit the file size to 1MB for 32-bit machines. */
647 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024))
649 const size_t pagesize
= __getpagesize ();
650 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
651 if (ROUNDED (st
.st_size
) < ROUNDED (fp
->_IO_buf_end
654 /* We can trim off some pages past the end of the file. */
655 (void) __munmap (fp
->_IO_buf_base
+ ROUNDED (st
.st_size
),
656 ROUNDED (fp
->_IO_buf_end
- fp
->_IO_buf_base
)
657 - ROUNDED (st
.st_size
));
658 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
660 else if (ROUNDED (st
.st_size
) > ROUNDED (fp
->_IO_buf_end
663 /* The file added some pages. We need to remap it. */
665 #ifdef _G_HAVE_MREMAP
666 p
= __mremap (fp
->_IO_buf_base
, ROUNDED (fp
->_IO_buf_end
668 ROUNDED (st
.st_size
), MREMAP_MAYMOVE
);
671 (void) __munmap (fp
->_IO_buf_base
,
672 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
676 (void) __munmap (fp
->_IO_buf_base
,
677 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
679 p
= _G_MMAP64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
682 p
= __mmap (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
688 fp
->_IO_buf_base
= p
;
689 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
693 /* The number of pages didn't change. */
694 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
698 fp
->_offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
699 _IO_setg (fp
, fp
->_IO_buf_base
,
700 fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
701 ? fp
->_IO_buf_base
+ fp
->_offset
: fp
->_IO_buf_end
,
704 /* If we are already positioned at or past the end of the file, don't
705 change the current offset. If not, seek past what we have mapped,
706 mimicking the position left by a normal underflow reading into its
709 if (fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
717 (fp
->_fileno
, fp
->_IO_buf_end
- fp
->_IO_buf_base
, SEEK_SET
)
718 != fp
->_IO_buf_end
- fp
->_IO_buf_base
)
719 fp
->_flags
|= _IO_ERR_SEEN
;
721 fp
->_offset
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
728 /* Life is no longer good for mmap. Punt it. */
729 (void) __munmap (fp
->_IO_buf_base
,
730 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
732 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
733 _IO_setg (fp
, NULL
, NULL
, NULL
);
735 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
737 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
738 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
744 /* Special callback replacing the underflow callbacks if we mmap the file. */
746 _IO_file_underflow_mmap (_IO_FILE
*fp
)
748 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
749 return *(unsigned char *) fp
->_IO_read_ptr
;
751 if (__builtin_expect (mmap_remap_check (fp
), 0))
752 /* We punted to the regular file functions. */
753 return _IO_UNDERFLOW (fp
);
755 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
756 return *(unsigned char *) fp
->_IO_read_ptr
;
758 fp
->_flags
|= _IO_EOF_SEEN
;
763 decide_maybe_mmap (_IO_FILE
*fp
)
765 /* We use the file in read-only mode. This could mean we can
766 mmap the file and use it without any copying. But not all
767 file descriptors are for mmap-able objects and on 32-bit
768 machines we don't want to map files which are too large since
769 this would require too much virtual memory. */
772 if (_IO_SYSSTAT (fp
, &st
) == 0
773 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
774 /* Limit the file size to 1MB for 32-bit machines. */
775 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024)
777 && (fp
->_offset
== _IO_pos_BAD
|| fp
->_offset
<= st
.st_size
))
779 /* Try to map the file. */
783 p
= _G_MMAP64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
785 p
= __mmap (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
789 /* OK, we managed to map the file. Set the buffer up and use a
790 special jump table with simplified underflow functions which
791 never tries to read anything from the file. */
799 (fp
->_fileno
, st
.st_size
, SEEK_SET
) != st
.st_size
)
801 (void) __munmap (p
, st
.st_size
);
802 fp
->_offset
= _IO_pos_BAD
;
806 INTUSE(_IO_setb
) (fp
, p
, (char *) p
+ st
.st_size
, 0);
808 if (fp
->_offset
== _IO_pos_BAD
)
811 _IO_setg (fp
, p
, p
+ fp
->_offset
, p
+ st
.st_size
);
812 fp
->_offset
= st
.st_size
;
815 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_file_jumps_mmap
;
817 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_wfile_jumps_mmap
;
818 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
825 /* We couldn't use mmap, so revert to the vanilla file operations. */
828 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
830 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
831 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
835 _IO_file_underflow_maybe_mmap (_IO_FILE
*fp
)
837 /* This is the first read attempt. Choose mmap or vanilla operations
838 and then punt to the chosen underflow routine. */
839 decide_maybe_mmap (fp
);
840 return _IO_UNDERFLOW (fp
);
845 _IO_new_file_overflow (f
, ch
)
849 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
851 f
->_flags
|= _IO_ERR_SEEN
;
855 /* If currently reading or no buffer allocated. */
856 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== NULL
)
858 /* Allocate a buffer if needed. */
859 if (f
->_IO_write_base
== NULL
)
861 INTUSE(_IO_doallocbuf
) (f
);
862 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
864 /* Otherwise must be currently reading.
865 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
866 logically slide the buffer forwards one block (by setting the
867 read pointers to all point at the beginning of the block). This
868 makes room for subsequent output.
869 Otherwise, set the read pointers to _IO_read_end (leaving that
870 alone, so it can continue to correspond to the external position). */
871 if (__builtin_expect (_IO_in_backup (f
), 0))
873 size_t nbackup
= f
->_IO_read_end
- f
->_IO_read_ptr
;
874 INTUSE(_IO_free_backup_area
) (f
);
875 f
->_IO_read_base
-= MIN (nbackup
,
876 f
->_IO_read_base
- f
->_IO_buf_base
);
877 f
->_IO_read_ptr
= f
->_IO_read_base
;
880 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
881 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
882 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
883 f
->_IO_write_base
= f
->_IO_write_ptr
;
884 f
->_IO_write_end
= f
->_IO_buf_end
;
885 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
887 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
888 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
889 f
->_IO_write_end
= f
->_IO_write_ptr
;
892 return INTUSE(_IO_do_write
) (f
, f
->_IO_write_base
,
893 f
->_IO_write_ptr
- f
->_IO_write_base
);
894 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
895 if (_IO_do_flush (f
) == EOF
)
897 *f
->_IO_write_ptr
++ = ch
;
898 if ((f
->_flags
& _IO_UNBUFFERED
)
899 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
900 if (INTUSE(_IO_do_write
) (f
, f
->_IO_write_base
,
901 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
903 return (unsigned char) ch
;
905 INTDEF2(_IO_new_file_overflow
, _IO_file_overflow
)
908 _IO_new_file_sync (fp
)
914 /* char* ptr = cur_ptr(); */
915 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
916 if (_IO_do_flush(fp
)) return EOF
;
917 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
921 if (_IO_in_backup (fp
))
922 delta
-= eGptr () - Gbase ();
924 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
925 if (new_pos
!= (_IO_off64_t
) EOF
)
926 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
928 else if (errno
== ESPIPE
)
929 ; /* Ignore error from unseekable devices. */
935 fp
->_offset
= _IO_pos_BAD
;
936 /* FIXME: Cleanup - can this be shared? */
937 /* setg(base(), ptr, ptr); */
940 INTDEF2(_IO_new_file_sync
, _IO_file_sync
)
943 _IO_file_sync_mmap (_IO_FILE
*fp
)
945 if (fp
->_IO_read_ptr
!= fp
->_IO_read_end
)
948 if (_IO_in_backup (fp
))
949 delta
-= eGptr () - Gbase ();
957 (fp
->_fileno
, fp
->_IO_read_ptr
- fp
->_IO_buf_base
, SEEK_SET
)
958 != fp
->_IO_read_ptr
- fp
->_IO_buf_base
)
960 fp
->_flags
|= _IO_ERR_SEEN
;
964 fp
->_offset
= fp
->_IO_read_ptr
- fp
->_IO_buf_base
;
965 fp
->_IO_read_end
= fp
->_IO_read_ptr
= fp
->_IO_read_base
;
971 _IO_new_file_seekoff (fp
, offset
, dir
, mode
)
978 _IO_off64_t delta
, new_offset
;
980 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
981 offset of the underlying file must be exact. */
982 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
983 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
986 dir
= _IO_seek_cur
, offset
= 0; /* Don't move any pointers. */
988 /* Flush unwritten characters.
989 (This may do an unneeded write if we seek within the buffer.
990 But to be able to switch to reading, we would need to set
991 egptr to ptr. That can't be done in the current design,
992 which assumes file_ptr() is eGptr. Anyway, since we probably
993 end up flushing when we close(), it doesn't make much difference.)
994 FIXME: simulate mem-papped files. */
996 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
|| _IO_in_put_mode (fp
))
997 if (INTUSE(_IO_switch_to_get_mode
) (fp
))
1000 if (fp
->_IO_buf_base
== NULL
)
1002 /* It could be that we already have a pushback buffer. */
1003 if (fp
->_IO_read_base
!= NULL
)
1005 free (fp
->_IO_read_base
);
1006 fp
->_flags
&= ~_IO_IN_BACKUP
;
1008 INTUSE(_IO_doallocbuf
) (fp
);
1009 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1010 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1016 /* Adjust for read-ahead (bytes is buffer). */
1017 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1018 if (fp
->_offset
== _IO_pos_BAD
)
1024 result
= _IO_SYSSEEK (fp
, 0, dir
);
1028 fp
->_offset
= result
;
1031 /* Make offset absolute, assuming current pointer is file_ptr(). */
1032 offset
+= fp
->_offset
;
1035 __set_errno (EINVAL
);
1045 struct _G_stat64 st
;
1046 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
1048 offset
+= st
.st_size
;
1055 /* At this point, dir==_IO_seek_set. */
1057 /* If we are only interested in the current position we've found it now. */
1061 /* If destination is within current buffer, optimize: */
1062 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
1063 && !_IO_in_backup (fp
))
1065 _IO_off64_t start_offset
= (fp
->_offset
1066 - (fp
->_IO_read_end
- fp
->_IO_buf_base
));
1067 if (offset
>= start_offset
&& offset
< fp
->_offset
)
1069 _IO_setg (fp
, fp
->_IO_buf_base
,
1070 fp
->_IO_buf_base
+ (offset
- start_offset
),
1072 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1074 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1079 if (fp
->_flags
& _IO_NO_READS
)
1082 /* Try to seek to a block boundary, to improve kernel page management. */
1083 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
1084 delta
= offset
- new_offset
;
1085 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1087 new_offset
= offset
;
1090 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
1097 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
1099 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
1102 /* We weren't allowed to read, but try to seek the remainder. */
1103 offset
= count
== EOF
? delta
: delta
-count
;
1108 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
1109 fp
->_IO_buf_base
+ count
);
1110 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1111 fp
->_offset
= result
+ count
;
1112 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1116 INTUSE(_IO_unsave_markers
) (fp
);
1117 result
= _IO_SYSSEEK (fp
, offset
, dir
);
1120 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1121 fp
->_offset
= result
;
1122 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1123 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1128 /* We need to do it since it is possible that the file offset in
1129 the kernel may be changed behind our back. It may happen when
1130 we fopen a file and then do a fork. One process may access the
1131 file and the kernel file offset will be changed. */
1132 if (fp
->_offset
>= 0)
1133 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
1137 INTDEF2(_IO_new_file_seekoff
, _IO_file_seekoff
)
1140 _IO_file_seekoff_mmap (fp
, offset
, dir
, mode
)
1148 /* If we are only interested in the current position, calculate it and
1149 return right now. This calculation does the right thing when we are
1150 using a pushback buffer, but in the usual case has the same value as
1151 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1153 return fp
->_offset
- (fp
->_IO_read_end
- fp
->_IO_read_ptr
);
1158 /* Adjust for read-ahead (bytes is buffer). */
1159 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1164 offset
+= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1167 /* At this point, dir==_IO_seek_set. */
1171 /* No negative offsets are valid. */
1172 __set_errno (EINVAL
);
1176 result
= _IO_SYSSEEK (fp
, offset
, 0);
1180 if (offset
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1181 /* One can fseek arbitrarily past the end of the file
1182 and it is meaningless until one attempts to read.
1183 Leave the buffer pointers in EOF state until underflow. */
1184 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_end
, fp
->_IO_buf_end
);
1186 /* Adjust the read pointers to match the file position,
1187 but so the next read attempt will call underflow. */
1188 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ offset
,
1189 fp
->_IO_buf_base
+ offset
);
1191 fp
->_offset
= result
;
1193 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1199 _IO_file_seekoff_maybe_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
,
1202 /* We only get here when we haven't tried to read anything yet.
1203 So there is nothing more useful for us to do here than just
1204 the underlying lseek call. */
1206 _IO_off64_t result
= _IO_SYSSEEK (fp
, offset
, dir
);
1210 fp
->_offset
= result
;
1215 _IO_file_read (fp
, buf
, size
)
1220 return (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0)
1221 ? read_not_cancel (fp
->_fileno
, buf
, size
)
1222 : read (fp
->_fileno
, buf
, size
));
1224 INTDEF(_IO_file_read
)
1227 _IO_file_seek (fp
, offset
, dir
)
1233 return _G_LSEEK64 (fp
->_fileno
, offset
, dir
);
1235 return lseek (fp
->_fileno
, offset
, dir
);
1238 INTDEF(_IO_file_seek
)
1241 _IO_file_stat (fp
, st
)
1246 return _G_FSTAT64 (fp
->_fileno
, (struct _G_stat64
*) st
);
1248 return fstat (fp
->_fileno
, (struct stat
*) st
);
1251 INTDEF(_IO_file_stat
)
1254 _IO_file_close_mmap (fp
)
1257 /* In addition to closing the file descriptor we have to unmap the file. */
1258 (void) __munmap (fp
->_IO_buf_base
, fp
->_IO_buf_end
- fp
->_IO_buf_base
);
1259 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
1260 /* Cancelling close should be avoided if possible since it leaves an
1261 unrecoverable state behind. */
1262 return close_not_cancel (fp
->_fileno
);
1269 /* Cancelling close should be avoided if possible since it leaves an
1270 unrecoverable state behind. */
1271 return close_not_cancel (fp
->_fileno
);
1273 INTDEF(_IO_file_close
)
1276 _IO_new_file_write (f
, data
, n
)
1281 _IO_ssize_t to_do
= n
;
1284 _IO_ssize_t count
= (__builtin_expect (f
->_flags2
1285 & _IO_FLAGS2_NOTCANCEL
, 0)
1286 ? write_not_cancel (f
->_fileno
, data
, to_do
)
1287 : write (f
->_fileno
, data
, to_do
));
1290 f
->_flags
|= _IO_ERR_SEEN
;
1294 data
= (void *) ((char *) data
+ count
);
1297 if (f
->_offset
>= 0)
1303 _IO_new_file_xsputn (f
, data
, n
)
1308 register const char *s
= (const char *) data
;
1309 _IO_size_t to_do
= n
;
1311 _IO_size_t count
= 0;
1315 /* This is an optimized implementation.
1316 If the amount to be written straddles a block boundary
1317 (or the filebuf is unbuffered), use sys_write directly. */
1319 /* First figure out how much space is available in the buffer. */
1320 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
1322 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
1325 register const char *p
;
1326 for (p
= s
+ n
; p
> s
; )
1337 else if (f
->_IO_write_end
> f
->_IO_write_ptr
)
1338 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
1340 /* Then fill the buffer. */
1348 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
1350 memcpy (f
->_IO_write_ptr
, s
, count
);
1351 f
->_IO_write_ptr
+= count
;
1357 register char *p
= f
->_IO_write_ptr
;
1358 register int i
= (int) count
;
1361 f
->_IO_write_ptr
= p
;
1365 if (to_do
+ must_flush
> 0)
1367 _IO_size_t block_size
, do_write
;
1368 /* Next flush the (full) buffer. */
1369 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
1370 /* If nothing else has to be written we must not signal the
1371 caller that everything has been written. */
1372 return to_do
== 0 ? EOF
: n
- to_do
;
1374 /* Try to maintain alignment: write a whole number of blocks.
1375 dont_write is what gets left over. */
1376 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
1377 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
1381 count
= new_do_write (f
, s
, do_write
);
1383 if (count
< do_write
)
1387 /* Now write out the remainder. Normally, this will fit in the
1388 buffer, but it's somewhat messier for line-buffered files,
1389 so we let _IO_default_xsputn handle the general case. */
1391 to_do
-= INTUSE(_IO_default_xsputn
) (f
, s
+do_write
, to_do
);
1395 INTDEF2(_IO_new_file_xsputn
, _IO_file_xsputn
)
1398 _IO_file_xsgetn (fp
, data
, n
)
1403 register _IO_size_t want
, have
;
1404 register _IO_ssize_t count
;
1405 register char *s
= data
;
1409 if (fp
->_IO_buf_base
== NULL
)
1411 /* Maybe we already have a push back pointer. */
1412 if (fp
->_IO_save_base
!= NULL
)
1414 free (fp
->_IO_save_base
);
1415 fp
->_flags
&= ~_IO_IN_BACKUP
;
1417 INTUSE(_IO_doallocbuf
) (fp
);
1422 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1425 memcpy (s
, fp
->_IO_read_ptr
, want
);
1426 fp
->_IO_read_ptr
+= want
;
1434 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1436 memcpy (s
, fp
->_IO_read_ptr
, have
);
1440 fp
->_IO_read_ptr
+= have
;
1443 /* Check for backup and repeat */
1444 if (_IO_in_backup (fp
))
1446 _IO_switch_to_main_get_area (fp
);
1450 /* If we now want less than a buffer, underflow and repeat
1451 the copy. Otherwise, _IO_SYSREAD directly to
1453 if (fp
->_IO_buf_base
1454 && want
< (size_t) (fp
->_IO_buf_end
- fp
->_IO_buf_base
))
1456 if (__underflow (fp
) == EOF
)
1462 /* These must be set before the sysread as we might longjmp out
1463 waiting for input. */
1464 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1465 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1467 /* Try to maintain alignment: read a whole number of blocks. */
1469 if (fp
->_IO_buf_base
)
1471 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1472 if (block_size
>= 128)
1473 count
-= want
% block_size
;
1476 count
= _IO_SYSREAD (fp
, s
, count
);
1480 fp
->_flags
|= _IO_EOF_SEEN
;
1482 fp
->_flags
|= _IO_ERR_SEEN
;
1489 if (fp
->_offset
!= _IO_pos_BAD
)
1490 _IO_pos_adjust (fp
->_offset
, count
);
1496 INTDEF(_IO_file_xsgetn
)
1498 static _IO_size_t
_IO_file_xsgetn_mmap (_IO_FILE
*, void *, _IO_size_t
);
1500 _IO_file_xsgetn_mmap (fp
, data
, n
)
1505 register _IO_size_t have
;
1506 char *read_ptr
= fp
->_IO_read_ptr
;
1507 register char *s
= (char *) data
;
1509 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1513 if (__builtin_expect (_IO_in_backup (fp
), 0))
1516 s
= __mempcpy (s
, read_ptr
, have
);
1518 memcpy (s
, read_ptr
, have
);
1522 _IO_switch_to_main_get_area (fp
);
1523 read_ptr
= fp
->_IO_read_ptr
;
1524 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1529 /* Check that we are mapping all of the file, in case it grew. */
1530 if (__builtin_expect (mmap_remap_check (fp
), 0))
1531 /* We punted mmap, so complete with the vanilla code. */
1532 return s
- (char *) data
+ _IO_XSGETN (fp
, data
, n
);
1534 read_ptr
= fp
->_IO_read_ptr
;
1535 have
= fp
->_IO_read_end
- read_ptr
;
1540 fp
->_flags
|= _IO_EOF_SEEN
;
1544 have
= MIN (have
, n
);
1546 s
= __mempcpy (s
, read_ptr
, have
);
1548 memcpy (s
, read_ptr
, have
);
1551 fp
->_IO_read_ptr
= read_ptr
+ have
;
1554 return s
- (char *) data
;
1557 static _IO_size_t
_IO_file_xsgetn_maybe_mmap (_IO_FILE
*, void *, _IO_size_t
);
1559 _IO_file_xsgetn_maybe_mmap (fp
, data
, n
)
1564 /* We only get here if this is the first attempt to read something.
1565 Decide which operations to use and then punt to the chosen one. */
1567 decide_maybe_mmap (fp
);
1568 return _IO_XSGETN (fp
, data
, n
);
1572 # undef _IO_do_write
1573 # undef _IO_file_close_it
1574 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1575 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1576 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1577 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1578 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1579 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1580 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1581 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1582 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1583 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1584 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1585 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1586 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);
1589 const struct _IO_jump_t _IO_file_jumps
=
1592 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1593 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1594 JUMP_INIT(underflow
, INTUSE(_IO_file_underflow
)),
1595 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1596 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1597 JUMP_INIT(xsputn
, INTUSE(_IO_file_xsputn
)),
1598 JUMP_INIT(xsgetn
, INTUSE(_IO_file_xsgetn
)),
1599 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1600 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1601 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1602 JUMP_INIT(sync
, _IO_new_file_sync
),
1603 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1604 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1605 JUMP_INIT(write
, _IO_new_file_write
),
1606 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1607 JUMP_INIT(close
, INTUSE(_IO_file_close
)),
1608 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1609 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1610 JUMP_INIT(imbue
, _IO_default_imbue
)
1612 libc_hidden_data_def (_IO_file_jumps
)
1614 const struct _IO_jump_t _IO_file_jumps_mmap
=
1617 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1618 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1619 JUMP_INIT(underflow
, _IO_file_underflow_mmap
),
1620 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1621 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1622 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1623 JUMP_INIT(xsgetn
, _IO_file_xsgetn_mmap
),
1624 JUMP_INIT(seekoff
, _IO_file_seekoff_mmap
),
1625 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1626 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1627 JUMP_INIT(sync
, _IO_file_sync_mmap
),
1628 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1629 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1630 JUMP_INIT(write
, _IO_new_file_write
),
1631 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1632 JUMP_INIT(close
, _IO_file_close_mmap
),
1633 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1634 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1635 JUMP_INIT(imbue
, _IO_default_imbue
)
1638 const struct _IO_jump_t _IO_file_jumps_maybe_mmap
=
1641 JUMP_INIT(finish
, INTUSE(_IO_file_finish
)),
1642 JUMP_INIT(overflow
, INTUSE(_IO_file_overflow
)),
1643 JUMP_INIT(underflow
, _IO_file_underflow_maybe_mmap
),
1644 JUMP_INIT(uflow
, INTUSE(_IO_default_uflow
)),
1645 JUMP_INIT(pbackfail
, INTUSE(_IO_default_pbackfail
)),
1646 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1647 JUMP_INIT(xsgetn
, _IO_file_xsgetn_maybe_mmap
),
1648 JUMP_INIT(seekoff
, _IO_file_seekoff_maybe_mmap
),
1649 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1650 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1651 JUMP_INIT(sync
, _IO_new_file_sync
),
1652 JUMP_INIT(doallocate
, INTUSE(_IO_file_doallocate
)),
1653 JUMP_INIT(read
, INTUSE(_IO_file_read
)),
1654 JUMP_INIT(write
, _IO_new_file_write
),
1655 JUMP_INIT(seek
, INTUSE(_IO_file_seek
)),
1656 JUMP_INIT(close
, _IO_file_close
),
1657 JUMP_INIT(stat
, INTUSE(_IO_file_stat
)),
1658 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1659 JUMP_INIT(imbue
, _IO_default_imbue
)