1 /* Copyright (C) 1993-2019 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
33 #include <sys/param.h>
34 #include <sys/types.h>
40 #include "../wcsmbs/wcsmbsload.h"
41 #include "../iconv/gconv_charset.h"
42 #include "../iconv/gconv_int.h"
43 #include <shlib-compat.h>
44 #include <not-cancel.h>
45 #include <kernel-features.h>
47 extern struct __gconv_trans_data __libio_translit attribute_hidden
;
49 /* An fstream can be in at most one of put mode, get mode, or putback mode.
50 Putback mode is a variant of get mode.
52 In a filebuf, there is only one current position, instead of two
53 separate get and put pointers. In get mode, the current position
54 is that of gptr(); in put mode that of pptr().
56 The position in the buffer that corresponds to the position
57 in external file system is normally _IO_read_end, except in putback
58 mode, when it is _IO_save_end and also when the file is in append mode,
59 since switching from read to write mode automatically sends the position in
60 the external file system to the end of file.
61 If the field _fb._offset is >= 0, it gives the offset in
62 the file as a whole corresponding to eGptr(). (?)
65 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
66 and _IO_read_base are equal to each other. These are usually equal
67 to _IO_buf_base, though not necessarily if we have switched from
68 get mode to put mode. (The reason is to maintain the invariant
69 that _IO_read_end corresponds to the external file position.)
70 _IO_write_base is non-NULL and usually equal to _IO_buf_base.
71 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
72 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
75 If a filebuf is in get or putback mode, eback() != egptr().
76 In get mode, the unread characters are between gptr() and egptr().
77 The OS file position corresponds to that of egptr().
80 Putback mode is used to remember "excess" characters that have
81 been sputbackc'd in a separate putback buffer.
82 In putback mode, the get buffer points to the special putback buffer.
83 The unread characters are the characters between gptr() and egptr()
84 in the putback buffer, as well as the area between save_gptr()
85 and save_egptr(), which point into the original reserve buffer.
86 (The pointers save_gptr() and save_egptr() are the values
87 of gptr() and egptr() at the time putback mode was entered.)
88 The OS position corresponds to that of save_egptr().
91 During line buffered output, _IO_write_base==base() && epptr()==base().
92 However, ptr() may be anywhere between base() and ebuf().
93 This forces a call to filebuf::overflow(int C) on every put.
94 If there is more space in the buffer, and C is not a '\n',
95 then C is inserted, and pptr() incremented.
98 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
101 #define CLOSED_FILEBUF_FLAGS \
102 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
106 _IO_new_file_init_internal (struct _IO_FILE_plus
*fp
)
108 /* POSIX.1 allows another file handle to be used to change the position
109 of our file descriptor. Hence we actually don't know the actual
110 position before we do the first fseek (and until a following fflush). */
111 fp
->file
._offset
= _IO_pos_BAD
;
112 fp
->file
._flags
|= CLOSED_FILEBUF_FLAGS
;
115 fp
->file
._fileno
= -1;
118 /* External version of _IO_new_file_init_internal which switches off
119 vtable validation. */
121 _IO_new_file_init (struct _IO_FILE_plus
*fp
)
123 IO_set_accept_foreign_vtables (&_IO_vtable_check
);
124 _IO_new_file_init_internal (fp
);
128 _IO_new_file_close_it (FILE *fp
)
131 if (!_IO_file_is_open (fp
))
134 if ((fp
->_flags
& _IO_NO_WRITES
) == 0
135 && (fp
->_flags
& _IO_CURRENTLY_PUTTING
) != 0)
136 write_status
= _IO_do_flush (fp
);
140 _IO_unsave_markers (fp
);
142 int close_status
= ((fp
->_flags2
& _IO_FLAGS2_NOCLOSE
) == 0
143 ? _IO_SYSCLOSE (fp
) : 0);
148 if (_IO_have_wbackup (fp
))
149 _IO_free_wbackup_area (fp
);
150 _IO_wsetb (fp
, NULL
, NULL
, 0);
151 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
152 _IO_wsetp (fp
, NULL
, NULL
);
154 _IO_setb (fp
, NULL
, NULL
, 0);
155 _IO_setg (fp
, NULL
, NULL
, NULL
);
156 _IO_setp (fp
, NULL
, NULL
);
158 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
159 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
161 fp
->_offset
= _IO_pos_BAD
;
163 return close_status
? close_status
: write_status
;
165 libc_hidden_ver (_IO_new_file_close_it
, _IO_file_close_it
)
168 _IO_new_file_finish (FILE *fp
, int dummy
)
170 if (_IO_file_is_open (fp
))
173 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
176 _IO_default_finish (fp
, 0);
178 libc_hidden_ver (_IO_new_file_finish
, _IO_file_finish
)
181 _IO_file_open (FILE *fp
, const char *filename
, int posix_mode
, int prot
,
182 int read_write
, int is32not64
)
185 if (__glibc_unlikely (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
))
186 fdesc
= __open_nocancel (filename
,
187 posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
189 fdesc
= __open (filename
, posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
193 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
194 /* For append mode, send the file offset to the end of the file. Don't
195 update the offset cache though, since the file handle is not active. */
196 if ((read_write
& (_IO_IS_APPENDING
| _IO_NO_READS
))
197 == (_IO_IS_APPENDING
| _IO_NO_READS
))
199 off64_t new_pos
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
200 if (new_pos
== _IO_pos_BAD
&& errno
!= ESPIPE
)
202 __close_nocancel (fdesc
);
206 _IO_link_in ((struct _IO_FILE_plus
*) fp
);
209 libc_hidden_def (_IO_file_open
)
212 _IO_new_file_fopen (FILE *fp
, const char *filename
, const char *mode
,
215 int oflags
= 0, omode
;
221 const char *last_recognized
;
223 if (_IO_file_is_open (fp
))
229 read_write
= _IO_NO_WRITES
;
233 oflags
= O_CREAT
|O_TRUNC
;
234 read_write
= _IO_NO_READS
;
238 oflags
= O_CREAT
|O_APPEND
;
239 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
242 __set_errno (EINVAL
);
245 last_recognized
= mode
;
246 for (i
= 1; i
< 7; ++i
)
254 read_write
&= _IO_IS_APPENDING
;
255 last_recognized
= mode
;
259 last_recognized
= mode
;
262 last_recognized
= mode
;
265 fp
->_flags2
|= _IO_FLAGS2_MMAP
;
268 fp
->_flags2
|= _IO_FLAGS2_NOTCANCEL
;
272 fp
->_flags2
|= _IO_FLAGS2_CLOEXEC
;
281 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
286 /* Test whether the mode string specifies the conversion. */
287 cs
= strstr (last_recognized
+ 1, ",ccs=");
290 /* Yep. Load the appropriate conversions and set the orientation
292 struct gconv_fcts fcts
;
293 struct _IO_codecvt
*cc
;
294 char *endp
= __strchrnul (cs
+ 5, ',');
295 char *ccs
= malloc (endp
- (cs
+ 5) + 3);
299 int malloc_err
= errno
; /* Whatever malloc failed with. */
300 (void) _IO_file_close_it (fp
);
301 __set_errno (malloc_err
);
305 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
308 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
309 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
311 /* Something went wrong, we cannot load the conversion modules.
312 This means we cannot proceed since the user explicitly asked
314 (void) _IO_file_close_it (fp
);
316 __set_errno (EINVAL
);
322 assert (fcts
.towc_nsteps
== 1);
323 assert (fcts
.tomb_nsteps
== 1);
325 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
326 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
328 /* Clear the state. We start all over again. */
329 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
330 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
332 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
334 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
335 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
337 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
338 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
339 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
340 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
342 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
343 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
345 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
346 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
347 cc
->__cd_out
.__cd
.__data
[0].__flags
348 = __GCONV_IS_LAST
| __GCONV_TRANSLIT
;
349 cc
->__cd_out
.__cd
.__data
[0].__statep
=
350 &result
->_wide_data
->_IO_state
;
352 /* From now on use the wide character callback functions. */
353 _IO_JUMPS_FILE_plus (fp
) = fp
->_wide_data
->_wide_vtable
;
355 /* Set the mode now. */
362 libc_hidden_ver (_IO_new_file_fopen
, _IO_file_fopen
)
365 _IO_new_file_attach (FILE *fp
, int fd
)
367 if (_IO_file_is_open (fp
))
370 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
371 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
372 /* Get the current position of the file. */
373 /* We have to do that since that may be junk. */
374 fp
->_offset
= _IO_pos_BAD
;
375 int save_errno
= errno
;
376 if (_IO_SEEKOFF (fp
, (off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
377 == _IO_pos_BAD
&& errno
!= ESPIPE
)
379 __set_errno (save_errno
);
382 libc_hidden_ver (_IO_new_file_attach
, _IO_file_attach
)
385 _IO_new_file_setbuf (FILE *fp
, char *p
, ssize_t len
)
387 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
390 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
392 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
396 libc_hidden_ver (_IO_new_file_setbuf
, _IO_file_setbuf
)
400 _IO_file_setbuf_mmap (FILE *fp
, char *p
, ssize_t len
)
404 /* Change the function table. */
405 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
406 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
408 /* And perform the normal operation. */
409 result
= _IO_new_file_setbuf (fp
, p
, len
);
411 /* If the call failed, restore to using mmap. */
414 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps_mmap
;
415 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
421 static size_t new_do_write (FILE *, const char *, size_t);
423 /* Write TO_DO bytes from DATA to FP.
424 Then mark FP as having empty buffers. */
427 _IO_new_do_write (FILE *fp
, const char *data
, size_t to_do
)
430 || (size_t) new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
432 libc_hidden_ver (_IO_new_do_write
, _IO_do_write
)
435 new_do_write (FILE *fp
, const char *data
, size_t to_do
)
438 if (fp
->_flags
& _IO_IS_APPENDING
)
439 /* On a system without a proper O_APPEND implementation,
440 you would need to sys_seek(0, SEEK_END) here, but is
441 not needed nor desirable for Unix- or Posix-like systems.
442 Instead, just indicate that offset (before and after) is
444 fp
->_offset
= _IO_pos_BAD
;
445 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
448 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
449 if (new_pos
== _IO_pos_BAD
)
451 fp
->_offset
= new_pos
;
453 count
= _IO_SYSWRITE (fp
, data
, to_do
);
454 if (fp
->_cur_column
&& count
)
455 fp
->_cur_column
= _IO_adjust_column (fp
->_cur_column
- 1, data
, count
) + 1;
456 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
457 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
458 fp
->_IO_write_end
= (fp
->_mode
<= 0
459 && (fp
->_flags
& (_IO_LINE_BUF
| _IO_UNBUFFERED
))
460 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
465 _IO_new_file_underflow (FILE *fp
)
469 /* C99 requires EOF to be "sticky". */
470 if (fp
->_flags
& _IO_EOF_SEEN
)
473 if (fp
->_flags
& _IO_NO_READS
)
475 fp
->_flags
|= _IO_ERR_SEEN
;
479 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
480 return *(unsigned char *) fp
->_IO_read_ptr
;
482 if (fp
->_IO_buf_base
== NULL
)
484 /* Maybe we already have a push back pointer. */
485 if (fp
->_IO_save_base
!= NULL
)
487 free (fp
->_IO_save_base
);
488 fp
->_flags
&= ~_IO_IN_BACKUP
;
493 /* FIXME This can/should be moved to genops ?? */
494 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
496 /* We used to flush all line-buffered stream. This really isn't
497 required by any standard. My recollection is that
498 traditional Unix systems did this for stdout. stderr better
499 not be line buffered. So we do just that here
500 explicitly. --drepper */
501 _IO_acquire_lock (stdout
);
503 if ((stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
504 == (_IO_LINKED
| _IO_LINE_BUF
))
505 _IO_OVERFLOW (stdout
, EOF
);
507 _IO_release_lock (stdout
);
510 _IO_switch_to_get_mode (fp
);
512 /* This is very tricky. We have to adjust those
513 pointers before we call _IO_SYSREAD () since
514 we may longjump () out while waiting for
515 input. Those pointers may be screwed up. H.J. */
516 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
517 fp
->_IO_read_end
= fp
->_IO_buf_base
;
518 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
521 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
522 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
526 fp
->_flags
|= _IO_EOF_SEEN
;
528 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
530 fp
->_IO_read_end
+= count
;
533 /* If a stream is read to EOF, the calling application may switch active
534 handles. As a result, our offset cache would no longer be valid, so
536 fp
->_offset
= _IO_pos_BAD
;
539 if (fp
->_offset
!= _IO_pos_BAD
)
540 _IO_pos_adjust (fp
->_offset
, count
);
541 return *(unsigned char *) fp
->_IO_read_ptr
;
543 libc_hidden_ver (_IO_new_file_underflow
, _IO_file_underflow
)
545 /* Guts of underflow callback if we mmap the file. This stats the file and
546 updates the stream state to match. In the normal case we return zero.
547 If the file is no longer eligible for mmap, its jump tables are reset to
548 the vanilla ones and we return nonzero. */
550 mmap_remap_check (FILE *fp
)
554 if (_IO_SYSSTAT (fp
, &st
) == 0
555 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
556 /* Limit the file size to 1MB for 32-bit machines. */
557 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024))
559 const size_t pagesize
= __getpagesize ();
560 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
561 if (ROUNDED (st
.st_size
) < ROUNDED (fp
->_IO_buf_end
564 /* We can trim off some pages past the end of the file. */
565 (void) __munmap (fp
->_IO_buf_base
+ ROUNDED (st
.st_size
),
566 ROUNDED (fp
->_IO_buf_end
- fp
->_IO_buf_base
)
567 - ROUNDED (st
.st_size
));
568 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
570 else if (ROUNDED (st
.st_size
) > ROUNDED (fp
->_IO_buf_end
573 /* The file added some pages. We need to remap it. */
576 p
= __mremap (fp
->_IO_buf_base
, ROUNDED (fp
->_IO_buf_end
578 ROUNDED (st
.st_size
), MREMAP_MAYMOVE
);
581 (void) __munmap (fp
->_IO_buf_base
,
582 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
586 (void) __munmap (fp
->_IO_buf_base
,
587 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
588 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
593 fp
->_IO_buf_base
= p
;
594 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
598 /* The number of pages didn't change. */
599 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
603 fp
->_offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
604 _IO_setg (fp
, fp
->_IO_buf_base
,
605 fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
606 ? fp
->_IO_buf_base
+ fp
->_offset
: fp
->_IO_buf_end
,
609 /* If we are already positioned at or past the end of the file, don't
610 change the current offset. If not, seek past what we have mapped,
611 mimicking the position left by a normal underflow reading into its
614 if (fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
616 if (__lseek64 (fp
->_fileno
, fp
->_IO_buf_end
- fp
->_IO_buf_base
,
618 != fp
->_IO_buf_end
- fp
->_IO_buf_base
)
619 fp
->_flags
|= _IO_ERR_SEEN
;
621 fp
->_offset
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
628 /* Life is no longer good for mmap. Punt it. */
629 (void) __munmap (fp
->_IO_buf_base
,
630 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
632 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
633 _IO_setg (fp
, NULL
, NULL
, NULL
);
635 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
637 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps
;
638 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
644 /* Special callback replacing the underflow callbacks if we mmap the file. */
646 _IO_file_underflow_mmap (FILE *fp
)
648 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
649 return *(unsigned char *) fp
->_IO_read_ptr
;
651 if (__glibc_unlikely (mmap_remap_check (fp
)))
652 /* We punted to the regular file functions. */
653 return _IO_UNDERFLOW (fp
);
655 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
656 return *(unsigned char *) fp
->_IO_read_ptr
;
658 fp
->_flags
|= _IO_EOF_SEEN
;
663 decide_maybe_mmap (FILE *fp
)
665 /* We use the file in read-only mode. This could mean we can
666 mmap the file and use it without any copying. But not all
667 file descriptors are for mmap-able objects and on 32-bit
668 machines we don't want to map files which are too large since
669 this would require too much virtual memory. */
672 if (_IO_SYSSTAT (fp
, &st
) == 0
673 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
674 /* Limit the file size to 1MB for 32-bit machines. */
675 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024)
677 && (fp
->_offset
== _IO_pos_BAD
|| fp
->_offset
<= st
.st_size
))
679 /* Try to map the file. */
682 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
685 /* OK, we managed to map the file. Set the buffer up and use a
686 special jump table with simplified underflow functions which
687 never tries to read anything from the file. */
689 if (__lseek64 (fp
->_fileno
, st
.st_size
, SEEK_SET
) != st
.st_size
)
691 (void) __munmap (p
, st
.st_size
);
692 fp
->_offset
= _IO_pos_BAD
;
696 _IO_setb (fp
, p
, (char *) p
+ st
.st_size
, 0);
698 if (fp
->_offset
== _IO_pos_BAD
)
701 _IO_setg (fp
, p
, p
+ fp
->_offset
, p
+ st
.st_size
);
702 fp
->_offset
= st
.st_size
;
705 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps_mmap
;
707 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps_mmap
;
708 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
715 /* We couldn't use mmap, so revert to the vanilla file operations. */
718 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
720 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps
;
721 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
725 _IO_file_underflow_maybe_mmap (FILE *fp
)
727 /* This is the first read attempt. Choose mmap or vanilla operations
728 and then punt to the chosen underflow routine. */
729 decide_maybe_mmap (fp
);
730 return _IO_UNDERFLOW (fp
);
735 _IO_new_file_overflow (FILE *f
, int ch
)
737 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
739 f
->_flags
|= _IO_ERR_SEEN
;
743 /* If currently reading or no buffer allocated. */
744 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== NULL
)
746 /* Allocate a buffer if needed. */
747 if (f
->_IO_write_base
== NULL
)
750 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
752 /* Otherwise must be currently reading.
753 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
754 logically slide the buffer forwards one block (by setting the
755 read pointers to all point at the beginning of the block). This
756 makes room for subsequent output.
757 Otherwise, set the read pointers to _IO_read_end (leaving that
758 alone, so it can continue to correspond to the external position). */
759 if (__glibc_unlikely (_IO_in_backup (f
)))
761 size_t nbackup
= f
->_IO_read_end
- f
->_IO_read_ptr
;
762 _IO_free_backup_area (f
);
763 f
->_IO_read_base
-= MIN (nbackup
,
764 f
->_IO_read_base
- f
->_IO_buf_base
);
765 f
->_IO_read_ptr
= f
->_IO_read_base
;
768 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
769 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
770 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
771 f
->_IO_write_base
= f
->_IO_write_ptr
;
772 f
->_IO_write_end
= f
->_IO_buf_end
;
773 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
775 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
776 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
| _IO_UNBUFFERED
))
777 f
->_IO_write_end
= f
->_IO_write_ptr
;
780 return _IO_do_write (f
, f
->_IO_write_base
,
781 f
->_IO_write_ptr
- f
->_IO_write_base
);
782 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
783 if (_IO_do_flush (f
) == EOF
)
785 *f
->_IO_write_ptr
++ = ch
;
786 if ((f
->_flags
& _IO_UNBUFFERED
)
787 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
788 if (_IO_do_write (f
, f
->_IO_write_base
,
789 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
791 return (unsigned char) ch
;
793 libc_hidden_ver (_IO_new_file_overflow
, _IO_file_overflow
)
796 _IO_new_file_sync (FILE *fp
)
801 /* char* ptr = cur_ptr(); */
802 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
803 if (_IO_do_flush(fp
)) return EOF
;
804 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
807 off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
808 if (new_pos
!= (off64_t
) EOF
)
809 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
810 else if (errno
== ESPIPE
)
811 ; /* Ignore error from unseekable devices. */
816 fp
->_offset
= _IO_pos_BAD
;
817 /* FIXME: Cleanup - can this be shared? */
818 /* setg(base(), ptr, ptr); */
821 libc_hidden_ver (_IO_new_file_sync
, _IO_file_sync
)
824 _IO_file_sync_mmap (FILE *fp
)
826 if (fp
->_IO_read_ptr
!= fp
->_IO_read_end
)
828 if (__lseek64 (fp
->_fileno
, fp
->_IO_read_ptr
- fp
->_IO_buf_base
,
830 != fp
->_IO_read_ptr
- fp
->_IO_buf_base
)
832 fp
->_flags
|= _IO_ERR_SEEN
;
836 fp
->_offset
= fp
->_IO_read_ptr
- fp
->_IO_buf_base
;
837 fp
->_IO_read_end
= fp
->_IO_read_ptr
= fp
->_IO_read_base
;
841 /* ftell{,o} implementation. The only time we modify the state of the stream
842 is when we have unflushed writes. In that case we seek to the end and
843 record that offset in the stream object. */
847 off64_t result
, offset
= 0;
849 /* No point looking at unflushed data if we haven't allocated buffers
851 if (fp
->_IO_buf_base
!= NULL
)
853 bool unflushed_writes
= fp
->_IO_write_ptr
> fp
->_IO_write_base
;
855 bool append_mode
= (fp
->_flags
& _IO_IS_APPENDING
) == _IO_IS_APPENDING
;
857 /* When we have unflushed writes in append mode, seek to the end of the
858 file and record that offset. This is the only time we change the file
859 stream state and it is safe since the file handle is active. */
860 if (unflushed_writes
&& append_mode
)
862 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
863 if (result
== _IO_pos_BAD
)
866 fp
->_offset
= result
;
869 /* Adjust for unflushed data. */
870 if (!unflushed_writes
)
871 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
872 /* We don't trust _IO_read_end to represent the current file offset when
873 writing in append mode because the value would have to be shifted to
874 the end of the file during a flush. Use the write base instead, along
875 with the new offset we got above when we did a seek to the end of the
877 else if (append_mode
)
878 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
879 /* For all other modes, _IO_read_end represents the file offset. */
881 offset
+= fp
->_IO_write_ptr
- fp
->_IO_read_end
;
884 if (fp
->_offset
!= _IO_pos_BAD
)
885 result
= fp
->_offset
;
887 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_cur
);
896 __set_errno (EINVAL
);
904 _IO_new_file_seekoff (FILE *fp
, off64_t offset
, int dir
, int mode
)
907 off64_t delta
, new_offset
;
910 /* Short-circuit into a separate function. We don't want to mix any
911 functionality and we don't want to touch anything inside the FILE
914 return do_ftell (fp
);
916 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
917 offset of the underlying file must be exact. */
918 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
919 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
921 bool was_writing
= (fp
->_IO_write_ptr
> fp
->_IO_write_base
922 || _IO_in_put_mode (fp
));
924 /* Flush unwritten characters.
925 (This may do an unneeded write if we seek within the buffer.
926 But to be able to switch to reading, we would need to set
927 egptr to pptr. That can't be done in the current design,
928 which assumes file_ptr() is eGptr. Anyway, since we probably
929 end up flushing when we close(), it doesn't make much difference.)
930 FIXME: simulate mem-mapped files. */
931 if (was_writing
&& _IO_switch_to_get_mode (fp
))
934 if (fp
->_IO_buf_base
== NULL
)
936 /* It could be that we already have a pushback buffer. */
937 if (fp
->_IO_read_base
!= NULL
)
939 free (fp
->_IO_read_base
);
940 fp
->_flags
&= ~_IO_IN_BACKUP
;
943 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
944 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
950 /* Adjust for read-ahead (bytes is buffer). */
951 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
953 if (fp
->_offset
== _IO_pos_BAD
)
955 /* Make offset absolute, assuming current pointer is file_ptr(). */
956 offset
+= fp
->_offset
;
959 __set_errno (EINVAL
);
970 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
972 offset
+= st
.st_size
;
980 _IO_free_backup_area (fp
);
982 /* At this point, dir==_IO_seek_set. */
984 /* If destination is within current buffer, optimize: */
985 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
986 && !_IO_in_backup (fp
))
988 off64_t start_offset
= (fp
->_offset
989 - (fp
->_IO_read_end
- fp
->_IO_buf_base
));
990 if (offset
>= start_offset
&& offset
< fp
->_offset
)
992 _IO_setg (fp
, fp
->_IO_buf_base
,
993 fp
->_IO_buf_base
+ (offset
- start_offset
),
995 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
997 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1002 if (fp
->_flags
& _IO_NO_READS
)
1005 /* Try to seek to a block boundary, to improve kernel page management. */
1006 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
1007 delta
= offset
- new_offset
;
1008 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1010 new_offset
= offset
;
1013 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
1020 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
1022 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
1025 /* We weren't allowed to read, but try to seek the remainder. */
1026 offset
= count
== EOF
? delta
: delta
-count
;
1031 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
1032 fp
->_IO_buf_base
+ count
);
1033 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1034 fp
->_offset
= result
+ count
;
1035 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1039 _IO_unsave_markers (fp
);
1040 result
= _IO_SYSSEEK (fp
, offset
, dir
);
1043 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1044 fp
->_offset
= result
;
1045 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1046 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1051 /* We need to do it since it is possible that the file offset in
1052 the kernel may be changed behind our back. It may happen when
1053 we fopen a file and then do a fork. One process may access the
1054 file and the kernel file offset will be changed. */
1055 if (fp
->_offset
>= 0)
1056 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
1060 libc_hidden_ver (_IO_new_file_seekoff
, _IO_file_seekoff
)
1063 _IO_file_seekoff_mmap (FILE *fp
, off64_t offset
, int dir
, int mode
)
1067 /* If we are only interested in the current position, calculate it and
1068 return right now. This calculation does the right thing when we are
1069 using a pushback buffer, but in the usual case has the same value as
1070 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1072 return fp
->_offset
- (fp
->_IO_read_end
- fp
->_IO_read_ptr
);
1077 /* Adjust for read-ahead (bytes is buffer). */
1078 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1083 offset
+= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1086 /* At this point, dir==_IO_seek_set. */
1090 /* No negative offsets are valid. */
1091 __set_errno (EINVAL
);
1095 result
= _IO_SYSSEEK (fp
, offset
, 0);
1099 if (offset
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1100 /* One can fseek arbitrarily past the end of the file
1101 and it is meaningless until one attempts to read.
1102 Leave the buffer pointers in EOF state until underflow. */
1103 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_end
, fp
->_IO_buf_end
);
1105 /* Adjust the read pointers to match the file position,
1106 but so the next read attempt will call underflow. */
1107 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ offset
,
1108 fp
->_IO_buf_base
+ offset
);
1110 fp
->_offset
= result
;
1112 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1118 _IO_file_seekoff_maybe_mmap (FILE *fp
, off64_t offset
, int dir
,
1121 /* We only get here when we haven't tried to read anything yet.
1122 So there is nothing more useful for us to do here than just
1123 the underlying lseek call. */
1125 off64_t result
= _IO_SYSSEEK (fp
, offset
, dir
);
1129 fp
->_offset
= result
;
1134 _IO_file_read (FILE *fp
, void *buf
, ssize_t size
)
1136 return (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0)
1137 ? __read_nocancel (fp
->_fileno
, buf
, size
)
1138 : __read (fp
->_fileno
, buf
, size
));
1140 libc_hidden_def (_IO_file_read
)
1143 _IO_file_seek (FILE *fp
, off64_t offset
, int dir
)
1145 return __lseek64 (fp
->_fileno
, offset
, dir
);
1147 libc_hidden_def (_IO_file_seek
)
1150 _IO_file_stat (FILE *fp
, void *st
)
1152 return __fxstat64 (_STAT_VER
, fp
->_fileno
, (struct stat64
*) st
);
1154 libc_hidden_def (_IO_file_stat
)
1157 _IO_file_close_mmap (FILE *fp
)
1159 /* In addition to closing the file descriptor we have to unmap the file. */
1160 (void) __munmap (fp
->_IO_buf_base
, fp
->_IO_buf_end
- fp
->_IO_buf_base
);
1161 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
1162 /* Cancelling close should be avoided if possible since it leaves an
1163 unrecoverable state behind. */
1164 return __close_nocancel (fp
->_fileno
);
1168 _IO_file_close (FILE *fp
)
1170 /* Cancelling close should be avoided if possible since it leaves an
1171 unrecoverable state behind. */
1172 return __close_nocancel (fp
->_fileno
);
1174 libc_hidden_def (_IO_file_close
)
1177 _IO_new_file_write (FILE *f
, const void *data
, ssize_t n
)
1182 ssize_t count
= (__builtin_expect (f
->_flags2
1183 & _IO_FLAGS2_NOTCANCEL
, 0)
1184 ? __write_nocancel (f
->_fileno
, data
, to_do
)
1185 : __write (f
->_fileno
, data
, to_do
));
1188 f
->_flags
|= _IO_ERR_SEEN
;
1192 data
= (void *) ((char *) data
+ count
);
1195 if (f
->_offset
>= 0)
1201 _IO_new_file_xsputn (FILE *f
, const void *data
, size_t n
)
1203 const char *s
= (const char *) data
;
1210 /* This is an optimized implementation.
1211 If the amount to be written straddles a block boundary
1212 (or the filebuf is unbuffered), use sys_write directly. */
1214 /* First figure out how much space is available in the buffer. */
1215 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
1217 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
1221 for (p
= s
+ n
; p
> s
; )
1232 else if (f
->_IO_write_end
> f
->_IO_write_ptr
)
1233 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
1235 /* Then fill the buffer. */
1240 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
1244 if (to_do
+ must_flush
> 0)
1246 size_t block_size
, do_write
;
1247 /* Next flush the (full) buffer. */
1248 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
1249 /* If nothing else has to be written we must not signal the
1250 caller that everything has been written. */
1251 return to_do
== 0 ? EOF
: n
- to_do
;
1253 /* Try to maintain alignment: write a whole number of blocks. */
1254 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
1255 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
1259 count
= new_do_write (f
, s
, do_write
);
1261 if (count
< do_write
)
1265 /* Now write out the remainder. Normally, this will fit in the
1266 buffer, but it's somewhat messier for line-buffered files,
1267 so we let _IO_default_xsputn handle the general case. */
1269 to_do
-= _IO_default_xsputn (f
, s
+do_write
, to_do
);
1273 libc_hidden_ver (_IO_new_file_xsputn
, _IO_file_xsputn
)
1276 _IO_file_xsgetn (FILE *fp
, void *data
, size_t n
)
1284 if (fp
->_IO_buf_base
== NULL
)
1286 /* Maybe we already have a push back pointer. */
1287 if (fp
->_IO_save_base
!= NULL
)
1289 free (fp
->_IO_save_base
);
1290 fp
->_flags
&= ~_IO_IN_BACKUP
;
1292 _IO_doallocbuf (fp
);
1297 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1300 memcpy (s
, fp
->_IO_read_ptr
, want
);
1301 fp
->_IO_read_ptr
+= want
;
1308 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1310 fp
->_IO_read_ptr
+= have
;
1313 /* Check for backup and repeat */
1314 if (_IO_in_backup (fp
))
1316 _IO_switch_to_main_get_area (fp
);
1320 /* If we now want less than a buffer, underflow and repeat
1321 the copy. Otherwise, _IO_SYSREAD directly to
1323 if (fp
->_IO_buf_base
1324 && want
< (size_t) (fp
->_IO_buf_end
- fp
->_IO_buf_base
))
1326 if (__underflow (fp
) == EOF
)
1332 /* These must be set before the sysread as we might longjmp out
1333 waiting for input. */
1334 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1335 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1337 /* Try to maintain alignment: read a whole number of blocks. */
1339 if (fp
->_IO_buf_base
)
1341 size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1342 if (block_size
>= 128)
1343 count
-= want
% block_size
;
1346 count
= _IO_SYSREAD (fp
, s
, count
);
1350 fp
->_flags
|= _IO_EOF_SEEN
;
1352 fp
->_flags
|= _IO_ERR_SEEN
;
1359 if (fp
->_offset
!= _IO_pos_BAD
)
1360 _IO_pos_adjust (fp
->_offset
, count
);
1366 libc_hidden_def (_IO_file_xsgetn
)
1369 _IO_file_xsgetn_mmap (FILE *fp
, void *data
, size_t n
)
1372 char *read_ptr
= fp
->_IO_read_ptr
;
1373 char *s
= (char *) data
;
1375 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1379 if (__glibc_unlikely (_IO_in_backup (fp
)))
1381 s
= __mempcpy (s
, read_ptr
, have
);
1383 _IO_switch_to_main_get_area (fp
);
1384 read_ptr
= fp
->_IO_read_ptr
;
1385 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1390 /* Check that we are mapping all of the file, in case it grew. */
1391 if (__glibc_unlikely (mmap_remap_check (fp
)))
1392 /* We punted mmap, so complete with the vanilla code. */
1393 return s
- (char *) data
+ _IO_XSGETN (fp
, data
, n
);
1395 read_ptr
= fp
->_IO_read_ptr
;
1396 have
= fp
->_IO_read_end
- read_ptr
;
1401 fp
->_flags
|= _IO_EOF_SEEN
;
1405 have
= MIN (have
, n
);
1406 s
= __mempcpy (s
, read_ptr
, have
);
1407 fp
->_IO_read_ptr
= read_ptr
+ have
;
1410 return s
- (char *) data
;
1414 _IO_file_xsgetn_maybe_mmap (FILE *fp
, void *data
, size_t n
)
1416 /* We only get here if this is the first attempt to read something.
1417 Decide which operations to use and then punt to the chosen one. */
1419 decide_maybe_mmap (fp
);
1420 return _IO_XSGETN (fp
, data
, n
);
1423 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1424 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1425 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1426 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1427 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1428 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1429 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1430 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1431 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1432 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1433 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1434 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1435 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);
1437 const struct _IO_jump_t _IO_file_jumps libio_vtable
=
1440 JUMP_INIT(finish
, _IO_file_finish
),
1441 JUMP_INIT(overflow
, _IO_file_overflow
),
1442 JUMP_INIT(underflow
, _IO_file_underflow
),
1443 JUMP_INIT(uflow
, _IO_default_uflow
),
1444 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1445 JUMP_INIT(xsputn
, _IO_file_xsputn
),
1446 JUMP_INIT(xsgetn
, _IO_file_xsgetn
),
1447 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1448 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1449 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1450 JUMP_INIT(sync
, _IO_new_file_sync
),
1451 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1452 JUMP_INIT(read
, _IO_file_read
),
1453 JUMP_INIT(write
, _IO_new_file_write
),
1454 JUMP_INIT(seek
, _IO_file_seek
),
1455 JUMP_INIT(close
, _IO_file_close
),
1456 JUMP_INIT(stat
, _IO_file_stat
),
1457 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1458 JUMP_INIT(imbue
, _IO_default_imbue
)
1460 libc_hidden_data_def (_IO_file_jumps
)
1462 const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable
=
1465 JUMP_INIT(finish
, _IO_file_finish
),
1466 JUMP_INIT(overflow
, _IO_file_overflow
),
1467 JUMP_INIT(underflow
, _IO_file_underflow_mmap
),
1468 JUMP_INIT(uflow
, _IO_default_uflow
),
1469 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1470 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1471 JUMP_INIT(xsgetn
, _IO_file_xsgetn_mmap
),
1472 JUMP_INIT(seekoff
, _IO_file_seekoff_mmap
),
1473 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1474 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1475 JUMP_INIT(sync
, _IO_file_sync_mmap
),
1476 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1477 JUMP_INIT(read
, _IO_file_read
),
1478 JUMP_INIT(write
, _IO_new_file_write
),
1479 JUMP_INIT(seek
, _IO_file_seek
),
1480 JUMP_INIT(close
, _IO_file_close_mmap
),
1481 JUMP_INIT(stat
, _IO_file_stat
),
1482 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1483 JUMP_INIT(imbue
, _IO_default_imbue
)
1486 const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable
=
1489 JUMP_INIT(finish
, _IO_file_finish
),
1490 JUMP_INIT(overflow
, _IO_file_overflow
),
1491 JUMP_INIT(underflow
, _IO_file_underflow_maybe_mmap
),
1492 JUMP_INIT(uflow
, _IO_default_uflow
),
1493 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1494 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1495 JUMP_INIT(xsgetn
, _IO_file_xsgetn_maybe_mmap
),
1496 JUMP_INIT(seekoff
, _IO_file_seekoff_maybe_mmap
),
1497 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1498 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1499 JUMP_INIT(sync
, _IO_new_file_sync
),
1500 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1501 JUMP_INIT(read
, _IO_file_read
),
1502 JUMP_INIT(write
, _IO_new_file_write
),
1503 JUMP_INIT(seek
, _IO_file_seek
),
1504 JUMP_INIT(close
, _IO_file_close
),
1505 JUMP_INIT(stat
, _IO_file_stat
),
1506 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1507 JUMP_INIT(imbue
, _IO_default_imbue
)