S390: Ifunc resolver macro for vector instructions.
[glibc.git] / libio / fileops.c
blobcbcd6f535380c36b79f0045e23537c1fa02af6fe
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. */
29 #ifndef _POSIX_SOURCE
30 # define _POSIX_SOURCE
31 #endif
32 #include "libioP.h"
33 #include <assert.h>
34 #include <fcntl.h>
35 #include <sys/mman.h>
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <string.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #include <stdlib.h>
43 #if _LIBC
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>
50 #endif
51 #ifndef errno
52 extern int errno;
53 #endif
54 #ifndef __set_errno
55 # define __set_errno(Val) errno = (Val)
56 #endif
59 #ifdef _LIBC
60 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
61 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
62 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
63 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
64 #else
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
78 #endif
81 #ifdef _LIBC
82 extern struct __gconv_trans_data __libio_translit attribute_hidden;
83 #endif
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(). (?)
101 PUT MODE:
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.
111 GET MODE:
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().
116 PUTBACK MODE:
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.
134 UNBUFFERED STREAMS:
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)
142 void
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;
151 _IO_link_in (fp);
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)
159 int write_status;
160 if (!_IO_file_is_open (fp))
161 return EOF;
163 if ((fp->_flags & _IO_NO_WRITES) == 0
164 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
165 write_status = _IO_do_flush (fp);
166 else
167 write_status = 0;
169 _IO_unsave_markers (fp);
171 int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
172 ? _IO_SYSCLOSE (fp) : 0);
174 /* Free buffer. */
175 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
176 if (fp->_mode > 0)
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);
184 #endif
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;
191 fp->_fileno = -1;
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)
198 void
199 _IO_new_file_finish (_IO_FILE *fp, int dummy)
201 if (_IO_file_is_open (fp))
203 _IO_do_flush (fp);
204 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
205 _IO_SYSCLOSE (fp);
207 _IO_default_finish (fp, 0);
209 libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
211 _IO_FILE *
212 _IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot,
213 int read_write, int is32not64)
215 int fdesc;
216 #ifdef _LIBC
217 if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
218 fdesc = open_not_cancel (filename,
219 posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
220 else
221 fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
222 #else
223 fdesc = open (filename, posix_mode, prot);
224 #endif
225 if (fdesc < 0)
226 return NULL;
227 fp->_fileno = fdesc;
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);
238 return NULL;
241 _IO_link_in ((struct _IO_FILE_plus *) fp);
242 return fp;
244 libc_hidden_def (_IO_file_open)
246 _IO_FILE *
247 _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
248 int is32not64)
250 int oflags = 0, omode;
251 int read_write;
252 int oprot = 0666;
253 int i;
254 _IO_FILE *result;
255 #ifdef _LIBC
256 const char *cs;
257 const char *last_recognized;
258 #endif
260 if (_IO_file_is_open (fp))
261 return 0;
262 switch (*mode)
264 case 'r':
265 omode = O_RDONLY;
266 read_write = _IO_NO_WRITES;
267 break;
268 case 'w':
269 omode = O_WRONLY;
270 oflags = O_CREAT|O_TRUNC;
271 read_write = _IO_NO_READS;
272 break;
273 case 'a':
274 omode = O_WRONLY;
275 oflags = O_CREAT|O_APPEND;
276 read_write = _IO_NO_READS|_IO_IS_APPENDING;
277 break;
278 default:
279 __set_errno (EINVAL);
280 return NULL;
282 #ifdef _LIBC
283 last_recognized = mode;
284 #endif
285 for (i = 1; i < 7; ++i)
287 switch (*++mode)
289 case '\0':
290 break;
291 case '+':
292 omode = O_RDWR;
293 read_write &= _IO_IS_APPENDING;
294 #ifdef _LIBC
295 last_recognized = mode;
296 #endif
297 continue;
298 case 'x':
299 oflags |= O_EXCL;
300 #ifdef _LIBC
301 last_recognized = mode;
302 #endif
303 continue;
304 case 'b':
305 #ifdef _LIBC
306 last_recognized = mode;
307 #endif
308 continue;
309 case 'm':
310 fp->_flags2 |= _IO_FLAGS2_MMAP;
311 continue;
312 case 'c':
313 fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
314 continue;
315 case 'e':
316 #ifdef O_CLOEXEC
317 oflags |= O_CLOEXEC;
318 #endif
319 fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
320 continue;
321 default:
322 /* Ignore. */
323 continue;
325 break;
328 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
329 is32not64);
331 if (result != NULL)
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);
345 #endif
347 /* Test whether the mode string specifies the conversion. */
348 cs = strstr (last_recognized + 1, ",ccs=");
349 if (cs != NULL)
351 /* Yep. Load the appropriate conversions and set the orientation
352 to wide. */
353 struct gconv_fcts fcts;
354 struct _IO_codecvt *cc;
355 char *endp = __strchrnul (cs + 5, ',');
356 char *ccs = malloc (endp - (cs + 5) + 3);
358 if (ccs == NULL)
360 int malloc_err = errno; /* Whatever malloc failed with. */
361 (void) _IO_file_close_it (fp);
362 __set_errno (malloc_err);
363 return NULL;
366 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
367 strip (ccs, ccs);
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
374 for these. */
375 (void) _IO_file_close_it (fp);
376 free (ccs);
377 __set_errno (EINVAL);
378 return NULL;
381 free (ccs);
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. */
420 result->_mode = 1;
424 return result;
426 libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
428 _IO_FILE *
429 _IO_new_file_attach (_IO_FILE *fp, int fd)
431 if (_IO_file_is_open (fp))
432 return NULL;
433 fp->_fileno = fd;
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)
442 return NULL;
443 __set_errno (save_errno);
444 return fp;
446 libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
448 _IO_FILE *
449 _IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
451 if (_IO_default_setbuf (fp, p, len) == NULL)
452 return NULL;
454 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
455 = fp->_IO_buf_base;
456 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
458 return fp;
460 libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
463 _IO_FILE *
464 _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
466 _IO_FILE *result;
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. */
476 if (result == NULL)
478 _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
479 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
482 return result;
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)
493 return (to_do == 0
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)
498 static
499 _IO_size_t
500 new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
502 _IO_size_t count;
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
508 unpredictable. */
509 fp->_offset = _IO_pos_BAD;
510 else if (fp->_IO_read_end != fp->_IO_write_base)
512 _IO_off64_t new_pos
513 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
514 if (new_pos == _IO_pos_BAD)
515 return 0;
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);
526 return count;
530 _IO_new_file_underflow (_IO_FILE *fp)
532 _IO_ssize_t count;
533 #if 0
534 /* SysV does not make this test; take it out for compatibility */
535 if (fp->_flags & _IO_EOF_SEEN)
536 return (EOF);
537 #endif
539 if (fp->_flags & _IO_NO_READS)
541 fp->_flags |= _IO_ERR_SEEN;
542 __set_errno (EBADF);
543 return EOF;
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;
556 _IO_doallocbuf (fp);
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))
563 #if 0
564 _IO_flush_all_linebuffered ();
565 #else
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);
578 #endif
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
590 = fp->_IO_buf_base;
592 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
593 fp->_IO_buf_end - fp->_IO_buf_base);
594 if (count <= 0)
596 if (count == 0)
597 fp->_flags |= _IO_EOF_SEEN;
598 else
599 fp->_flags |= _IO_ERR_SEEN, count = 0;
601 fp->_IO_read_end += count;
602 if (count == 0)
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
606 unset it. */
607 fp->_offset = _IO_pos_BAD;
608 return EOF;
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. */
620 static int
621 mmap_remap_check (_IO_FILE *fp)
623 struct stat64 st;
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
633 - fp->_IO_buf_base))
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
642 - fp->_IO_buf_base))
644 /* The file added some pages. We need to remap it. */
645 void *p;
646 #ifdef _G_HAVE_MREMAP
647 p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
648 - fp->_IO_buf_base),
649 ROUNDED (st.st_size), MREMAP_MAYMOVE);
650 if (p == MAP_FAILED)
652 (void) __munmap (fp->_IO_buf_base,
653 fp->_IO_buf_end - fp->_IO_buf_base);
654 goto punt;
656 #else
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,
660 fp->_fileno, 0);
661 if (p == MAP_FAILED)
662 goto punt;
663 #endif
664 fp->_IO_buf_base = p;
665 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
667 else
669 /* The number of pages didn't change. */
670 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
672 # undef ROUNDED
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,
678 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
683 buffer until EOF. */
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,
688 SEEK_SET)
689 != fp->_IO_buf_end - fp->_IO_buf_base)
690 fp->_flags |= _IO_ERR_SEEN;
691 else
692 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
695 return 0;
697 else
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);
702 punt:
703 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
704 _IO_setg (fp, NULL, NULL, NULL);
705 if (fp->_mode <= 0)
706 _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
707 else
708 _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
709 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
711 return 1;
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;
730 return EOF;
733 static void
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. */
741 struct stat64 st;
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)
747 /* Sanity check. */
748 && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
750 /* Try to map the file. */
751 void *p;
753 p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
754 if (p != MAP_FAILED)
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;
765 else
767 _IO_setb (fp, p, (char *) p + st.st_size, 0);
769 if (fp->_offset == _IO_pos_BAD)
770 fp->_offset = 0;
772 _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
773 fp->_offset = st.st_size;
775 if (fp->_mode <= 0)
776 _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
777 else
778 _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap;
779 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
781 return;
786 /* We couldn't use mmap, so revert to the vanilla file operations. */
788 if (fp->_mode <= 0)
789 _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
790 else
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;
811 __set_errno (EBADF);
812 return EOF;
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)
820 _IO_doallocbuf (f);
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;
850 if (ch == EOF)
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)
855 return 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)
861 return 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)
869 _IO_ssize_t delta;
870 int retval = 0;
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;
876 if (delta != 0)
878 #ifdef TODO
879 if (_IO_in_backup (fp))
880 delta -= eGptr () - Gbase ();
881 #endif
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;
885 #ifdef ESPIPE
886 else if (errno == ESPIPE)
887 ; /* Ignore error from unseekable devices. */
888 #endif
889 else
890 retval = EOF;
892 if (retval != EOF)
893 fp->_offset = _IO_pos_BAD;
894 /* FIXME: Cleanup - can this be shared? */
895 /* setg(base(), ptr, ptr); */
896 return retval;
898 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
900 static int
901 _IO_file_sync_mmap (_IO_FILE *fp)
903 if (fp->_IO_read_ptr != fp->_IO_read_end)
905 #ifdef TODO
906 if (_IO_in_backup (fp))
907 delta -= eGptr () - Gbase ();
908 #endif
909 if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base,
910 SEEK_SET)
911 != fp->_IO_read_ptr - fp->_IO_buf_base)
913 fp->_flags |= _IO_ERR_SEEN;
914 return EOF;
917 fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
918 fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
919 return 0;
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. */
925 static _IO_off64_t
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
931 yet. */
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)
945 return EOF;
946 else
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
957 file. */
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. */
961 else
962 offset += fp->_IO_write_ptr - fp->_IO_read_end;
965 if (fp->_offset != _IO_pos_BAD)
966 result = fp->_offset;
967 else
968 result = _IO_SYSSEEK (fp, 0, _IO_seek_cur);
970 if (result == EOF)
971 return result;
973 result += offset;
975 if (result < 0)
977 __set_errno (EINVAL);
978 return EOF;
981 return result;
984 _IO_off64_t
985 _IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
987 _IO_off64_t result;
988 _IO_off64_t delta, new_offset;
989 long count;
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
993 object. */
994 if (mode == 0)
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))
1013 return EOF;
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);
1028 switch (dir)
1030 case _IO_seek_cur:
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)
1035 goto dumb;
1036 /* Make offset absolute, assuming current pointer is file_ptr(). */
1037 offset += fp->_offset;
1038 if (offset < 0)
1040 __set_errno (EINVAL);
1041 return EOF;
1044 dir = _IO_seek_set;
1045 break;
1046 case _IO_seek_set:
1047 break;
1048 case _IO_seek_end:
1050 struct stat64 st;
1051 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1053 offset += st.st_size;
1054 dir = _IO_seek_set;
1056 else
1057 goto dumb;
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),
1072 fp->_IO_read_end);
1073 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1075 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1076 goto resync;
1080 if (fp->_flags & _IO_NO_READS)
1081 goto dumb;
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;
1089 delta = 0;
1091 result = _IO_SYSSEEK (fp, new_offset, 0);
1092 if (result < 0)
1093 return EOF;
1094 if (delta == 0)
1095 count = 0;
1096 else
1098 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
1099 (must_be_exact
1100 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
1101 if (count < delta)
1103 /* We weren't allowed to read, but try to seek the remainder. */
1104 offset = count == EOF ? delta : delta-count;
1105 dir = _IO_seek_cur;
1106 goto dumb;
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);
1114 return offset;
1115 dumb:
1117 _IO_unsave_markers (fp);
1118 result = _IO_SYSSEEK (fp, offset, dir);
1119 if (result != EOF)
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);
1126 return result;
1128 resync:
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);
1136 return offset;
1138 libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
1140 _IO_off64_t
1141 _IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
1143 _IO_off64_t result;
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). */
1149 if (mode == 0)
1150 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
1152 switch (dir)
1154 case _IO_seek_cur:
1155 /* Adjust for read-ahead (bytes is buffer). */
1156 offset += fp->_IO_read_ptr - fp->_IO_read_base;
1157 break;
1158 case _IO_seek_set:
1159 break;
1160 case _IO_seek_end:
1161 offset += fp->_IO_buf_end - fp->_IO_buf_base;
1162 break;
1164 /* At this point, dir==_IO_seek_set. */
1166 if (offset < 0)
1168 /* No negative offsets are valid. */
1169 __set_errno (EINVAL);
1170 return EOF;
1173 result = _IO_SYSSEEK (fp, offset, 0);
1174 if (result < 0)
1175 return EOF;
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);
1182 else
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);
1192 return offset;
1195 static _IO_off64_t
1196 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1197 int mode)
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);
1204 if (result < 0)
1205 return EOF;
1207 fp->_offset = result;
1208 return result;
1211 _IO_ssize_t
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)
1220 _IO_off64_t
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)
1254 _IO_ssize_t
1255 _IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n)
1257 _IO_ssize_t to_do = n;
1258 while (to_do > 0)
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));
1264 if (count < 0)
1266 f->_flags |= _IO_ERR_SEEN;
1267 break;
1269 to_do -= count;
1270 data = (void *) ((char *) data + count);
1272 n -= to_do;
1273 if (f->_offset >= 0)
1274 f->_offset += n;
1275 return n;
1278 _IO_size_t
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;
1283 int must_flush = 0;
1284 _IO_size_t count = 0;
1286 if (n <= 0)
1287 return 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;
1296 if (count >= n)
1298 const char *p;
1299 for (p = s + n; p > s; )
1301 if (*--p == '\n')
1303 count = p - s + 1;
1304 must_flush = 1;
1305 break;
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. */
1314 if (count > 0)
1316 if (count > to_do)
1317 count = to_do;
1318 #ifdef _LIBC
1319 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1320 #else
1321 memcpy (f->_IO_write_ptr, s, count);
1322 f->_IO_write_ptr += count;
1323 #endif
1324 s += count;
1325 to_do -= 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);
1340 if (do_write)
1342 count = new_do_write (f, s, do_write);
1343 to_do -= count;
1344 if (count < do_write)
1345 return n - to_do;
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. */
1351 if (to_do)
1352 to_do -= _IO_default_xsputn (f, s+do_write, to_do);
1354 return n - to_do;
1356 libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
1358 _IO_size_t
1359 _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
1361 _IO_size_t want, have;
1362 _IO_ssize_t count;
1363 char *s = data;
1365 want = n;
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);
1378 while (want > 0)
1380 have = fp->_IO_read_end - fp->_IO_read_ptr;
1381 if (want <= have)
1383 memcpy (s, fp->_IO_read_ptr, want);
1384 fp->_IO_read_ptr += want;
1385 want = 0;
1387 else
1389 if (have > 0)
1391 #ifdef _LIBC
1392 s = __mempcpy (s, fp->_IO_read_ptr, have);
1393 #else
1394 memcpy (s, fp->_IO_read_ptr, have);
1395 s += have;
1396 #endif
1397 want -= 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);
1405 continue;
1408 /* If we now want less than a buffer, underflow and repeat
1409 the copy. Otherwise, _IO_SYSREAD directly to
1410 the user buffer. */
1411 if (fp->_IO_buf_base
1412 && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
1414 if (__underflow (fp) == EOF)
1415 break;
1417 continue;
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. */
1426 count = want;
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);
1435 if (count <= 0)
1437 if (count == 0)
1438 fp->_flags |= _IO_EOF_SEEN;
1439 else
1440 fp->_flags |= _IO_ERR_SEEN;
1442 break;
1445 s += count;
1446 want -= count;
1447 if (fp->_offset != _IO_pos_BAD)
1448 _IO_pos_adjust (fp->_offset, count);
1452 return n - want;
1454 libc_hidden_def (_IO_file_xsgetn)
1456 static _IO_size_t
1457 _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
1459 _IO_size_t have;
1460 char *read_ptr = fp->_IO_read_ptr;
1461 char *s = (char *) data;
1463 have = fp->_IO_read_end - fp->_IO_read_ptr;
1465 if (have < n)
1467 if (__glibc_unlikely (_IO_in_backup (fp)))
1469 #ifdef _LIBC
1470 s = __mempcpy (s, read_ptr, have);
1471 #else
1472 memcpy (s, read_ptr, have);
1473 s += have;
1474 #endif
1475 n -= 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;
1481 if (have < n)
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;
1493 if (have < n)
1494 fp->_flags |= _IO_EOF_SEEN;
1496 if (have != 0)
1498 have = MIN (have, n);
1499 #ifdef _LIBC
1500 s = __mempcpy (s, read_ptr, have);
1501 #else
1502 memcpy (s, read_ptr, have);
1503 s += have;
1504 #endif
1505 fp->_IO_read_ptr = read_ptr + have;
1508 return s - (char *) data;
1511 static _IO_size_t
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);
1521 #ifdef _LIBC
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);
1535 #endif
1537 const struct _IO_jump_t _IO_file_jumps =
1539 JUMP_INIT_DUMMY,
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 =
1564 JUMP_INIT_DUMMY,
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 =
1588 JUMP_INIT_DUMMY,
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)