1 /* Copyright (C) 1993-2014 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
35 #include <sys/param.h>
36 #include <sys/types.h>
43 # include "../wcsmbs/wcsmbsload.h"
44 # include "../iconv/gconv_charset.h"
45 # include "../iconv/gconv_int.h"
46 # include <shlib-compat.h>
47 # include <not-cancel.h>
48 # include <kernel-features.h>
54 # define __set_errno(Val) errno = (Val)
59 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
60 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
61 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
62 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
64 # define _IO_new_do_write _IO_do_write
65 # define _IO_new_file_attach _IO_file_attach
66 # define _IO_new_file_close_it _IO_file_close_it
67 # define _IO_new_file_finish _IO_file_finish
68 # define _IO_new_file_fopen _IO_file_fopen
69 # define _IO_new_file_init _IO_file_init
70 # define _IO_new_file_setbuf _IO_file_setbuf
71 # define _IO_new_file_sync _IO_file_sync
72 # define _IO_new_file_overflow _IO_file_overflow
73 # define _IO_new_file_seekoff _IO_file_seekoff
74 # define _IO_new_file_underflow _IO_file_underflow
75 # define _IO_new_file_write _IO_file_write
76 # define _IO_new_file_xsputn _IO_file_xsputn
81 extern struct __gconv_trans_data __libio_translit attribute_hidden
;
85 /* An fstream can be in at most one of put mode, get mode, or putback mode.
86 Putback mode is a variant of get mode.
88 In a filebuf, there is only one current position, instead of two
89 separate get and put pointers. In get mode, the current position
90 is that of gptr(); in put mode that of pptr().
92 The position in the buffer that corresponds to the position
93 in external file system is normally _IO_read_end, except in putback
94 mode, when it is _IO_save_end and also when the file is in append mode,
95 since switching from read to write mode automatically sends the position in
96 the external file system to the end of file.
97 If the field _fb._offset is >= 0, it gives the offset in
98 the file as a whole corresponding to eGptr(). (?)
101 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
102 and _IO_read_base are equal to each other. These are usually equal
103 to _IO_buf_base, though not necessarily if we have switched from
104 get mode to put mode. (The reason is to maintain the invariant
105 that _IO_read_end corresponds to the external file position.)
106 _IO_write_base is non-NULL and usually equal to _IO_buf_base.
107 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
108 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
111 If a filebuf is in get or putback mode, eback() != egptr().
112 In get mode, the unread characters are between gptr() and egptr().
113 The OS file position corresponds to that of egptr().
116 Putback mode is used to remember "excess" characters that have
117 been sputbackc'd in a separate putback buffer.
118 In putback mode, the get buffer points to the special putback buffer.
119 The unread characters are the characters between gptr() and egptr()
120 in the putback buffer, as well as the area between save_gptr()
121 and save_egptr(), which point into the original reserve buffer.
122 (The pointers save_gptr() and save_egptr() are the values
123 of gptr() and egptr() at the time putback mode was entered.)
124 The OS position corresponds to that of save_egptr().
126 LINE BUFFERED OUTPUT:
127 During line buffered output, _IO_write_base==base() && epptr()==base().
128 However, ptr() may be anywhere between base() and ebuf().
129 This forces a call to filebuf::overflow(int C) on every put.
130 If there is more space in the buffer, and C is not a '\n',
131 then C is inserted, and pptr() incremented.
134 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
137 #define CLOSED_FILEBUF_FLAGS \
138 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
142 _IO_new_file_init (struct _IO_FILE_plus
*fp
)
144 /* POSIX.1 allows another file handle to be used to change the position
145 of our file descriptor. Hence we actually don't know the actual
146 position before we do the first fseek (and until a following fflush). */
147 fp
->file
._offset
= _IO_pos_BAD
;
148 fp
->file
._IO_file_flags
|= CLOSED_FILEBUF_FLAGS
;
151 fp
->file
._fileno
= -1;
153 libc_hidden_ver (_IO_new_file_init
, _IO_file_init
)
156 _IO_new_file_close_it (_IO_FILE
*fp
)
159 if (!_IO_file_is_open (fp
))
162 if ((fp
->_flags
& _IO_NO_WRITES
) == 0
163 && (fp
->_flags
& _IO_CURRENTLY_PUTTING
) != 0)
164 write_status
= _IO_do_flush (fp
);
168 _IO_unsave_markers (fp
);
170 int close_status
= ((fp
->_flags2
& _IO_FLAGS2_NOCLOSE
) == 0
171 ? _IO_SYSCLOSE (fp
) : 0);
174 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
177 if (_IO_have_wbackup (fp
))
178 _IO_free_wbackup_area (fp
);
179 _IO_wsetb (fp
, NULL
, NULL
, 0);
180 _IO_wsetg (fp
, NULL
, NULL
, NULL
);
181 _IO_wsetp (fp
, NULL
, NULL
);
184 _IO_setb (fp
, NULL
, NULL
, 0);
185 _IO_setg (fp
, NULL
, NULL
, NULL
);
186 _IO_setp (fp
, NULL
, NULL
);
188 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
189 fp
->_flags
= _IO_MAGIC
|CLOSED_FILEBUF_FLAGS
;
191 fp
->_offset
= _IO_pos_BAD
;
193 return close_status
? close_status
: write_status
;
195 libc_hidden_ver (_IO_new_file_close_it
, _IO_file_close_it
)
198 _IO_new_file_finish (_IO_FILE
*fp
, int dummy
)
200 if (_IO_file_is_open (fp
))
203 if (!(fp
->_flags
& _IO_DELETE_DONT_CLOSE
))
206 _IO_default_finish (fp
, 0);
208 libc_hidden_ver (_IO_new_file_finish
, _IO_file_finish
)
211 _IO_file_open (_IO_FILE
*fp
, const char *filename
, int posix_mode
, int prot
,
212 int read_write
, int is32not64
)
216 if (__glibc_unlikely (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
))
217 fdesc
= open_not_cancel (filename
,
218 posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
220 fdesc
= open (filename
, posix_mode
| (is32not64
? 0 : O_LARGEFILE
), prot
);
222 fdesc
= open (filename
, posix_mode
, prot
);
227 _IO_mask_flags (fp
, read_write
,_IO_NO_READS
+_IO_NO_WRITES
+_IO_IS_APPENDING
);
228 /* For append mode, send the file offset to the end of the file. Don't
229 update the offset cache though, since the file handle is not active. */
230 if ((read_write
& (_IO_IS_APPENDING
| _IO_NO_READS
))
231 == (_IO_IS_APPENDING
| _IO_NO_READS
))
233 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
234 if (new_pos
== _IO_pos_BAD
&& errno
!= ESPIPE
)
236 close_not_cancel (fdesc
);
240 _IO_link_in ((struct _IO_FILE_plus
*) fp
);
243 libc_hidden_def (_IO_file_open
)
246 _IO_new_file_fopen (_IO_FILE
*fp
, const char *filename
, const char *mode
,
249 int oflags
= 0, omode
;
256 const char *last_recognized
;
259 if (_IO_file_is_open (fp
))
265 read_write
= _IO_NO_WRITES
;
269 oflags
= O_CREAT
|O_TRUNC
;
270 read_write
= _IO_NO_READS
;
274 oflags
= O_CREAT
|O_APPEND
;
275 read_write
= _IO_NO_READS
|_IO_IS_APPENDING
;
278 __set_errno (EINVAL
);
282 last_recognized
= mode
;
284 for (i
= 1; i
< 7; ++i
)
292 read_write
&= _IO_IS_APPENDING
;
294 last_recognized
= mode
;
300 last_recognized
= mode
;
305 last_recognized
= mode
;
309 fp
->_flags2
|= _IO_FLAGS2_MMAP
;
312 fp
->_flags2
|= _IO_FLAGS2_NOTCANCEL
;
318 fp
->_flags2
|= _IO_FLAGS2_CLOEXEC
;
327 result
= _IO_file_open (fp
, filename
, omode
|oflags
, oprot
, read_write
,
332 #ifndef __ASSUME_O_CLOEXEC
333 if ((fp
->_flags2
& _IO_FLAGS2_CLOEXEC
) != 0 && __have_o_cloexec
<= 0)
335 int fd
= _IO_fileno (fp
);
336 if (__have_o_cloexec
== 0)
338 int flags
= __fcntl (fd
, F_GETFD
);
339 __have_o_cloexec
= (flags
& FD_CLOEXEC
) == 0 ? -1 : 1;
341 if (__have_o_cloexec
< 0)
342 __fcntl (fd
, F_SETFD
, FD_CLOEXEC
);
346 /* Test whether the mode string specifies the conversion. */
347 cs
= strstr (last_recognized
+ 1, ",ccs=");
350 /* Yep. Load the appropriate conversions and set the orientation
352 struct gconv_fcts fcts
;
353 struct _IO_codecvt
*cc
;
354 char *endp
= __strchrnul (cs
+ 5, ',');
355 char ccs
[endp
- (cs
+ 5) + 3];
357 *((char *) __mempcpy (ccs
, cs
+ 5, endp
- (cs
+ 5))) = '\0';
360 if (__wcsmbs_named_conv (&fcts
, ccs
[2] == '\0'
361 ? upstr (ccs
, cs
+ 5) : ccs
) != 0)
363 /* Something went wrong, we cannot load the conversion modules.
364 This means we cannot proceed since the user explicitly asked
366 (void) _IO_file_close_it (fp
);
367 __set_errno (EINVAL
);
371 assert (fcts
.towc_nsteps
== 1);
372 assert (fcts
.tomb_nsteps
== 1);
374 fp
->_wide_data
->_IO_read_ptr
= fp
->_wide_data
->_IO_read_end
;
375 fp
->_wide_data
->_IO_write_ptr
= fp
->_wide_data
->_IO_write_base
;
377 /* Clear the state. We start all over again. */
378 memset (&fp
->_wide_data
->_IO_state
, '\0', sizeof (__mbstate_t
));
379 memset (&fp
->_wide_data
->_IO_last_state
, '\0', sizeof (__mbstate_t
));
381 cc
= fp
->_codecvt
= &fp
->_wide_data
->_codecvt
;
383 /* The functions are always the same. */
384 *cc
= __libio_codecvt
;
386 cc
->__cd_in
.__cd
.__nsteps
= fcts
.towc_nsteps
;
387 cc
->__cd_in
.__cd
.__steps
= fcts
.towc
;
389 cc
->__cd_in
.__cd
.__data
[0].__invocation_counter
= 0;
390 cc
->__cd_in
.__cd
.__data
[0].__internal_use
= 1;
391 cc
->__cd_in
.__cd
.__data
[0].__flags
= __GCONV_IS_LAST
;
392 cc
->__cd_in
.__cd
.__data
[0].__statep
= &result
->_wide_data
->_IO_state
;
394 cc
->__cd_out
.__cd
.__nsteps
= fcts
.tomb_nsteps
;
395 cc
->__cd_out
.__cd
.__steps
= fcts
.tomb
;
397 cc
->__cd_out
.__cd
.__data
[0].__invocation_counter
= 0;
398 cc
->__cd_out
.__cd
.__data
[0].__internal_use
= 1;
399 cc
->__cd_out
.__cd
.__data
[0].__flags
400 = __GCONV_IS_LAST
| __GCONV_TRANSLIT
;
401 cc
->__cd_out
.__cd
.__data
[0].__statep
=
402 &result
->_wide_data
->_IO_state
;
404 /* From now on use the wide character callback functions. */
405 ((struct _IO_FILE_plus
*) fp
)->vtable
= fp
->_wide_data
->_wide_vtable
;
407 /* Set the mode now. */
414 libc_hidden_ver (_IO_new_file_fopen
, _IO_file_fopen
)
417 _IO_new_file_attach (_IO_FILE
*fp
, int fd
)
419 if (_IO_file_is_open (fp
))
422 fp
->_flags
&= ~(_IO_NO_READS
+_IO_NO_WRITES
);
423 fp
->_flags
|= _IO_DELETE_DONT_CLOSE
;
424 /* Get the current position of the file. */
425 /* We have to do that since that may be junk. */
426 fp
->_offset
= _IO_pos_BAD
;
427 int save_errno
= errno
;
428 if (_IO_SEEKOFF (fp
, (_IO_off64_t
)0, _IO_seek_cur
, _IOS_INPUT
|_IOS_OUTPUT
)
429 == _IO_pos_BAD
&& errno
!= ESPIPE
)
431 __set_errno (save_errno
);
434 libc_hidden_ver (_IO_new_file_attach
, _IO_file_attach
)
437 _IO_new_file_setbuf (_IO_FILE
*fp
, char *p
, _IO_ssize_t len
)
439 if (_IO_default_setbuf (fp
, p
, len
) == NULL
)
442 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
444 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
448 libc_hidden_ver (_IO_new_file_setbuf
, _IO_file_setbuf
)
452 _IO_file_setbuf_mmap (_IO_FILE
*fp
, char *p
, _IO_ssize_t len
)
456 /* Change the function table. */
457 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
458 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
460 /* And perform the normal operation. */
461 result
= _IO_new_file_setbuf (fp
, p
, len
);
463 /* If the call failed, restore to using mmap. */
466 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps_mmap
;
467 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
473 static _IO_size_t
new_do_write (_IO_FILE
*, const char *, _IO_size_t
);
475 /* Write TO_DO bytes from DATA to FP.
476 Then mark FP as having empty buffers. */
479 _IO_new_do_write (_IO_FILE
*fp
, const char *data
, _IO_size_t to_do
)
482 || (_IO_size_t
) new_do_write (fp
, data
, to_do
) == to_do
) ? 0 : EOF
;
484 libc_hidden_ver (_IO_new_do_write
, _IO_do_write
)
488 new_do_write (_IO_FILE
*fp
, const char *data
, _IO_size_t to_do
)
491 if (fp
->_flags
& _IO_IS_APPENDING
)
492 /* On a system without a proper O_APPEND implementation,
493 you would need to sys_seek(0, SEEK_END) here, but is
494 not needed nor desirable for Unix- or Posix-like systems.
495 Instead, just indicate that offset (before and after) is
497 fp
->_offset
= _IO_pos_BAD
;
498 else if (fp
->_IO_read_end
!= fp
->_IO_write_base
)
501 = _IO_SYSSEEK (fp
, fp
->_IO_write_base
- fp
->_IO_read_end
, 1);
502 if (new_pos
== _IO_pos_BAD
)
504 fp
->_offset
= new_pos
;
506 count
= _IO_SYSWRITE (fp
, data
, to_do
);
507 if (fp
->_cur_column
&& count
)
508 fp
->_cur_column
= _IO_adjust_column (fp
->_cur_column
- 1, data
, count
) + 1;
509 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
510 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_buf_base
;
511 fp
->_IO_write_end
= (fp
->_mode
<= 0
512 && (fp
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
513 ? fp
->_IO_buf_base
: fp
->_IO_buf_end
);
518 _IO_new_file_underflow (_IO_FILE
*fp
)
522 /* SysV does not make this test; take it out for compatibility */
523 if (fp
->_flags
& _IO_EOF_SEEN
)
527 if (fp
->_flags
& _IO_NO_READS
)
529 fp
->_flags
|= _IO_ERR_SEEN
;
533 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
534 return *(unsigned char *) fp
->_IO_read_ptr
;
536 if (fp
->_IO_buf_base
== NULL
)
538 /* Maybe we already have a push back pointer. */
539 if (fp
->_IO_save_base
!= NULL
)
541 free (fp
->_IO_save_base
);
542 fp
->_flags
&= ~_IO_IN_BACKUP
;
547 /* Flush all line buffered files before reading. */
548 /* FIXME This can/should be moved to genops ?? */
549 if (fp
->_flags
& (_IO_LINE_BUF
|_IO_UNBUFFERED
))
552 _IO_flush_all_linebuffered ();
554 /* We used to flush all line-buffered stream. This really isn't
555 required by any standard. My recollection is that
556 traditional Unix systems did this for stdout. stderr better
557 not be line buffered. So we do just that here
558 explicitly. --drepper */
559 _IO_acquire_lock (_IO_stdout
);
561 if ((_IO_stdout
->_flags
& (_IO_LINKED
| _IO_NO_WRITES
| _IO_LINE_BUF
))
562 == (_IO_LINKED
| _IO_LINE_BUF
))
563 _IO_OVERFLOW (_IO_stdout
, EOF
);
565 _IO_release_lock (_IO_stdout
);
569 _IO_switch_to_get_mode (fp
);
571 /* This is very tricky. We have to adjust those
572 pointers before we call _IO_SYSREAD () since
573 we may longjump () out while waiting for
574 input. Those pointers may be screwed up. H.J. */
575 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_buf_base
;
576 fp
->_IO_read_end
= fp
->_IO_buf_base
;
577 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
580 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
581 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
585 fp
->_flags
|= _IO_EOF_SEEN
;
587 fp
->_flags
|= _IO_ERR_SEEN
, count
= 0;
589 fp
->_IO_read_end
+= count
;
592 /* If a stream is read to EOF, the calling application may switch active
593 handles. As a result, our offset cache would no longer be valid, so
595 fp
->_offset
= _IO_pos_BAD
;
598 if (fp
->_offset
!= _IO_pos_BAD
)
599 _IO_pos_adjust (fp
->_offset
, count
);
600 return *(unsigned char *) fp
->_IO_read_ptr
;
602 libc_hidden_ver (_IO_new_file_underflow
, _IO_file_underflow
)
604 /* Guts of underflow callback if we mmap the file. This stats the file and
605 updates the stream state to match. In the normal case we return zero.
606 If the file is no longer eligible for mmap, its jump tables are reset to
607 the vanilla ones and we return nonzero. */
609 mmap_remap_check (_IO_FILE
*fp
)
613 if (_IO_SYSSTAT (fp
, &st
) == 0
614 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
615 /* Limit the file size to 1MB for 32-bit machines. */
616 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024))
618 const size_t pagesize
= __getpagesize ();
619 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
620 if (ROUNDED (st
.st_size
) < ROUNDED (fp
->_IO_buf_end
623 /* We can trim off some pages past the end of the file. */
624 (void) __munmap (fp
->_IO_buf_base
+ ROUNDED (st
.st_size
),
625 ROUNDED (fp
->_IO_buf_end
- fp
->_IO_buf_base
)
626 - ROUNDED (st
.st_size
));
627 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
629 else if (ROUNDED (st
.st_size
) > ROUNDED (fp
->_IO_buf_end
632 /* The file added some pages. We need to remap it. */
634 #ifdef _G_HAVE_MREMAP
635 p
= __mremap (fp
->_IO_buf_base
, ROUNDED (fp
->_IO_buf_end
637 ROUNDED (st
.st_size
), MREMAP_MAYMOVE
);
640 (void) __munmap (fp
->_IO_buf_base
,
641 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
645 (void) __munmap (fp
->_IO_buf_base
,
646 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
647 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
,
652 fp
->_IO_buf_base
= p
;
653 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
657 /* The number of pages didn't change. */
658 fp
->_IO_buf_end
= fp
->_IO_buf_base
+ st
.st_size
;
662 fp
->_offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
663 _IO_setg (fp
, fp
->_IO_buf_base
,
664 fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
665 ? fp
->_IO_buf_base
+ fp
->_offset
: fp
->_IO_buf_end
,
668 /* If we are already positioned at or past the end of the file, don't
669 change the current offset. If not, seek past what we have mapped,
670 mimicking the position left by a normal underflow reading into its
673 if (fp
->_offset
< fp
->_IO_buf_end
- fp
->_IO_buf_base
)
675 if (__lseek64 (fp
->_fileno
, fp
->_IO_buf_end
- fp
->_IO_buf_base
,
677 != fp
->_IO_buf_end
- fp
->_IO_buf_base
)
678 fp
->_flags
|= _IO_ERR_SEEN
;
680 fp
->_offset
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
687 /* Life is no longer good for mmap. Punt it. */
688 (void) __munmap (fp
->_IO_buf_base
,
689 fp
->_IO_buf_end
- fp
->_IO_buf_base
);
691 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
692 _IO_setg (fp
, NULL
, NULL
, NULL
);
694 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
696 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
697 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
703 /* Special callback replacing the underflow callbacks if we mmap the file. */
705 _IO_file_underflow_mmap (_IO_FILE
*fp
)
707 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
708 return *(unsigned char *) fp
->_IO_read_ptr
;
710 if (__glibc_unlikely (mmap_remap_check (fp
)))
711 /* We punted to the regular file functions. */
712 return _IO_UNDERFLOW (fp
);
714 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
715 return *(unsigned char *) fp
->_IO_read_ptr
;
717 fp
->_flags
|= _IO_EOF_SEEN
;
722 decide_maybe_mmap (_IO_FILE
*fp
)
724 /* We use the file in read-only mode. This could mean we can
725 mmap the file and use it without any copying. But not all
726 file descriptors are for mmap-able objects and on 32-bit
727 machines we don't want to map files which are too large since
728 this would require too much virtual memory. */
731 if (_IO_SYSSTAT (fp
, &st
) == 0
732 && S_ISREG (st
.st_mode
) && st
.st_size
!= 0
733 /* Limit the file size to 1MB for 32-bit machines. */
734 && (sizeof (ptrdiff_t) > 4 || st
.st_size
< 1*1024*1024)
736 && (fp
->_offset
== _IO_pos_BAD
|| fp
->_offset
<= st
.st_size
))
738 /* Try to map the file. */
741 p
= __mmap64 (NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fp
->_fileno
, 0);
744 /* OK, we managed to map the file. Set the buffer up and use a
745 special jump table with simplified underflow functions which
746 never tries to read anything from the file. */
748 if (__lseek64 (fp
->_fileno
, st
.st_size
, SEEK_SET
) != st
.st_size
)
750 (void) __munmap (p
, st
.st_size
);
751 fp
->_offset
= _IO_pos_BAD
;
755 _IO_setb (fp
, p
, (char *) p
+ st
.st_size
, 0);
757 if (fp
->_offset
== _IO_pos_BAD
)
760 _IO_setg (fp
, p
, p
+ fp
->_offset
, p
+ st
.st_size
);
761 fp
->_offset
= st
.st_size
;
764 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_file_jumps_mmap
;
766 _IO_JUMPS ((struct _IO_FILE_plus
*)fp
) = &_IO_wfile_jumps_mmap
;
767 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps_mmap
;
774 /* We couldn't use mmap, so revert to the vanilla file operations. */
777 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_file_jumps
;
779 _IO_JUMPS ((struct _IO_FILE_plus
*) fp
) = &_IO_wfile_jumps
;
780 fp
->_wide_data
->_wide_vtable
= &_IO_wfile_jumps
;
784 _IO_file_underflow_maybe_mmap (_IO_FILE
*fp
)
786 /* This is the first read attempt. Choose mmap or vanilla operations
787 and then punt to the chosen underflow routine. */
788 decide_maybe_mmap (fp
);
789 return _IO_UNDERFLOW (fp
);
794 _IO_new_file_overflow (_IO_FILE
*f
, int ch
)
796 if (f
->_flags
& _IO_NO_WRITES
) /* SET ERROR */
798 f
->_flags
|= _IO_ERR_SEEN
;
802 /* If currently reading or no buffer allocated. */
803 if ((f
->_flags
& _IO_CURRENTLY_PUTTING
) == 0 || f
->_IO_write_base
== NULL
)
805 /* Allocate a buffer if needed. */
806 if (f
->_IO_write_base
== NULL
)
809 _IO_setg (f
, f
->_IO_buf_base
, f
->_IO_buf_base
, f
->_IO_buf_base
);
811 /* Otherwise must be currently reading.
812 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
813 logically slide the buffer forwards one block (by setting the
814 read pointers to all point at the beginning of the block). This
815 makes room for subsequent output.
816 Otherwise, set the read pointers to _IO_read_end (leaving that
817 alone, so it can continue to correspond to the external position). */
818 if (__glibc_unlikely (_IO_in_backup (f
)))
820 size_t nbackup
= f
->_IO_read_end
- f
->_IO_read_ptr
;
821 _IO_free_backup_area (f
);
822 f
->_IO_read_base
-= MIN (nbackup
,
823 f
->_IO_read_base
- f
->_IO_buf_base
);
824 f
->_IO_read_ptr
= f
->_IO_read_base
;
827 if (f
->_IO_read_ptr
== f
->_IO_buf_end
)
828 f
->_IO_read_end
= f
->_IO_read_ptr
= f
->_IO_buf_base
;
829 f
->_IO_write_ptr
= f
->_IO_read_ptr
;
830 f
->_IO_write_base
= f
->_IO_write_ptr
;
831 f
->_IO_write_end
= f
->_IO_buf_end
;
832 f
->_IO_read_base
= f
->_IO_read_ptr
= f
->_IO_read_end
;
834 f
->_flags
|= _IO_CURRENTLY_PUTTING
;
835 if (f
->_mode
<= 0 && f
->_flags
& (_IO_LINE_BUF
+_IO_UNBUFFERED
))
836 f
->_IO_write_end
= f
->_IO_write_ptr
;
839 return _IO_do_write (f
, f
->_IO_write_base
,
840 f
->_IO_write_ptr
- f
->_IO_write_base
);
841 if (f
->_IO_write_ptr
== f
->_IO_buf_end
) /* Buffer is really full */
842 if (_IO_do_flush (f
) == EOF
)
844 *f
->_IO_write_ptr
++ = ch
;
845 if ((f
->_flags
& _IO_UNBUFFERED
)
846 || ((f
->_flags
& _IO_LINE_BUF
) && ch
== '\n'))
847 if (_IO_do_write (f
, f
->_IO_write_base
,
848 f
->_IO_write_ptr
- f
->_IO_write_base
) == EOF
)
850 return (unsigned char) ch
;
852 libc_hidden_ver (_IO_new_file_overflow
, _IO_file_overflow
)
855 _IO_new_file_sync (_IO_FILE
*fp
)
860 /* char* ptr = cur_ptr(); */
861 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
862 if (_IO_do_flush(fp
)) return EOF
;
863 delta
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
867 if (_IO_in_backup (fp
))
868 delta
-= eGptr () - Gbase ();
870 _IO_off64_t new_pos
= _IO_SYSSEEK (fp
, delta
, 1);
871 if (new_pos
!= (_IO_off64_t
) EOF
)
872 fp
->_IO_read_end
= fp
->_IO_read_ptr
;
874 else if (errno
== ESPIPE
)
875 ; /* Ignore error from unseekable devices. */
881 fp
->_offset
= _IO_pos_BAD
;
882 /* FIXME: Cleanup - can this be shared? */
883 /* setg(base(), ptr, ptr); */
886 libc_hidden_ver (_IO_new_file_sync
, _IO_file_sync
)
889 _IO_file_sync_mmap (_IO_FILE
*fp
)
891 if (fp
->_IO_read_ptr
!= fp
->_IO_read_end
)
894 if (_IO_in_backup (fp
))
895 delta
-= eGptr () - Gbase ();
897 if (__lseek64 (fp
->_fileno
, fp
->_IO_read_ptr
- fp
->_IO_buf_base
,
899 != fp
->_IO_read_ptr
- fp
->_IO_buf_base
)
901 fp
->_flags
|= _IO_ERR_SEEN
;
905 fp
->_offset
= fp
->_IO_read_ptr
- fp
->_IO_buf_base
;
906 fp
->_IO_read_end
= fp
->_IO_read_ptr
= fp
->_IO_read_base
;
910 /* ftell{,o} implementation. The only time we modify the state of the stream
911 is when we have unflushed writes. In that case we seek to the end and
912 record that offset in the stream object. */
914 do_ftell (_IO_FILE
*fp
)
916 _IO_off64_t result
, offset
= 0;
918 /* No point looking at unflushed data if we haven't allocated buffers
920 if (fp
->_IO_buf_base
!= NULL
)
922 bool unflushed_writes
= fp
->_IO_write_ptr
> fp
->_IO_write_base
;
924 bool append_mode
= (fp
->_flags
& _IO_IS_APPENDING
) == _IO_IS_APPENDING
;
926 /* When we have unflushed writes in append mode, seek to the end of the
927 file and record that offset. This is the only time we change the file
928 stream state and it is safe since the file handle is active. */
929 if (unflushed_writes
&& append_mode
)
931 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_end
);
932 if (result
== _IO_pos_BAD
)
935 fp
->_offset
= result
;
938 /* Adjust for unflushed data. */
939 if (!unflushed_writes
)
940 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
941 /* We don't trust _IO_read_end to represent the current file offset when
942 writing in append mode because the value would have to be shifted to
943 the end of the file during a flush. Use the write base instead, along
944 with the new offset we got above when we did a seek to the end of the
946 else if (append_mode
)
947 offset
+= fp
->_IO_write_ptr
- fp
->_IO_write_base
;
948 /* For all other modes, _IO_read_end represents the file offset. */
950 offset
+= fp
->_IO_write_ptr
- fp
->_IO_read_end
;
953 if (fp
->_offset
!= _IO_pos_BAD
)
954 result
= fp
->_offset
;
956 result
= _IO_SYSSEEK (fp
, 0, _IO_seek_cur
);
965 __set_errno (EINVAL
);
973 _IO_new_file_seekoff (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
, int mode
)
976 _IO_off64_t delta
, new_offset
;
979 /* Short-circuit into a separate function. We don't want to mix any
980 functionality and we don't want to touch anything inside the FILE
983 return do_ftell (fp
);
985 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
986 offset of the underlying file must be exact. */
987 int must_be_exact
= (fp
->_IO_read_base
== fp
->_IO_read_end
988 && fp
->_IO_write_base
== fp
->_IO_write_ptr
);
990 bool was_writing
= (fp
->_IO_write_ptr
> fp
->_IO_write_base
991 || _IO_in_put_mode (fp
));
993 /* Flush unwritten characters.
994 (This may do an unneeded write if we seek within the buffer.
995 But to be able to switch to reading, we would need to set
996 egptr to pptr. That can't be done in the current design,
997 which assumes file_ptr() is eGptr. Anyway, since we probably
998 end up flushing when we close(), it doesn't make much difference.)
999 FIXME: simulate mem-mapped files. */
1000 if (was_writing
&& _IO_switch_to_get_mode (fp
))
1003 if (fp
->_IO_buf_base
== NULL
)
1005 /* It could be that we already have a pushback buffer. */
1006 if (fp
->_IO_read_base
!= NULL
)
1008 free (fp
->_IO_read_base
);
1009 fp
->_flags
&= ~_IO_IN_BACKUP
;
1011 _IO_doallocbuf (fp
);
1012 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1013 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1019 /* Adjust for read-ahead (bytes is buffer). */
1020 offset
-= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1022 if (fp
->_offset
== _IO_pos_BAD
)
1024 /* Make offset absolute, assuming current pointer is file_ptr(). */
1025 offset
+= fp
->_offset
;
1028 __set_errno (EINVAL
);
1039 if (_IO_SYSSTAT (fp
, &st
) == 0 && S_ISREG (st
.st_mode
))
1041 offset
+= st
.st_size
;
1048 /* At this point, dir==_IO_seek_set. */
1050 /* If destination is within current buffer, optimize: */
1051 if (fp
->_offset
!= _IO_pos_BAD
&& fp
->_IO_read_base
!= NULL
1052 && !_IO_in_backup (fp
))
1054 _IO_off64_t start_offset
= (fp
->_offset
1055 - (fp
->_IO_read_end
- fp
->_IO_buf_base
));
1056 if (offset
>= start_offset
&& offset
< fp
->_offset
)
1058 _IO_setg (fp
, fp
->_IO_buf_base
,
1059 fp
->_IO_buf_base
+ (offset
- start_offset
),
1061 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1063 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1068 if (fp
->_flags
& _IO_NO_READS
)
1071 /* Try to seek to a block boundary, to improve kernel page management. */
1072 new_offset
= offset
& ~(fp
->_IO_buf_end
- fp
->_IO_buf_base
- 1);
1073 delta
= offset
- new_offset
;
1074 if (delta
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1076 new_offset
= offset
;
1079 result
= _IO_SYSSEEK (fp
, new_offset
, 0);
1086 count
= _IO_SYSREAD (fp
, fp
->_IO_buf_base
,
1088 ? delta
: fp
->_IO_buf_end
- fp
->_IO_buf_base
));
1091 /* We weren't allowed to read, but try to seek the remainder. */
1092 offset
= count
== EOF
? delta
: delta
-count
;
1097 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ delta
,
1098 fp
->_IO_buf_base
+ count
);
1099 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1100 fp
->_offset
= result
+ count
;
1101 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1105 _IO_unsave_markers (fp
);
1106 result
= _IO_SYSSEEK (fp
, offset
, dir
);
1109 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1110 fp
->_offset
= result
;
1111 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1112 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1117 /* We need to do it since it is possible that the file offset in
1118 the kernel may be changed behind our back. It may happen when
1119 we fopen a file and then do a fork. One process may access the
1120 file and the kernel file offset will be changed. */
1121 if (fp
->_offset
>= 0)
1122 _IO_SYSSEEK (fp
, fp
->_offset
, 0);
1126 libc_hidden_ver (_IO_new_file_seekoff
, _IO_file_seekoff
)
1129 _IO_file_seekoff_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
, int mode
)
1133 /* If we are only interested in the current position, calculate it and
1134 return right now. This calculation does the right thing when we are
1135 using a pushback buffer, but in the usual case has the same value as
1136 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1138 return fp
->_offset
- (fp
->_IO_read_end
- fp
->_IO_read_ptr
);
1143 /* Adjust for read-ahead (bytes is buffer). */
1144 offset
+= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1149 offset
+= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1152 /* At this point, dir==_IO_seek_set. */
1156 /* No negative offsets are valid. */
1157 __set_errno (EINVAL
);
1161 result
= _IO_SYSSEEK (fp
, offset
, 0);
1165 if (offset
> fp
->_IO_buf_end
- fp
->_IO_buf_base
)
1166 /* One can fseek arbitrarily past the end of the file
1167 and it is meaningless until one attempts to read.
1168 Leave the buffer pointers in EOF state until underflow. */
1169 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_end
, fp
->_IO_buf_end
);
1171 /* Adjust the read pointers to match the file position,
1172 but so the next read attempt will call underflow. */
1173 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
+ offset
,
1174 fp
->_IO_buf_base
+ offset
);
1176 fp
->_offset
= result
;
1178 _IO_mask_flags (fp
, 0, _IO_EOF_SEEN
);
1184 _IO_file_seekoff_maybe_mmap (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
,
1187 /* We only get here when we haven't tried to read anything yet.
1188 So there is nothing more useful for us to do here than just
1189 the underlying lseek call. */
1191 _IO_off64_t result
= _IO_SYSSEEK (fp
, offset
, dir
);
1195 fp
->_offset
= result
;
1200 _IO_file_read (_IO_FILE
*fp
, void *buf
, _IO_ssize_t size
)
1202 return (__builtin_expect (fp
->_flags2
& _IO_FLAGS2_NOTCANCEL
, 0)
1203 ? read_not_cancel (fp
->_fileno
, buf
, size
)
1204 : read (fp
->_fileno
, buf
, size
));
1206 libc_hidden_def (_IO_file_read
)
1209 _IO_file_seek (_IO_FILE
*fp
, _IO_off64_t offset
, int dir
)
1211 return __lseek64 (fp
->_fileno
, offset
, dir
);
1213 libc_hidden_def (_IO_file_seek
)
1216 _IO_file_stat (_IO_FILE
*fp
, void *st
)
1218 return __fxstat64 (_STAT_VER
, fp
->_fileno
, (struct stat64
*) st
);
1220 libc_hidden_def (_IO_file_stat
)
1223 _IO_file_close_mmap (_IO_FILE
*fp
)
1225 /* In addition to closing the file descriptor we have to unmap the file. */
1226 (void) __munmap (fp
->_IO_buf_base
, fp
->_IO_buf_end
- fp
->_IO_buf_base
);
1227 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
1228 /* Cancelling close should be avoided if possible since it leaves an
1229 unrecoverable state behind. */
1230 return close_not_cancel (fp
->_fileno
);
1234 _IO_file_close (_IO_FILE
*fp
)
1236 /* Cancelling close should be avoided if possible since it leaves an
1237 unrecoverable state behind. */
1238 return close_not_cancel (fp
->_fileno
);
1240 libc_hidden_def (_IO_file_close
)
1243 _IO_new_file_write (_IO_FILE
*f
, const void *data
, _IO_ssize_t n
)
1245 _IO_ssize_t to_do
= n
;
1248 _IO_ssize_t count
= (__builtin_expect (f
->_flags2
1249 & _IO_FLAGS2_NOTCANCEL
, 0)
1250 ? write_not_cancel (f
->_fileno
, data
, to_do
)
1251 : write (f
->_fileno
, data
, to_do
));
1254 f
->_flags
|= _IO_ERR_SEEN
;
1258 data
= (void *) ((char *) data
+ count
);
1261 if (f
->_offset
>= 0)
1267 _IO_new_file_xsputn (_IO_FILE
*f
, const void *data
, _IO_size_t n
)
1269 const char *s
= (const char *) data
;
1270 _IO_size_t to_do
= n
;
1272 _IO_size_t count
= 0;
1276 /* This is an optimized implementation.
1277 If the amount to be written straddles a block boundary
1278 (or the filebuf is unbuffered), use sys_write directly. */
1280 /* First figure out how much space is available in the buffer. */
1281 if ((f
->_flags
& _IO_LINE_BUF
) && (f
->_flags
& _IO_CURRENTLY_PUTTING
))
1283 count
= f
->_IO_buf_end
- f
->_IO_write_ptr
;
1287 for (p
= s
+ n
; p
> s
; )
1298 else if (f
->_IO_write_end
> f
->_IO_write_ptr
)
1299 count
= f
->_IO_write_end
- f
->_IO_write_ptr
; /* Space available. */
1301 /* Then fill the buffer. */
1307 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
1309 memcpy (f
->_IO_write_ptr
, s
, count
);
1310 f
->_IO_write_ptr
+= count
;
1315 if (to_do
+ must_flush
> 0)
1317 _IO_size_t block_size
, do_write
;
1318 /* Next flush the (full) buffer. */
1319 if (_IO_OVERFLOW (f
, EOF
) == EOF
)
1320 /* If nothing else has to be written we must not signal the
1321 caller that everything has been written. */
1322 return to_do
== 0 ? EOF
: n
- to_do
;
1324 /* Try to maintain alignment: write a whole number of blocks. */
1325 block_size
= f
->_IO_buf_end
- f
->_IO_buf_base
;
1326 do_write
= to_do
- (block_size
>= 128 ? to_do
% block_size
: 0);
1330 count
= new_do_write (f
, s
, do_write
);
1332 if (count
< do_write
)
1336 /* Now write out the remainder. Normally, this will fit in the
1337 buffer, but it's somewhat messier for line-buffered files,
1338 so we let _IO_default_xsputn handle the general case. */
1340 to_do
-= _IO_default_xsputn (f
, s
+do_write
, to_do
);
1344 libc_hidden_ver (_IO_new_file_xsputn
, _IO_file_xsputn
)
1347 _IO_file_xsgetn (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1349 _IO_size_t want
, have
;
1355 if (fp
->_IO_buf_base
== NULL
)
1357 /* Maybe we already have a push back pointer. */
1358 if (fp
->_IO_save_base
!= NULL
)
1360 free (fp
->_IO_save_base
);
1361 fp
->_flags
&= ~_IO_IN_BACKUP
;
1363 _IO_doallocbuf (fp
);
1368 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1371 memcpy (s
, fp
->_IO_read_ptr
, want
);
1372 fp
->_IO_read_ptr
+= want
;
1380 s
= __mempcpy (s
, fp
->_IO_read_ptr
, have
);
1382 memcpy (s
, fp
->_IO_read_ptr
, have
);
1386 fp
->_IO_read_ptr
+= have
;
1389 /* Check for backup and repeat */
1390 if (_IO_in_backup (fp
))
1392 _IO_switch_to_main_get_area (fp
);
1396 /* If we now want less than a buffer, underflow and repeat
1397 the copy. Otherwise, _IO_SYSREAD directly to
1399 if (fp
->_IO_buf_base
1400 && want
< (size_t) (fp
->_IO_buf_end
- fp
->_IO_buf_base
))
1402 if (__underflow (fp
) == EOF
)
1408 /* These must be set before the sysread as we might longjmp out
1409 waiting for input. */
1410 _IO_setg (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1411 _IO_setp (fp
, fp
->_IO_buf_base
, fp
->_IO_buf_base
);
1413 /* Try to maintain alignment: read a whole number of blocks. */
1415 if (fp
->_IO_buf_base
)
1417 _IO_size_t block_size
= fp
->_IO_buf_end
- fp
->_IO_buf_base
;
1418 if (block_size
>= 128)
1419 count
-= want
% block_size
;
1422 count
= _IO_SYSREAD (fp
, s
, count
);
1426 fp
->_flags
|= _IO_EOF_SEEN
;
1428 fp
->_flags
|= _IO_ERR_SEEN
;
1435 if (fp
->_offset
!= _IO_pos_BAD
)
1436 _IO_pos_adjust (fp
->_offset
, count
);
1442 libc_hidden_def (_IO_file_xsgetn
)
1445 _IO_file_xsgetn_mmap (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1448 char *read_ptr
= fp
->_IO_read_ptr
;
1449 char *s
= (char *) data
;
1451 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1455 if (__glibc_unlikely (_IO_in_backup (fp
)))
1458 s
= __mempcpy (s
, read_ptr
, have
);
1460 memcpy (s
, read_ptr
, have
);
1464 _IO_switch_to_main_get_area (fp
);
1465 read_ptr
= fp
->_IO_read_ptr
;
1466 have
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
1471 /* Check that we are mapping all of the file, in case it grew. */
1472 if (__glibc_unlikely (mmap_remap_check (fp
)))
1473 /* We punted mmap, so complete with the vanilla code. */
1474 return s
- (char *) data
+ _IO_XSGETN (fp
, data
, n
);
1476 read_ptr
= fp
->_IO_read_ptr
;
1477 have
= fp
->_IO_read_end
- read_ptr
;
1482 fp
->_flags
|= _IO_EOF_SEEN
;
1486 have
= MIN (have
, n
);
1488 s
= __mempcpy (s
, read_ptr
, have
);
1490 memcpy (s
, read_ptr
, have
);
1493 fp
->_IO_read_ptr
= read_ptr
+ have
;
1496 return s
- (char *) data
;
1500 _IO_file_xsgetn_maybe_mmap (_IO_FILE
*fp
, void *data
, _IO_size_t n
)
1502 /* We only get here if this is the first attempt to read something.
1503 Decide which operations to use and then punt to the chosen one. */
1505 decide_maybe_mmap (fp
);
1506 return _IO_XSGETN (fp
, data
, n
);
1510 versioned_symbol (libc
, _IO_new_do_write
, _IO_do_write
, GLIBC_2_1
);
1511 versioned_symbol (libc
, _IO_new_file_attach
, _IO_file_attach
, GLIBC_2_1
);
1512 versioned_symbol (libc
, _IO_new_file_close_it
, _IO_file_close_it
, GLIBC_2_1
);
1513 versioned_symbol (libc
, _IO_new_file_finish
, _IO_file_finish
, GLIBC_2_1
);
1514 versioned_symbol (libc
, _IO_new_file_fopen
, _IO_file_fopen
, GLIBC_2_1
);
1515 versioned_symbol (libc
, _IO_new_file_init
, _IO_file_init
, GLIBC_2_1
);
1516 versioned_symbol (libc
, _IO_new_file_setbuf
, _IO_file_setbuf
, GLIBC_2_1
);
1517 versioned_symbol (libc
, _IO_new_file_sync
, _IO_file_sync
, GLIBC_2_1
);
1518 versioned_symbol (libc
, _IO_new_file_overflow
, _IO_file_overflow
, GLIBC_2_1
);
1519 versioned_symbol (libc
, _IO_new_file_seekoff
, _IO_file_seekoff
, GLIBC_2_1
);
1520 versioned_symbol (libc
, _IO_new_file_underflow
, _IO_file_underflow
, GLIBC_2_1
);
1521 versioned_symbol (libc
, _IO_new_file_write
, _IO_file_write
, GLIBC_2_1
);
1522 versioned_symbol (libc
, _IO_new_file_xsputn
, _IO_file_xsputn
, GLIBC_2_1
);
1525 const struct _IO_jump_t _IO_file_jumps
=
1528 JUMP_INIT(finish
, _IO_file_finish
),
1529 JUMP_INIT(overflow
, _IO_file_overflow
),
1530 JUMP_INIT(underflow
, _IO_file_underflow
),
1531 JUMP_INIT(uflow
, _IO_default_uflow
),
1532 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1533 JUMP_INIT(xsputn
, _IO_file_xsputn
),
1534 JUMP_INIT(xsgetn
, _IO_file_xsgetn
),
1535 JUMP_INIT(seekoff
, _IO_new_file_seekoff
),
1536 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1537 JUMP_INIT(setbuf
, _IO_new_file_setbuf
),
1538 JUMP_INIT(sync
, _IO_new_file_sync
),
1539 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1540 JUMP_INIT(read
, _IO_file_read
),
1541 JUMP_INIT(write
, _IO_new_file_write
),
1542 JUMP_INIT(seek
, _IO_file_seek
),
1543 JUMP_INIT(close
, _IO_file_close
),
1544 JUMP_INIT(stat
, _IO_file_stat
),
1545 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1546 JUMP_INIT(imbue
, _IO_default_imbue
)
1548 libc_hidden_data_def (_IO_file_jumps
)
1550 const struct _IO_jump_t _IO_file_jumps_mmap
=
1553 JUMP_INIT(finish
, _IO_file_finish
),
1554 JUMP_INIT(overflow
, _IO_file_overflow
),
1555 JUMP_INIT(underflow
, _IO_file_underflow_mmap
),
1556 JUMP_INIT(uflow
, _IO_default_uflow
),
1557 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1558 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1559 JUMP_INIT(xsgetn
, _IO_file_xsgetn_mmap
),
1560 JUMP_INIT(seekoff
, _IO_file_seekoff_mmap
),
1561 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1562 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1563 JUMP_INIT(sync
, _IO_file_sync_mmap
),
1564 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1565 JUMP_INIT(read
, _IO_file_read
),
1566 JUMP_INIT(write
, _IO_new_file_write
),
1567 JUMP_INIT(seek
, _IO_file_seek
),
1568 JUMP_INIT(close
, _IO_file_close_mmap
),
1569 JUMP_INIT(stat
, _IO_file_stat
),
1570 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1571 JUMP_INIT(imbue
, _IO_default_imbue
)
1574 const struct _IO_jump_t _IO_file_jumps_maybe_mmap
=
1577 JUMP_INIT(finish
, _IO_file_finish
),
1578 JUMP_INIT(overflow
, _IO_file_overflow
),
1579 JUMP_INIT(underflow
, _IO_file_underflow_maybe_mmap
),
1580 JUMP_INIT(uflow
, _IO_default_uflow
),
1581 JUMP_INIT(pbackfail
, _IO_default_pbackfail
),
1582 JUMP_INIT(xsputn
, _IO_new_file_xsputn
),
1583 JUMP_INIT(xsgetn
, _IO_file_xsgetn_maybe_mmap
),
1584 JUMP_INIT(seekoff
, _IO_file_seekoff_maybe_mmap
),
1585 JUMP_INIT(seekpos
, _IO_default_seekpos
),
1586 JUMP_INIT(setbuf
, (_IO_setbuf_t
) _IO_file_setbuf_mmap
),
1587 JUMP_INIT(sync
, _IO_new_file_sync
),
1588 JUMP_INIT(doallocate
, _IO_file_doallocate
),
1589 JUMP_INIT(read
, _IO_file_read
),
1590 JUMP_INIT(write
, _IO_new_file_write
),
1591 JUMP_INIT(seek
, _IO_file_seek
),
1592 JUMP_INIT(close
, _IO_file_close
),
1593 JUMP_INIT(stat
, _IO_file_stat
),
1594 JUMP_INIT(showmanyc
, _IO_default_showmanyc
),
1595 JUMP_INIT(imbue
, _IO_default_imbue
)