1 /* Copyright (C) 1993-2015 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 <http://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. */
30 # 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>
49 # include <kernel-features.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)
65 # define _IO_new_do_write _IO_do_write
66 # define _IO_new_file_attach _IO_file_attach
67 # define _IO_new_file_close_it _IO_file_close_it
68 # define _IO_new_file_finish _IO_file_finish
69 # define _IO_new_file_fopen _IO_file_fopen
70 # define _IO_new_file_init _IO_file_init
71 # define _IO_new_file_setbuf _IO_file_setbuf
72 # define _IO_new_file_sync _IO_file_sync
73 # define _IO_new_file_overflow _IO_file_overflow
74 # define _IO_new_file_seekoff _IO_file_seekoff
75 # define _IO_new_file_underflow _IO_file_underflow
76 # define _IO_new_file_write _IO_file_write
77 # define _IO_new_file_xsputn _IO_file_xsputn
82 extern struct __gconv_trans_data __libio_translit attribute_hidden
;
86 /* An fstream can be in at most one of put mode, get mode, or putback mode.
87 Putback mode is a variant of get mode.
89 In a filebuf, there is only one current position, instead of two
90 separate get and put pointers. In get mode, the current position
91 is that of gptr(); in put mode that of pptr().
93 The position in the buffer that corresponds to the position
94 in external file system is normally _IO_read_end, except in putback
95 mode, when it is _IO_save_end and also when the file is in append mode,
96 since switching from read to write mode automatically sends the position in
97 the external file system to the end of file.
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_buf_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 (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
;
152 fp
->file
._fileno
= -1;
154 libc_hidden_ver (_IO_new_file_init
, _IO_file_init
)
157 _IO_new_file_close_it (_IO_FILE
*fp
)
160 if (!_IO_file_is_open (fp
))
163 if ((fp
->_flags
& _IO_NO_WRITES
) == 0
164 && (fp
->_flags
& _IO_CURRENTLY_PUTTING
) != 0)
165 write_status
= _IO_do_flush (fp
);
169 _IO_unsave_markers (fp
);
171 int close_status
= ((fp
->_flags2
& _IO_FLAGS2_NOCLOSE
) == 0
172 ? _IO_SYSCLOSE (fp
) : 0);
175 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
178 if (_IO_have_wbackup (fp
))
179 _IO_free_wbackup_area (fp
);
180 _IO_wsetb (fp
, NULL
, NULL
, 0);
181 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
182 _IO_wsetp (fp
, NULL
, NULL
);
185 _IO_setb (fp
, NULL
, NULL
, 0);
186 _IO_setg (fp
, NULL
, NULL
, NULL
);
187 _IO_setp (fp
, NULL
, NULL
);
189 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
190 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
192 fp
->_offset
= _IO_pos_BAD
;
194 return close_status
? close_status
: write_status
;
196 libc_hidden_ver (_IO_new_file_close_it
, _IO_file_close_it
)
199 _IO_new_file_finish (_IO_FILE
*fp
, int dummy
)
201 if (_IO_file_is_open (fp
))
204 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
207 _IO_default_finish (fp
, 0);
209 libc_hidden_ver (_IO_new_file_finish
, _IO_file_finish
)
212 _IO_file_open (_IO_FILE
*fp
, const char *filename
, int posix_mode
, int prot
,
213 int read_write
, int is32not64
)
217 if (__glibc_unlikely (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
))
218 fdesc
= open_not_cancel (filename
,
219 posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
221 fdesc
= open (filename
, posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
223 fdesc
= open (filename
, posix_mode
, prot
);
228 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
229 /* For append mode, send the file offset to the end of the file. Don't
230 update the offset cache though, since the file handle is not active. */
231 if ((read_write
& (_IO_IS_APPENDING
| _IO_NO_READS
))
232 == (_IO_IS_APPENDING
| _IO_NO_READS
))
234 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
235 if (new_pos
== _IO_pos_BAD
&& errno
!= ESPIPE
)
237 close_not_cancel (fdesc
);
241 _IO_link_in ((struct _IO_FILE_plus
*) fp
);
244 libc_hidden_def (_IO_file_open
)
247 _IO_new_file_fopen (_IO_FILE
*fp
, const char *filename
, const char *mode
,
250 int oflags
= 0, omode
;
257 const char *last_recognized
;
260 if (_IO_file_is_open (fp
))
266 read_write
= _IO_NO_WRITES
;
270 oflags
= O_CREAT
|O_TRUNC
;
271 read_write
= _IO_NO_READS
;
275 oflags
= O_CREAT
|O_APPEND
;
276 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
279 __set_errno (EINVAL
);
283 last_recognized
= mode
;
285 for (i
= 1; i
< 7; ++i
)
293 read_write
&= _IO_IS_APPENDING
;
295 last_recognized
= mode
;
301 last_recognized
= mode
;
306 last_recognized
= mode
;
310 fp
->_flags2
|= _IO_FLAGS2_MMAP
;
313 fp
->_flags2
|= _IO_FLAGS2_NOTCANCEL
;
319 fp
->_flags2
|= _IO_FLAGS2_CLOEXEC
;
328 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
333 #ifndef __ASSUME_O_CLOEXEC
334 if ((fp
->_flags2
& _IO_FLAGS2_CLOEXEC
) != 0 && __have_o_cloexec
<= 0)
336 int fd
= _IO_fileno (fp
);
337 if (__have_o_cloexec
== 0)
339 int flags
= __fcntl (fd
, F_GETFD
);
340 __have_o_cloexec
= (flags
& FD_CLOEXEC
) == 0 ? -1 : 1;
342 if (__have_o_cloexec
< 0)
343 __fcntl (fd
, F_SETFD
, FD_CLOEXEC
);
347 /* Test whether the mode string specifies the conversion. */
348 cs
= strstr (last_recognized
+ 1, ",ccs=");
351 /* Yep. Load the appropriate conversions and set the orientation
353 struct gconv_fcts fcts
;
354 struct _IO_codecvt
*cc
;
355 char *endp
= __strchrnul (cs
+ 5, ',');
356 char *ccs
= malloc (endp
- (cs
+ 5) + 3);
360 int malloc_err
= errno
; /* Whatever malloc failed with. */
361 (void) _IO_file_close_it (fp
);
362 __set_errno (malloc_err
);
366 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
369 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
370 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
372 /* Something went wrong, we cannot load the conversion modules.
373 This means we cannot proceed since the user explicitly asked
375 (void) _IO_file_close_it (fp
);
377 __set_errno (EINVAL
);
383 assert (fcts
.towc_nsteps
== 1);
384 assert (fcts
.tomb_nsteps
== 1);
386 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
387 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
389 /* Clear the state. We start all over again. */
390 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
391 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
393 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
395 /* The functions are always the same. */
396 *cc
= __libio_codecvt
;
398 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
399 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
401 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
402 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
403 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
404 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
406 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
407 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
409 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
410 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
411 cc
->__cd_out
.__cd
.__data
[0].__flags
412 = __GCONV_IS_LAST
| __GCONV_TRANSLIT
;
413 cc
->__cd_out
.__cd
.__data
[0].__statep
=
414 &result
->_wide_data
->_IO_state
;
416 /* From now on use the wide character callback functions. */
417 _IO_JUMPS_FILE_plus (fp
) = fp
->_wide_data
->_wide_vtable
;
419 /* Set the mode now. */
426 libc_hidden_ver (_IO_new_file_fopen
, _IO_file_fopen
)
429 _IO_new_file_attach (_IO_FILE
*fp
, int fd
)
431 if (_IO_file_is_open (fp
))
434 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
435 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
436 /* Get the current position of the file. */
437 /* We have to do that since that may be junk. */
438 fp
->_offset
= _IO_pos_BAD
;
439 int save_errno
= errno
;
440 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
441 == _IO_pos_BAD
&& errno
!= ESPIPE
)
443 __set_errno (save_errno
);
446 libc_hidden_ver (_IO_new_file_attach
, _IO_file_attach
)
449 _IO_new_file_setbuf (_IO_FILE
*fp
, char *p
, _IO_ssize_t len
)
451 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
454 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
456 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
460 libc_hidden_ver (_IO_new_file_setbuf
, _IO_file_setbuf
)
464 _IO_file_setbuf_mmap (_IO_FILE
*fp
, char *p
, _IO_ssize_t len
)
468 /* Change the function table. */
469 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
470 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
472 /* And perform the normal operation. */
473 result
= _IO_new_file_setbuf (fp
, p
, len
);
475 /* If the call failed, restore to using mmap. */
478 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps_mmap
;
479 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
485 static _IO_size_t
new_do_write (_IO_FILE
*, const char *, _IO_size_t
);
487 /* Write TO_DO bytes from DATA to FP.
488 Then mark FP as having empty buffers. */
491 _IO_new_do_write (_IO_FILE
*fp
, const char *data
, _IO_size_t to_do
)
494 || (_IO_size_t
) new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
496 libc_hidden_ver (_IO_new_do_write
, _IO_do_write
)
500 new_do_write (_IO_FILE
*fp
, const char *data
, _IO_size_t to_do
)
503 if (fp
->_flags
& _IO_IS_APPENDING
)
504 /* On a system without a proper O_APPEND implementation,
505 you would need to sys_seek(0, SEEK_END) here, but is
506 not needed nor desirable for Unix- or Posix-like systems.
507 Instead, just indicate that offset (before and after) is
509 fp
->_offset
= _IO_pos_BAD
;
510 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
513 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
514 if (new_pos
== _IO_pos_BAD
)
516 fp
->_offset
= new_pos
;
518 count
= _IO_SYSWRITE (fp
, data
, to_do
);
519 if (fp
->_cur_column
&& count
)
520 fp
->_cur_column
= _IO_adjust_column (fp
->_cur_column
- 1, data
, count
) + 1;
521 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
522 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
523 fp
->_IO_write_end
= (fp
->_mode
<= 0
524 && (fp
->_flags
& (_IO_LINE_BUF
| _IO_UNBUFFERED
))
525 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
530 _IO_new_file_underflow (_IO_FILE
*fp
)
534 /* SysV does not make this test; take it out for compatibility */
535 if (fp
->_flags
& _IO_EOF_SEEN
)
539 if (fp
->_flags
& _IO_NO_READS
)
541 fp
->_flags
|= _IO_ERR_SEEN
;
545 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
546 return *(unsigned char *) fp
->_IO_read_ptr
;
548 if (fp
->_IO_buf_base
== NULL
)
550 /* Maybe we already have a push back pointer. */
551 if (fp
->_IO_save_base
!= NULL
)
553 free (fp
->_IO_save_base
);
554 fp
->_flags
&= ~_IO_IN_BACKUP
;
559 /* Flush all line buffered files before reading. */
560 /* FIXME This can/should be moved to genops ?? */
561 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
564 _IO_flush_all_linebuffered ();
566 /* We used to flush all line-buffered stream. This really isn't
567 required by any standard. My recollection is that
568 traditional Unix systems did this for stdout. stderr better
569 not be line buffered. So we do just that here
570 explicitly. --drepper */
571 _IO_acquire_lock (_IO_stdout
);
573 if ((_IO_stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
574 == (_IO_LINKED
| _IO_LINE_BUF
))
575 _IO_OVERFLOW (_IO_stdout
, EOF
);
577 _IO_release_lock (_IO_stdout
);
581 _IO_switch_to_get_mode (fp
);
583 /* This is very tricky. We have to adjust those
584 pointers before we call _IO_SYSREAD () since
585 we may longjump () out while waiting for
586 input. Those pointers may be screwed up. H.J. */
587 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
588 fp
->_IO_read_end
= fp
->_IO_buf_base
;
589 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
592 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
593 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
597 fp
->_flags
|= _IO_EOF_SEEN
;
599 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
601 fp
->_IO_read_end
+= count
;
604 /* If a stream is read to EOF, the calling application may switch active
605 handles. As a result, our offset cache would no longer be valid, so
607 fp
->_offset
= _IO_pos_BAD
;
610 if (fp
->_offset
!= _IO_pos_BAD
)
611 _IO_pos_adjust (fp
->_offset
, count
);
612 return *(unsigned char *) fp
->_IO_read_ptr
;
614 libc_hidden_ver (_IO_new_file_underflow
, _IO_file_underflow
)
616 /* Guts of underflow callback if we mmap the file. This stats the file and
617 updates the stream state to match. In the normal case we return zero.
618 If the file is no longer eligible for mmap, its jump tables are reset to
619 the vanilla ones and we return nonzero. */
621 mmap_remap_check (_IO_FILE
*fp
)
625 if (_IO_SYSSTAT (fp
, &st
) == 0
626 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
627 /* Limit the file size to 1MB for 32-bit machines. */
628 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024))
630 const size_t pagesize
= __getpagesize ();
631 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
632 if (ROUNDED (st
.st_size
) < ROUNDED (fp
->_IO_buf_end
635 /* We can trim off some pages past the end of the file. */
636 (void) __munmap (fp
->_IO_buf_base
+ ROUNDED (st
.st_size
),
637 ROUNDED (fp
->_IO_buf_end
- fp
->_IO_buf_base
)
638 - ROUNDED (st
.st_size
));
639 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
641 else if (ROUNDED (st
.st_size
) > ROUNDED (fp
->_IO_buf_end
644 /* The file added some pages. We need to remap it. */
646 #ifdef _G_HAVE_MREMAP
647 p
= __mremap (fp
->_IO_buf_base
, ROUNDED (fp
->_IO_buf_end
649 ROUNDED (st
.st_size
), MREMAP_MAYMOVE
);
652 (void) __munmap (fp
->_IO_buf_base
,
653 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
657 (void) __munmap (fp
->_IO_buf_base
,
658 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
659 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
664 fp
->_IO_buf_base
= p
;
665 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
669 /* The number of pages didn't change. */
670 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
674 fp
->_offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
675 _IO_setg (fp
, fp
->_IO_buf_base
,
676 fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
677 ? fp
->_IO_buf_base
+ fp
->_offset
: fp
->_IO_buf_end
,
680 /* If we are already positioned at or past the end of the file, don't
681 change the current offset. If not, seek past what we have mapped,
682 mimicking the position left by a normal underflow reading into its
685 if (fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
687 if (__lseek64 (fp
->_fileno
, fp
->_IO_buf_end
- fp
->_IO_buf_base
,
689 != fp
->_IO_buf_end
- fp
->_IO_buf_base
)
690 fp
->_flags
|= _IO_ERR_SEEN
;
692 fp
->_offset
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
699 /* Life is no longer good for mmap. Punt it. */
700 (void) __munmap (fp
->_IO_buf_base
,
701 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
703 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
704 _IO_setg (fp
, NULL
, NULL
, NULL
);
706 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
708 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps
;
709 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
715 /* Special callback replacing the underflow callbacks if we mmap the file. */
717 _IO_file_underflow_mmap (_IO_FILE
*fp
)
719 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
720 return *(unsigned char *) fp
->_IO_read_ptr
;
722 if (__glibc_unlikely (mmap_remap_check (fp
)))
723 /* We punted to the regular file functions. */
724 return _IO_UNDERFLOW (fp
);
726 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
727 return *(unsigned char *) fp
->_IO_read_ptr
;
729 fp
->_flags
|= _IO_EOF_SEEN
;
734 decide_maybe_mmap (_IO_FILE
*fp
)
736 /* We use the file in read-only mode. This could mean we can
737 mmap the file and use it without any copying. But not all
738 file descriptors are for mmap-able objects and on 32-bit
739 machines we don't want to map files which are too large since
740 this would require too much virtual memory. */
743 if (_IO_SYSSTAT (fp
, &st
) == 0
744 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
745 /* Limit the file size to 1MB for 32-bit machines. */
746 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024)
748 && (fp
->_offset
== _IO_pos_BAD
|| fp
->_offset
<= st
.st_size
))
750 /* Try to map the file. */
753 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
756 /* OK, we managed to map the file. Set the buffer up and use a
757 special jump table with simplified underflow functions which
758 never tries to read anything from the file. */
760 if (__lseek64 (fp
->_fileno
, st
.st_size
, SEEK_SET
) != st
.st_size
)
762 (void) __munmap (p
, st
.st_size
);
763 fp
->_offset
= _IO_pos_BAD
;
767 _IO_setb (fp
, p
, (char *) p
+ st
.st_size
, 0);
769 if (fp
->_offset
== _IO_pos_BAD
)
772 _IO_setg (fp
, p
, p
+ fp
->_offset
, p
+ st
.st_size
);
773 fp
->_offset
= st
.st_size
;
776 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps_mmap
;
778 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps_mmap
;
779 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
786 /* We couldn't use mmap, so revert to the vanilla file operations. */
789 _IO_JUMPS_FILE_plus (fp
) = &_IO_file_jumps
;
791 _IO_JUMPS_FILE_plus (fp
) = &_IO_wfile_jumps
;
792 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
796 _IO_file_underflow_maybe_mmap (_IO_FILE
*fp
)
798 /* This is the first read attempt. Choose mmap or vanilla operations
799 and then punt to the chosen underflow routine. */
800 decide_maybe_mmap (fp
);
801 return _IO_UNDERFLOW (fp
);
806 _IO_new_file_overflow (_IO_FILE
*f
, int ch
)
808 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
810 f
->_flags
|= _IO_ERR_SEEN
;
814 /* If currently reading or no buffer allocated. */
815 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== NULL
)
817 /* Allocate a buffer if needed. */
818 if (f
->_IO_write_base
== NULL
)
821 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
823 /* Otherwise must be currently reading.
824 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
825 logically slide the buffer forwards one block (by setting the
826 read pointers to all point at the beginning of the block). This
827 makes room for subsequent output.
828 Otherwise, set the read pointers to _IO_read_end (leaving that
829 alone, so it can continue to correspond to the external position). */
830 if (__glibc_unlikely (_IO_in_backup (f
)))
832 size_t nbackup
= f
->_IO_read_end
- f
->_IO_read_ptr
;
833 _IO_free_backup_area (f
);
834 f
->_IO_read_base
-= MIN (nbackup
,
835 f
->_IO_read_base
- f
->_IO_buf_base
);
836 f
->_IO_read_ptr
= f
->_IO_read_base
;
839 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
840 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
841 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
842 f
->_IO_write_base
= f
->_IO_write_ptr
;
843 f
->_IO_write_end
= f
->_IO_buf_end
;
844 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
846 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
847 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
| _IO_UNBUFFERED
))
848 f
->_IO_write_end
= f
->_IO_write_ptr
;
851 return _IO_do_write (f
, f
->_IO_write_base
,
852 f
->_IO_write_ptr
- f
->_IO_write_base
);
853 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
854 if (_IO_do_flush (f
) == EOF
)
856 *f
->_IO_write_ptr
++ = ch
;
857 if ((f
->_flags
& _IO_UNBUFFERED
)
858 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
859 if (_IO_do_write (f
, f
->_IO_write_base
,
860 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
862 return (unsigned char) ch
;
864 libc_hidden_ver (_IO_new_file_overflow
, _IO_file_overflow
)
867 _IO_new_file_sync (_IO_FILE
*fp
)
872 /* char* ptr = cur_ptr(); */
873 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
874 if (_IO_do_flush(fp
)) return EOF
;
875 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
879 if (_IO_in_backup (fp
))
880 delta
-= eGptr () - Gbase ();
882 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
883 if (new_pos
!= (_IO_off64_t
) EOF
)
884 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
886 else if (errno
== ESPIPE
)
887 ; /* Ignore error from unseekable devices. */
893 fp
->_offset
= _IO_pos_BAD
;
894 /* FIXME: Cleanup - can this be shared? */
895 /* setg(base(), ptr, ptr); */
898 libc_hidden_ver (_IO_new_file_sync
, _IO_file_sync
)
901 _IO_file_sync_mmap (_IO_FILE
*fp
)
903 if (fp
->_IO_read_ptr
!= fp
->_IO_read_end
)
906 if (_IO_in_backup (fp
))
907 delta
-= eGptr () - Gbase ();
909 if (__lseek64 (fp
->_fileno
, fp
->_IO_read_ptr
- fp
->_IO_buf_base
,
911 != fp
->_IO_read_ptr
- fp
->_IO_buf_base
)
913 fp
->_flags
|= _IO_ERR_SEEN
;
917 fp
->_offset
= fp
->_IO_read_ptr
- fp
->_IO_buf_base
;
918 fp
->_IO_read_end
= fp
->_IO_read_ptr
= fp
->_IO_read_base
;
922 /* ftell{,o} implementation. The only time we modify the state of the stream
923 is when we have unflushed writes. In that case we seek to the end and
924 record that offset in the stream object. */
926 do_ftell (_IO_FILE
*fp
)
928 _IO_off64_t result
, offset
= 0;
930 /* No point looking at unflushed data if we haven't allocated buffers
932 if (fp
->_IO_buf_base
!= NULL
)
934 bool unflushed_writes
= fp
->_IO_write_ptr
> fp
->_IO_write_base
;
936 bool append_mode
= (fp
->_flags
& _IO_IS_APPENDING
) == _IO_IS_APPENDING
;
938 /* When we have unflushed writes in append mode, seek to the end of the
939 file and record that offset. This is the only time we change the file
940 stream state and it is safe since the file handle is active. */
941 if (unflushed_writes
&& append_mode
)
943 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
944 if (result
== _IO_pos_BAD
)
947 fp
->_offset
= result
;
950 /* Adjust for unflushed data. */
951 if (!unflushed_writes
)
952 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
953 /* We don't trust _IO_read_end to represent the current file offset when
954 writing in append mode because the value would have to be shifted to
955 the end of the file during a flush. Use the write base instead, along
956 with the new offset we got above when we did a seek to the end of the
958 else if (append_mode
)
959 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
960 /* For all other modes, _IO_read_end represents the file offset. */
962 offset
+= fp
->_IO_write_ptr
- fp
->_IO_read_end
;
965 if (fp
->_offset
!= _IO_pos_BAD
)
966 result
= fp
->_offset
;
968 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_cur
);
977 __set_errno (EINVAL
);
985 _IO_new_file_seekoff (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
, int mode
)
988 _IO_off64_t delta
, new_offset
;
991 /* Short-circuit into a separate function. We don't want to mix any
992 functionality and we don't want to touch anything inside the FILE
995 return do_ftell (fp
);
997 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
998 offset of the underlying file must be exact. */
999 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
1000 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
1002 bool was_writing
= (fp
->_IO_write_ptr
> fp
->_IO_write_base
1003 || _IO_in_put_mode (fp
));
1005 /* Flush unwritten characters.
1006 (This may do an unneeded write if we seek within the buffer.
1007 But to be able to switch to reading, we would need to set
1008 egptr to pptr. That can't be done in the current design,
1009 which assumes file_ptr() is eGptr. Anyway, since we probably
1010 end up flushing when we close(), it doesn't make much difference.)
1011 FIXME: simulate mem-mapped files. */
1012 if (was_writing
&& _IO_switch_to_get_mode (fp
))
1015 if (fp
->_IO_buf_base
== NULL
)
1017 /* It could be that we already have a pushback buffer. */
1018 if (fp
->_IO_read_base
!= NULL
)
1020 free (fp
->_IO_read_base
);
1021 fp
->_flags
&= ~_IO_IN_BACKUP
;
1023 _IO_doallocbuf (fp
);
1024 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1025 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1031 /* Adjust for read-ahead (bytes is buffer). */
1032 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1034 if (fp
->_offset
== _IO_pos_BAD
)
1036 /* Make offset absolute, assuming current pointer is file_ptr(). */
1037 offset
+= fp
->_offset
;
1040 __set_errno (EINVAL
);
1051 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
1053 offset
+= st
.st_size
;
1060 /* At this point, dir==_IO_seek_set. */
1062 /* If destination is within current buffer, optimize: */
1063 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
1064 && !_IO_in_backup (fp
))
1066 _IO_off64_t start_offset
= (fp
->_offset
1067 - (fp
->_IO_read_end
- fp
->_IO_buf_base
));
1068 if (offset
>= start_offset
&& offset
< fp
->_offset
)
1070 _IO_setg (fp
, fp
->_IO_buf_base
,
1071 fp
->_IO_buf_base
+ (offset
- start_offset
),
1073 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1075 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1080 if (fp
->_flags
& _IO_NO_READS
)
1083 /* Try to seek to a block boundary, to improve kernel page management. */
1084 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
1085 delta
= offset
- new_offset
;
1086 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1088 new_offset
= offset
;
1091 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
1098 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
1100 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
1103 /* We weren't allowed to read, but try to seek the remainder. */
1104 offset
= count
== EOF
? delta
: delta
-count
;
1109 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
1110 fp
->_IO_buf_base
+ count
);
1111 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1112 fp
->_offset
= result
+ count
;
1113 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1117 _IO_unsave_markers (fp
);
1118 result
= _IO_SYSSEEK (fp
, offset
, dir
);
1121 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1122 fp
->_offset
= result
;
1123 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1124 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1129 /* We need to do it since it is possible that the file offset in
1130 the kernel may be changed behind our back. It may happen when
1131 we fopen a file and then do a fork. One process may access the
1132 file and the kernel file offset will be changed. */
1133 if (fp
->_offset
>= 0)
1134 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
1138 libc_hidden_ver (_IO_new_file_seekoff
, _IO_file_seekoff
)
1141 _IO_file_seekoff_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
, int mode
)
1145 /* If we are only interested in the current position, calculate it and
1146 return right now. This calculation does the right thing when we are
1147 using a pushback buffer, but in the usual case has the same value as
1148 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1150 return fp
->_offset
- (fp
->_IO_read_end
- fp
->_IO_read_ptr
);
1155 /* Adjust for read-ahead (bytes is buffer). */
1156 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1161 offset
+= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1164 /* At this point, dir==_IO_seek_set. */
1168 /* No negative offsets are valid. */
1169 __set_errno (EINVAL
);
1173 result
= _IO_SYSSEEK (fp
, offset
, 0);
1177 if (offset
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1178 /* One can fseek arbitrarily past the end of the file
1179 and it is meaningless until one attempts to read.
1180 Leave the buffer pointers in EOF state until underflow. */
1181 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_end
, fp
->_IO_buf_end
);
1183 /* Adjust the read pointers to match the file position,
1184 but so the next read attempt will call underflow. */
1185 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ offset
,
1186 fp
->_IO_buf_base
+ offset
);
1188 fp
->_offset
= result
;
1190 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1196 _IO_file_seekoff_maybe_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
,
1199 /* We only get here when we haven't tried to read anything yet.
1200 So there is nothing more useful for us to do here than just
1201 the underlying lseek call. */
1203 _IO_off64_t result
= _IO_SYSSEEK (fp
, offset
, dir
);
1207 fp
->_offset
= result
;
1212 _IO_file_read (_IO_FILE
*fp
, void *buf
, _IO_ssize_t size
)
1214 return (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0)
1215 ? read_not_cancel (fp
->_fileno
, buf
, size
)
1216 : read (fp
->_fileno
, buf
, size
));
1218 libc_hidden_def (_IO_file_read
)
1221 _IO_file_seek (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
)
1223 return __lseek64 (fp
->_fileno
, offset
, dir
);
1225 libc_hidden_def (_IO_file_seek
)
1228 _IO_file_stat (_IO_FILE
*fp
, void *st
)
1230 return __fxstat64 (_STAT_VER
, fp
->_fileno
, (struct stat64
*) st
);
1232 libc_hidden_def (_IO_file_stat
)
1235 _IO_file_close_mmap (_IO_FILE
*fp
)
1237 /* In addition to closing the file descriptor we have to unmap the file. */
1238 (void) __munmap (fp
->_IO_buf_base
, fp
->_IO_buf_end
- fp
->_IO_buf_base
);
1239 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
1240 /* Cancelling close should be avoided if possible since it leaves an
1241 unrecoverable state behind. */
1242 return close_not_cancel (fp
->_fileno
);
1246 _IO_file_close (_IO_FILE
*fp
)
1248 /* Cancelling close should be avoided if possible since it leaves an
1249 unrecoverable state behind. */
1250 return close_not_cancel (fp
->_fileno
);
1252 libc_hidden_def (_IO_file_close
)
1255 _IO_new_file_write (_IO_FILE
*f
, const void *data
, _IO_ssize_t n
)
1257 _IO_ssize_t to_do
= n
;
1260 _IO_ssize_t count
= (__builtin_expect (f
->_flags2
1261 & _IO_FLAGS2_NOTCANCEL
, 0)
1262 ? write_not_cancel (f
->_fileno
, data
, to_do
)
1263 : write (f
->_fileno
, data
, to_do
));
1266 f
->_flags
|= _IO_ERR_SEEN
;
1270 data
= (void *) ((char *) data
+ count
);
1273 if (f
->_offset
>= 0)
1279 _IO_new_file_xsputn (_IO_FILE
*f
, const void *data
, _IO_size_t n
)
1281 const char *s
= (const char *) data
;
1282 _IO_size_t to_do
= n
;
1284 _IO_size_t count
= 0;
1288 /* This is an optimized implementation.
1289 If the amount to be written straddles a block boundary
1290 (or the filebuf is unbuffered), use sys_write directly. */
1292 /* First figure out how much space is available in the buffer. */
1293 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
1295 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
1299 for (p
= s
+ n
; p
> s
; )
1310 else if (f
->_IO_write_end
> f
->_IO_write_ptr
)
1311 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
1313 /* Then fill the buffer. */
1319 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
1321 memcpy (f
->_IO_write_ptr
, s
, count
);
1322 f
->_IO_write_ptr
+= count
;
1327 if (to_do
+ must_flush
> 0)
1329 _IO_size_t block_size
, do_write
;
1330 /* Next flush the (full) buffer. */
1331 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
1332 /* If nothing else has to be written we must not signal the
1333 caller that everything has been written. */
1334 return to_do
== 0 ? EOF
: n
- to_do
;
1336 /* Try to maintain alignment: write a whole number of blocks. */
1337 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
1338 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
1342 count
= new_do_write (f
, s
, do_write
);
1344 if (count
< do_write
)
1348 /* Now write out the remainder. Normally, this will fit in the
1349 buffer, but it's somewhat messier for line-buffered files,
1350 so we let _IO_default_xsputn handle the general case. */
1352 to_do
-= _IO_default_xsputn (f
, s
+do_write
, to_do
);
1356 libc_hidden_ver (_IO_new_file_xsputn
, _IO_file_xsputn
)
1359 _IO_file_xsgetn (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1361 _IO_size_t want
, have
;
1367 if (fp
->_IO_buf_base
== NULL
)
1369 /* Maybe we already have a push back pointer. */
1370 if (fp
->_IO_save_base
!= NULL
)
1372 free (fp
->_IO_save_base
);
1373 fp
->_flags
&= ~_IO_IN_BACKUP
;
1375 _IO_doallocbuf (fp
);
1380 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1383 memcpy (s
, fp
->_IO_read_ptr
, want
);
1384 fp
->_IO_read_ptr
+= want
;
1392 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1394 memcpy (s
, fp
->_IO_read_ptr
, have
);
1398 fp
->_IO_read_ptr
+= have
;
1401 /* Check for backup and repeat */
1402 if (_IO_in_backup (fp
))
1404 _IO_switch_to_main_get_area (fp
);
1408 /* If we now want less than a buffer, underflow and repeat
1409 the copy. Otherwise, _IO_SYSREAD directly to
1411 if (fp
->_IO_buf_base
1412 && want
< (size_t) (fp
->_IO_buf_end
- fp
->_IO_buf_base
))
1414 if (__underflow (fp
) == EOF
)
1420 /* These must be set before the sysread as we might longjmp out
1421 waiting for input. */
1422 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1423 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1425 /* Try to maintain alignment: read a whole number of blocks. */
1427 if (fp
->_IO_buf_base
)
1429 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1430 if (block_size
>= 128)
1431 count
-= want
% block_size
;
1434 count
= _IO_SYSREAD (fp
, s
, count
);
1438 fp
->_flags
|= _IO_EOF_SEEN
;
1440 fp
->_flags
|= _IO_ERR_SEEN
;
1447 if (fp
->_offset
!= _IO_pos_BAD
)
1448 _IO_pos_adjust (fp
->_offset
, count
);
1454 libc_hidden_def (_IO_file_xsgetn
)
1457 _IO_file_xsgetn_mmap (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1460 char *read_ptr
= fp
->_IO_read_ptr
;
1461 char *s
= (char *) data
;
1463 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1467 if (__glibc_unlikely (_IO_in_backup (fp
)))
1470 s
= __mempcpy (s
, read_ptr
, have
);
1472 memcpy (s
, read_ptr
, have
);
1476 _IO_switch_to_main_get_area (fp
);
1477 read_ptr
= fp
->_IO_read_ptr
;
1478 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1483 /* Check that we are mapping all of the file, in case it grew. */
1484 if (__glibc_unlikely (mmap_remap_check (fp
)))
1485 /* We punted mmap, so complete with the vanilla code. */
1486 return s
- (char *) data
+ _IO_XSGETN (fp
, data
, n
);
1488 read_ptr
= fp
->_IO_read_ptr
;
1489 have
= fp
->_IO_read_end
- read_ptr
;
1494 fp
->_flags
|= _IO_EOF_SEEN
;
1498 have
= MIN (have
, n
);
1500 s
= __mempcpy (s
, read_ptr
, have
);
1502 memcpy (s
, read_ptr
, have
);
1505 fp
->_IO_read_ptr
= read_ptr
+ have
;
1508 return s
- (char *) data
;
1512 _IO_file_xsgetn_maybe_mmap (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1514 /* We only get here if this is the first attempt to read something.
1515 Decide which operations to use and then punt to the chosen one. */
1517 decide_maybe_mmap (fp
);
1518 return _IO_XSGETN (fp
, data
, n
);
1522 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1523 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1524 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1525 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1526 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1527 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1528 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1529 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1530 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1531 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1532 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1533 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1534 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);
1537 const struct _IO_jump_t _IO_file_jumps
=
1540 JUMP_INIT(finish
, _IO_file_finish
),
1541 JUMP_INIT(overflow
, _IO_file_overflow
),
1542 JUMP_INIT(underflow
, _IO_file_underflow
),
1543 JUMP_INIT(uflow
, _IO_default_uflow
),
1544 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1545 JUMP_INIT(xsputn
, _IO_file_xsputn
),
1546 JUMP_INIT(xsgetn
, _IO_file_xsgetn
),
1547 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1548 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1549 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1550 JUMP_INIT(sync
, _IO_new_file_sync
),
1551 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1552 JUMP_INIT(read
, _IO_file_read
),
1553 JUMP_INIT(write
, _IO_new_file_write
),
1554 JUMP_INIT(seek
, _IO_file_seek
),
1555 JUMP_INIT(close
, _IO_file_close
),
1556 JUMP_INIT(stat
, _IO_file_stat
),
1557 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1558 JUMP_INIT(imbue
, _IO_default_imbue
)
1560 libc_hidden_data_def (_IO_file_jumps
)
1562 const struct _IO_jump_t _IO_file_jumps_mmap
=
1565 JUMP_INIT(finish
, _IO_file_finish
),
1566 JUMP_INIT(overflow
, _IO_file_overflow
),
1567 JUMP_INIT(underflow
, _IO_file_underflow_mmap
),
1568 JUMP_INIT(uflow
, _IO_default_uflow
),
1569 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1570 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1571 JUMP_INIT(xsgetn
, _IO_file_xsgetn_mmap
),
1572 JUMP_INIT(seekoff
, _IO_file_seekoff_mmap
),
1573 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1574 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1575 JUMP_INIT(sync
, _IO_file_sync_mmap
),
1576 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1577 JUMP_INIT(read
, _IO_file_read
),
1578 JUMP_INIT(write
, _IO_new_file_write
),
1579 JUMP_INIT(seek
, _IO_file_seek
),
1580 JUMP_INIT(close
, _IO_file_close_mmap
),
1581 JUMP_INIT(stat
, _IO_file_stat
),
1582 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1583 JUMP_INIT(imbue
, _IO_default_imbue
)
1586 const struct _IO_jump_t _IO_file_jumps_maybe_mmap
=
1589 JUMP_INIT(finish
, _IO_file_finish
),
1590 JUMP_INIT(overflow
, _IO_file_overflow
),
1591 JUMP_INIT(underflow
, _IO_file_underflow_maybe_mmap
),
1592 JUMP_INIT(uflow
, _IO_default_uflow
),
1593 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1594 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1595 JUMP_INIT(xsgetn
, _IO_file_xsgetn_maybe_mmap
),
1596 JUMP_INIT(seekoff
, _IO_file_seekoff_maybe_mmap
),
1597 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1598 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1599 JUMP_INIT(sync
, _IO_new_file_sync
),
1600 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1601 JUMP_INIT(read
, _IO_file_read
),
1602 JUMP_INIT(write
, _IO_new_file_write
),
1603 JUMP_INIT(seek
, _IO_file_seek
),
1604 JUMP_INIT(close
, _IO_file_close
),
1605 JUMP_INIT(stat
, _IO_file_stat
),
1606 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1607 JUMP_INIT(imbue
, _IO_default_imbue
)