mktime: check signed shifts on long_int and time_t, too
[glibc.git] / libio / fileops.c
blob93750f8084ae20ce8e013d772b55a69c16e54d34
1 /* Copyright (C) 1993-2012 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/param.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <string.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #include <stdlib.h>
42 #if _LIBC
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>
49 #endif
50 #ifndef errno
51 extern int errno;
52 #endif
53 #ifndef __set_errno
54 # define __set_errno(Val) errno = (Val)
55 #endif
58 #ifdef _LIBC
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)
63 # define _IO_do_write _IO_new_do_write /* For macro uses. */
64 # define _IO_file_close_it _IO_new_file_close_it
65 #else
66 # define _IO_new_do_write _IO_do_write
67 # define _IO_new_file_attach _IO_file_attach
68 # define _IO_new_file_close_it _IO_file_close_it
69 # define _IO_new_file_finish _IO_file_finish
70 # define _IO_new_file_fopen _IO_file_fopen
71 # define _IO_new_file_init _IO_file_init
72 # define _IO_new_file_setbuf _IO_file_setbuf
73 # define _IO_new_file_sync _IO_file_sync
74 # define _IO_new_file_overflow _IO_file_overflow
75 # define _IO_new_file_seekoff _IO_file_seekoff
76 # define _IO_new_file_underflow _IO_file_underflow
77 # define _IO_new_file_write _IO_file_write
78 # define _IO_new_file_xsputn _IO_file_xsputn
79 #endif
82 #ifdef _LIBC
83 extern struct __gconv_trans_data __libio_translit attribute_hidden;
84 #endif
87 /* An fstream can be in at most one of put mode, get mode, or putback mode.
88 Putback mode is a variant of get mode.
90 In a filebuf, there is only one current position, instead of two
91 separate get and put pointers. In get mode, the current position
92 is that of gptr(); in put mode that of pptr().
94 The position in the buffer that corresponds to the position
95 in external file system is normally _IO_read_end, except in putback
96 mode, when it is _IO_save_end.
97 If the field _fb._offset is >= 0, it gives the offset in
98 the file as a whole corresponding to eGptr(). (?)
100 PUT MODE:
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_base_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.
110 GET MODE:
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().
115 PUTBACK MODE:
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.
133 UNBUFFERED STREAMS:
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)
141 void
142 _IO_new_file_init (fp)
143 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 INTUSE(_IO_link_in) (fp);
152 fp->file._fileno = -1;
154 INTDEF2(_IO_new_file_init, _IO_file_init)
157 _IO_new_file_close_it (fp)
158 _IO_FILE *fp;
160 if (!_IO_file_is_open (fp))
161 return EOF;
163 int write_status;
164 if (_IO_in_put_mode (fp))
165 write_status = _IO_do_flush (fp);
166 else if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
167 && !_IO_in_backup (fp))
169 off64_t o = _IO_SEEKOFF (fp, 0, _IO_seek_cur, 0);
170 if (o == WEOF)
171 write_status = EOF;
172 else
173 write_status = _IO_SYSSEEK (fp, o, SEEK_SET) < 0 ? EOF : 0;
175 else
176 write_status = 0;
178 INTUSE(_IO_unsave_markers) (fp);
180 int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
181 ? _IO_SYSCLOSE (fp) : 0);
183 /* Free buffer. */
184 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
185 if (fp->_mode > 0)
187 if (_IO_have_wbackup (fp))
188 INTUSE(_IO_free_wbackup_area) (fp);
189 INTUSE(_IO_wsetb) (fp, NULL, NULL, 0);
190 _IO_wsetg (fp, NULL, NULL, NULL);
191 _IO_wsetp (fp, NULL, NULL);
193 #endif
194 INTUSE(_IO_setb) (fp, NULL, NULL, 0);
195 _IO_setg (fp, NULL, NULL, NULL);
196 _IO_setp (fp, NULL, NULL);
198 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
199 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
200 fp->_fileno = -1;
201 fp->_offset = _IO_pos_BAD;
203 return close_status ? close_status : write_status;
205 INTDEF2(_IO_new_file_close_it, _IO_file_close_it)
207 void
208 _IO_new_file_finish (fp, dummy)
209 _IO_FILE *fp;
210 int dummy;
212 if (_IO_file_is_open (fp))
214 _IO_do_flush (fp);
215 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
216 _IO_SYSCLOSE (fp);
218 INTUSE(_IO_default_finish) (fp, 0);
220 INTDEF2(_IO_new_file_finish, _IO_file_finish)
222 _IO_FILE *
223 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
224 _IO_FILE *fp;
225 const char *filename;
226 int posix_mode;
227 int prot;
228 int read_write;
229 int is32not64;
231 int fdesc;
232 #ifdef _LIBC
233 if (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0))
234 fdesc = open_not_cancel (filename,
235 posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
236 else
237 fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
238 #else
239 fdesc = open (filename, posix_mode, prot);
240 #endif
241 if (fdesc < 0)
242 return NULL;
243 fp->_fileno = fdesc;
244 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
245 if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS))
246 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
247 == _IO_pos_BAD && errno != ESPIPE)
249 close_not_cancel (fdesc);
250 return NULL;
252 INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp);
253 return fp;
255 libc_hidden_def (_IO_file_open)
257 _IO_FILE *
258 _IO_new_file_fopen (fp, filename, mode, is32not64)
259 _IO_FILE *fp;
260 const char *filename;
261 const char *mode;
262 int is32not64;
264 int oflags = 0, omode;
265 int read_write;
266 int oprot = 0666;
267 int i;
268 _IO_FILE *result;
269 #ifdef _LIBC
270 const char *cs;
271 const char *last_recognized;
272 #endif
274 if (_IO_file_is_open (fp))
275 return 0;
276 switch (*mode)
278 case 'r':
279 omode = O_RDONLY;
280 read_write = _IO_NO_WRITES;
281 break;
282 case 'w':
283 omode = O_WRONLY;
284 oflags = O_CREAT|O_TRUNC;
285 read_write = _IO_NO_READS;
286 break;
287 case 'a':
288 omode = O_WRONLY;
289 oflags = O_CREAT|O_APPEND;
290 read_write = _IO_NO_READS|_IO_IS_APPENDING;
291 break;
292 default:
293 __set_errno (EINVAL);
294 return NULL;
296 #ifdef _LIBC
297 last_recognized = mode;
298 #endif
299 for (i = 1; i < 7; ++i)
301 switch (*++mode)
303 case '\0':
304 break;
305 case '+':
306 omode = O_RDWR;
307 read_write &= _IO_IS_APPENDING;
308 #ifdef _LIBC
309 last_recognized = mode;
310 #endif
311 continue;
312 case 'x':
313 oflags |= O_EXCL;
314 #ifdef _LIBC
315 last_recognized = mode;
316 #endif
317 continue;
318 case 'b':
319 #ifdef _LIBC
320 last_recognized = mode;
321 #endif
322 continue;
323 case 'm':
324 fp->_flags2 |= _IO_FLAGS2_MMAP;
325 continue;
326 case 'c':
327 fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
328 continue;
329 case 'e':
330 #ifdef O_CLOEXEC
331 oflags |= O_CLOEXEC;
332 #endif
333 fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
334 continue;
335 default:
336 /* Ignore. */
337 continue;
339 break;
342 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
343 is32not64);
345 if (result != NULL)
347 #ifndef __ASSUME_O_CLOEXEC
348 if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0)
350 int fd = _IO_fileno (fp);
351 if (__have_o_cloexec == 0)
353 int flags = __fcntl (fd, F_GETFD);
354 __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
356 if (__have_o_cloexec < 0)
357 __fcntl (fd, F_SETFD, FD_CLOEXEC);
359 #endif
361 /* Test whether the mode string specifies the conversion. */
362 cs = strstr (last_recognized + 1, ",ccs=");
363 if (cs != NULL)
365 /* Yep. Load the appropriate conversions and set the orientation
366 to wide. */
367 struct gconv_fcts fcts;
368 struct _IO_codecvt *cc;
369 char *endp = __strchrnul (cs + 5, ',');
370 char ccs[endp - (cs + 5) + 3];
372 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
373 strip (ccs, ccs);
375 if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
376 ? upstr (ccs, cs + 5) : ccs) != 0)
378 /* Something went wrong, we cannot load the conversion modules.
379 This means we cannot proceed since the user explicitly asked
380 for these. */
381 (void) INTUSE(_IO_file_close_it) (fp);
382 __set_errno (EINVAL);
383 return NULL;
386 assert (fcts.towc_nsteps == 1);
387 assert (fcts.tomb_nsteps == 1);
389 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
390 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
392 /* Clear the state. We start all over again. */
393 memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
394 memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
396 cc = fp->_codecvt = &fp->_wide_data->_codecvt;
398 /* The functions are always the same. */
399 *cc = __libio_codecvt;
401 cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
402 cc->__cd_in.__cd.__steps = fcts.towc;
404 cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
405 cc->__cd_in.__cd.__data[0].__internal_use = 1;
406 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
407 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
409 /* XXX For now no transliteration. */
410 cc->__cd_in.__cd.__data[0].__trans = NULL;
412 cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
413 cc->__cd_out.__cd.__steps = fcts.tomb;
415 cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
416 cc->__cd_out.__cd.__data[0].__internal_use = 1;
417 cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
418 cc->__cd_out.__cd.__data[0].__statep =
419 &result->_wide_data->_IO_state;
421 /* And now the transliteration. */
422 cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
424 /* From now on use the wide character callback functions. */
425 ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
427 /* Set the mode now. */
428 result->_mode = 1;
432 return result;
434 INTDEF2(_IO_new_file_fopen, _IO_file_fopen)
436 _IO_FILE *
437 _IO_new_file_attach (fp, fd)
438 _IO_FILE *fp;
439 int fd;
441 if (_IO_file_is_open (fp))
442 return NULL;
443 fp->_fileno = fd;
444 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
445 fp->_flags |= _IO_DELETE_DONT_CLOSE;
446 /* Get the current position of the file. */
447 /* We have to do that since that may be junk. */
448 fp->_offset = _IO_pos_BAD;
449 int save_errno = errno;
450 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
451 == _IO_pos_BAD && errno != ESPIPE)
452 return NULL;
453 __set_errno (save_errno);
454 return fp;
456 INTDEF2(_IO_new_file_attach, _IO_file_attach)
458 _IO_FILE *
459 _IO_new_file_setbuf (fp, p, len)
460 _IO_FILE *fp;
461 char *p;
462 _IO_ssize_t len;
464 if (_IO_default_setbuf (fp, p, len) == NULL)
465 return NULL;
467 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
468 = fp->_IO_buf_base;
469 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
471 return fp;
473 INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf)
476 _IO_FILE *
477 _IO_file_setbuf_mmap (fp, p, len)
478 _IO_FILE *fp;
479 char *p;
480 _IO_ssize_t len;
482 _IO_FILE *result;
484 /* Change the function table. */
485 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
486 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
488 /* And perform the normal operation. */
489 result = _IO_new_file_setbuf (fp, p, len);
491 /* If the call failed, restore to using mmap. */
492 if (result == NULL)
494 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
495 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
498 return result;
501 static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
503 /* Write TO_DO bytes from DATA to FP.
504 Then mark FP as having empty buffers. */
507 _IO_new_do_write (fp, data, to_do)
508 _IO_FILE *fp;
509 const char *data;
510 _IO_size_t to_do;
512 return (to_do == 0
513 || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
515 INTDEF2(_IO_new_do_write, _IO_do_write)
517 static
518 _IO_size_t
519 new_do_write (fp, data, to_do)
520 _IO_FILE *fp;
521 const char *data;
522 _IO_size_t to_do;
524 _IO_size_t count;
525 if (fp->_flags & _IO_IS_APPENDING)
526 /* On a system without a proper O_APPEND implementation,
527 you would need to sys_seek(0, SEEK_END) here, but is
528 not needed nor desirable for Unix- or Posix-like systems.
529 Instead, just indicate that offset (before and after) is
530 unpredictable. */
531 fp->_offset = _IO_pos_BAD;
532 else if (fp->_IO_read_end != fp->_IO_write_base)
534 _IO_off64_t new_pos
535 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
536 if (new_pos == _IO_pos_BAD)
537 return 0;
538 fp->_offset = new_pos;
540 count = _IO_SYSWRITE (fp, data, to_do);
541 if (fp->_cur_column && count)
542 fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
543 count) + 1;
544 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
545 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
546 fp->_IO_write_end = (fp->_mode <= 0
547 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
548 ? fp->_IO_buf_base : fp->_IO_buf_end);
549 return count;
553 _IO_new_file_underflow (fp)
554 _IO_FILE *fp;
556 _IO_ssize_t count;
557 #if 0
558 /* SysV does not make this test; take it out for compatibility */
559 if (fp->_flags & _IO_EOF_SEEN)
560 return (EOF);
561 #endif
563 if (fp->_flags & _IO_NO_READS)
565 fp->_flags |= _IO_ERR_SEEN;
566 __set_errno (EBADF);
567 return EOF;
569 if (fp->_IO_read_ptr < fp->_IO_read_end)
570 return *(unsigned char *) fp->_IO_read_ptr;
572 if (fp->_IO_buf_base == NULL)
574 /* Maybe we already have a push back pointer. */
575 if (fp->_IO_save_base != NULL)
577 free (fp->_IO_save_base);
578 fp->_flags &= ~_IO_IN_BACKUP;
580 INTUSE(_IO_doallocbuf) (fp);
583 /* Flush all line buffered files before reading. */
584 /* FIXME This can/should be moved to genops ?? */
585 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
587 #if 0
588 INTUSE(_IO_flush_all_linebuffered) ();
589 #else
590 /* We used to flush all line-buffered stream. This really isn't
591 required by any standard. My recollection is that
592 traditional Unix systems did this for stdout. stderr better
593 not be line buffered. So we do just that here
594 explicitly. --drepper */
595 _IO_acquire_lock (_IO_stdout);
597 if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
598 == (_IO_LINKED | _IO_LINE_BUF))
599 _IO_OVERFLOW (_IO_stdout, EOF);
601 _IO_release_lock (_IO_stdout);
602 #endif
605 INTUSE(_IO_switch_to_get_mode) (fp);
607 /* This is very tricky. We have to adjust those
608 pointers before we call _IO_SYSREAD () since
609 we may longjump () out while waiting for
610 input. Those pointers may be screwed up. H.J. */
611 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
612 fp->_IO_read_end = fp->_IO_buf_base;
613 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
614 = fp->_IO_buf_base;
616 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
617 fp->_IO_buf_end - fp->_IO_buf_base);
618 if (count <= 0)
620 if (count == 0)
621 fp->_flags |= _IO_EOF_SEEN;
622 else
623 fp->_flags |= _IO_ERR_SEEN, count = 0;
625 fp->_IO_read_end += count;
626 if (count == 0)
627 return EOF;
628 if (fp->_offset != _IO_pos_BAD)
629 _IO_pos_adjust (fp->_offset, count);
630 return *(unsigned char *) fp->_IO_read_ptr;
632 INTDEF2(_IO_new_file_underflow, _IO_file_underflow)
634 /* Guts of underflow callback if we mmap the file. This stats the file and
635 updates the stream state to match. In the normal case we return zero.
636 If the file is no longer eligible for mmap, its jump tables are reset to
637 the vanilla ones and we return nonzero. */
638 static int
639 mmap_remap_check (_IO_FILE *fp)
641 struct _G_stat64 st;
643 if (_IO_SYSSTAT (fp, &st) == 0
644 && S_ISREG (st.st_mode) && st.st_size != 0
645 /* Limit the file size to 1MB for 32-bit machines. */
646 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024))
648 const size_t pagesize = __getpagesize ();
649 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
650 if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end
651 - fp->_IO_buf_base))
653 /* We can trim off some pages past the end of the file. */
654 (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size),
655 ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base)
656 - ROUNDED (st.st_size));
657 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
659 else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
660 - fp->_IO_buf_base))
662 /* The file added some pages. We need to remap it. */
663 void *p;
664 #ifdef _G_HAVE_MREMAP
665 p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
666 - fp->_IO_buf_base),
667 ROUNDED (st.st_size), MREMAP_MAYMOVE);
668 if (p == MAP_FAILED)
670 (void) __munmap (fp->_IO_buf_base,
671 fp->_IO_buf_end - fp->_IO_buf_base);
672 goto punt;
674 #else
675 (void) __munmap (fp->_IO_buf_base,
676 fp->_IO_buf_end - fp->_IO_buf_base);
677 # ifdef _G_MMAP64
678 p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
679 fp->_fileno, 0);
680 # else
681 p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED,
682 fp->_fileno, 0);
683 # endif
684 if (p == MAP_FAILED)
685 goto punt;
686 #endif
687 fp->_IO_buf_base = p;
688 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
690 else
692 /* The number of pages didn't change. */
693 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
695 # undef ROUNDED
697 fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
698 _IO_setg (fp, fp->_IO_buf_base,
699 fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
700 ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
701 fp->_IO_buf_end);
703 /* If we are already positioned at or past the end of the file, don't
704 change the current offset. If not, seek past what we have mapped,
705 mimicking the position left by a normal underflow reading into its
706 buffer until EOF. */
708 if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
710 if (
711 # ifdef _G_LSEEK64
712 _G_LSEEK64
713 # else
714 __lseek
715 # endif
716 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET)
717 != fp->_IO_buf_end - fp->_IO_buf_base)
718 fp->_flags |= _IO_ERR_SEEN;
719 else
720 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
723 return 0;
725 else
727 /* Life is no longer good for mmap. Punt it. */
728 (void) __munmap (fp->_IO_buf_base,
729 fp->_IO_buf_end - fp->_IO_buf_base);
730 punt:
731 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
732 _IO_setg (fp, NULL, NULL, NULL);
733 if (fp->_mode <= 0)
734 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
735 else
736 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
737 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
739 return 1;
743 /* Special callback replacing the underflow callbacks if we mmap the file. */
745 _IO_file_underflow_mmap (_IO_FILE *fp)
747 if (fp->_IO_read_ptr < fp->_IO_read_end)
748 return *(unsigned char *) fp->_IO_read_ptr;
750 if (__builtin_expect (mmap_remap_check (fp), 0))
751 /* We punted to the regular file functions. */
752 return _IO_UNDERFLOW (fp);
754 if (fp->_IO_read_ptr < fp->_IO_read_end)
755 return *(unsigned char *) fp->_IO_read_ptr;
757 fp->_flags |= _IO_EOF_SEEN;
758 return EOF;
761 static void
762 decide_maybe_mmap (_IO_FILE *fp)
764 /* We use the file in read-only mode. This could mean we can
765 mmap the file and use it without any copying. But not all
766 file descriptors are for mmap-able objects and on 32-bit
767 machines we don't want to map files which are too large since
768 this would require too much virtual memory. */
769 struct _G_stat64 st;
771 if (_IO_SYSSTAT (fp, &st) == 0
772 && S_ISREG (st.st_mode) && st.st_size != 0
773 /* Limit the file size to 1MB for 32-bit machines. */
774 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)
775 /* Sanity check. */
776 && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
778 /* Try to map the file. */
779 void *p;
781 # ifdef _G_MMAP64
782 p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
783 # else
784 p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
785 # endif
786 if (p != MAP_FAILED)
788 /* OK, we managed to map the file. Set the buffer up and use a
789 special jump table with simplified underflow functions which
790 never tries to read anything from the file. */
792 if (
793 # ifdef _G_LSEEK64
794 _G_LSEEK64
795 # else
796 __lseek
797 # endif
798 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
800 (void) __munmap (p, st.st_size);
801 fp->_offset = _IO_pos_BAD;
803 else
805 INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0);
807 if (fp->_offset == _IO_pos_BAD)
808 fp->_offset = 0;
810 _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
811 fp->_offset = st.st_size;
813 if (fp->_mode <= 0)
814 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap;
815 else
816 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap;
817 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
819 return;
824 /* We couldn't use mmap, so revert to the vanilla file operations. */
826 if (fp->_mode <= 0)
827 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
828 else
829 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
830 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
834 _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
836 /* This is the first read attempt. Choose mmap or vanilla operations
837 and then punt to the chosen underflow routine. */
838 decide_maybe_mmap (fp);
839 return _IO_UNDERFLOW (fp);
844 _IO_new_file_overflow (f, ch)
845 _IO_FILE *f;
846 int ch;
848 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
850 f->_flags |= _IO_ERR_SEEN;
851 __set_errno (EBADF);
852 return EOF;
854 /* If currently reading or no buffer allocated. */
855 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
857 /* Allocate a buffer if needed. */
858 if (f->_IO_write_base == NULL)
860 INTUSE(_IO_doallocbuf) (f);
861 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
863 /* Otherwise must be currently reading.
864 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
865 logically slide the buffer forwards one block (by setting the
866 read pointers to all point at the beginning of the block). This
867 makes room for subsequent output.
868 Otherwise, set the read pointers to _IO_read_end (leaving that
869 alone, so it can continue to correspond to the external position). */
870 if (__builtin_expect (_IO_in_backup (f), 0))
872 size_t nbackup = f->_IO_read_end - f->_IO_read_ptr;
873 INTUSE(_IO_free_backup_area) (f);
874 f->_IO_read_base -= MIN (nbackup,
875 f->_IO_read_base - f->_IO_buf_base);
876 f->_IO_read_ptr = f->_IO_read_base;
879 if (f->_IO_read_ptr == f->_IO_buf_end)
880 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
881 f->_IO_write_ptr = f->_IO_read_ptr;
882 f->_IO_write_base = f->_IO_write_ptr;
883 f->_IO_write_end = f->_IO_buf_end;
884 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
886 f->_flags |= _IO_CURRENTLY_PUTTING;
887 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
888 f->_IO_write_end = f->_IO_write_ptr;
890 if (ch == EOF)
891 return INTUSE(_IO_do_write) (f, f->_IO_write_base,
892 f->_IO_write_ptr - f->_IO_write_base);
893 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
894 if (_IO_do_flush (f) == EOF)
895 return EOF;
896 *f->_IO_write_ptr++ = ch;
897 if ((f->_flags & _IO_UNBUFFERED)
898 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
899 if (INTUSE(_IO_do_write) (f, f->_IO_write_base,
900 f->_IO_write_ptr - f->_IO_write_base) == EOF)
901 return EOF;
902 return (unsigned char) ch;
904 INTDEF2(_IO_new_file_overflow, _IO_file_overflow)
907 _IO_new_file_sync (fp)
908 _IO_FILE *fp;
910 _IO_ssize_t delta;
911 int retval = 0;
913 /* char* ptr = cur_ptr(); */
914 if (fp->_IO_write_ptr > fp->_IO_write_base)
915 if (_IO_do_flush(fp)) return EOF;
916 delta = fp->_IO_read_ptr - fp->_IO_read_end;
917 if (delta != 0)
919 #ifdef TODO
920 if (_IO_in_backup (fp))
921 delta -= eGptr () - Gbase ();
922 #endif
923 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
924 if (new_pos != (_IO_off64_t) EOF)
925 fp->_IO_read_end = fp->_IO_read_ptr;
926 #ifdef ESPIPE
927 else if (errno == ESPIPE)
928 ; /* Ignore error from unseekable devices. */
929 #endif
930 else
931 retval = EOF;
933 if (retval != EOF)
934 fp->_offset = _IO_pos_BAD;
935 /* FIXME: Cleanup - can this be shared? */
936 /* setg(base(), ptr, ptr); */
937 return retval;
939 INTDEF2(_IO_new_file_sync, _IO_file_sync)
941 static int
942 _IO_file_sync_mmap (_IO_FILE *fp)
944 if (fp->_IO_read_ptr != fp->_IO_read_end)
946 #ifdef TODO
947 if (_IO_in_backup (fp))
948 delta -= eGptr () - Gbase ();
949 #endif
950 if (
951 # ifdef _G_LSEEK64
952 _G_LSEEK64
953 # else
954 __lseek
955 # endif
956 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, SEEK_SET)
957 != fp->_IO_read_ptr - fp->_IO_buf_base)
959 fp->_flags |= _IO_ERR_SEEN;
960 return EOF;
963 fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
964 fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
965 return 0;
969 _IO_off64_t
970 _IO_new_file_seekoff (fp, offset, dir, mode)
971 _IO_FILE *fp;
972 _IO_off64_t offset;
973 int dir;
974 int mode;
976 _IO_off64_t result;
977 _IO_off64_t delta, new_offset;
978 long count;
979 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
980 offset of the underlying file must be exact. */
981 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
982 && fp->_IO_write_base == fp->_IO_write_ptr);
984 if (mode == 0)
985 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
987 /* Flush unwritten characters.
988 (This may do an unneeded write if we seek within the buffer.
989 But to be able to switch to reading, we would need to set
990 egptr to ptr. That can't be done in the current design,
991 which assumes file_ptr() is eGptr. Anyway, since we probably
992 end up flushing when we close(), it doesn't make much difference.)
993 FIXME: simulate mem-papped files. */
995 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
996 if (INTUSE(_IO_switch_to_get_mode) (fp))
997 return EOF;
999 if (fp->_IO_buf_base == NULL)
1001 /* It could be that we already have a pushback buffer. */
1002 if (fp->_IO_read_base != NULL)
1004 free (fp->_IO_read_base);
1005 fp->_flags &= ~_IO_IN_BACKUP;
1007 INTUSE(_IO_doallocbuf) (fp);
1008 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1009 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1012 switch (dir)
1014 case _IO_seek_cur:
1015 /* Adjust for read-ahead (bytes is buffer). */
1016 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
1017 if (fp->_offset == _IO_pos_BAD)
1019 if (mode != 0)
1020 goto dumb;
1021 else
1023 result = _IO_SYSSEEK (fp, 0, dir);
1024 if (result == EOF)
1025 return result;
1027 fp->_offset = result;
1030 /* Make offset absolute, assuming current pointer is file_ptr(). */
1031 offset += fp->_offset;
1032 if (offset < 0)
1034 __set_errno (EINVAL);
1035 return EOF;
1038 dir = _IO_seek_set;
1039 break;
1040 case _IO_seek_set:
1041 break;
1042 case _IO_seek_end:
1044 struct _G_stat64 st;
1045 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1047 offset += st.st_size;
1048 dir = _IO_seek_set;
1050 else
1051 goto dumb;
1054 /* At this point, dir==_IO_seek_set. */
1056 /* If we are only interested in the current position we've found it now. */
1057 if (mode == 0)
1058 return offset;
1060 /* If destination is within current buffer, optimize: */
1061 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
1062 && !_IO_in_backup (fp))
1064 _IO_off64_t start_offset = (fp->_offset
1065 - (fp->_IO_read_end - fp->_IO_buf_base));
1066 if (offset >= start_offset && offset < fp->_offset)
1068 _IO_setg (fp, fp->_IO_buf_base,
1069 fp->_IO_buf_base + (offset - start_offset),
1070 fp->_IO_read_end);
1071 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1073 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1074 goto resync;
1078 if (fp->_flags & _IO_NO_READS)
1079 goto dumb;
1081 /* Try to seek to a block boundary, to improve kernel page management. */
1082 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
1083 delta = offset - new_offset;
1084 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
1086 new_offset = offset;
1087 delta = 0;
1089 result = _IO_SYSSEEK (fp, new_offset, 0);
1090 if (result < 0)
1091 return EOF;
1092 if (delta == 0)
1093 count = 0;
1094 else
1096 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
1097 (must_be_exact
1098 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
1099 if (count < delta)
1101 /* We weren't allowed to read, but try to seek the remainder. */
1102 offset = count == EOF ? delta : delta-count;
1103 dir = _IO_seek_cur;
1104 goto dumb;
1107 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
1108 fp->_IO_buf_base + count);
1109 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1110 fp->_offset = result + count;
1111 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1112 return offset;
1113 dumb:
1115 INTUSE(_IO_unsave_markers) (fp);
1116 result = _IO_SYSSEEK (fp, offset, dir);
1117 if (result != EOF)
1119 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1120 fp->_offset = result;
1121 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1122 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1124 return result;
1126 resync:
1127 /* We need to do it since it is possible that the file offset in
1128 the kernel may be changed behind our back. It may happen when
1129 we fopen a file and then do a fork. One process may access the
1130 file and the kernel file offset will be changed. */
1131 if (fp->_offset >= 0)
1132 _IO_SYSSEEK (fp, fp->_offset, 0);
1134 return offset;
1136 INTDEF2(_IO_new_file_seekoff, _IO_file_seekoff)
1138 _IO_off64_t
1139 _IO_file_seekoff_mmap (fp, offset, dir, mode)
1140 _IO_FILE *fp;
1141 _IO_off64_t offset;
1142 int dir;
1143 int mode;
1145 _IO_off64_t result;
1147 /* If we are only interested in the current position, calculate it and
1148 return right now. This calculation does the right thing when we are
1149 using a pushback buffer, but in the usual case has the same value as
1150 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1151 if (mode == 0)
1152 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
1154 switch (dir)
1156 case _IO_seek_cur:
1157 /* Adjust for read-ahead (bytes is buffer). */
1158 offset += fp->_IO_read_ptr - fp->_IO_read_base;
1159 break;
1160 case _IO_seek_set:
1161 break;
1162 case _IO_seek_end:
1163 offset += fp->_IO_buf_end - fp->_IO_buf_base;
1164 break;
1166 /* At this point, dir==_IO_seek_set. */
1168 if (offset < 0)
1170 /* No negative offsets are valid. */
1171 __set_errno (EINVAL);
1172 return EOF;
1175 result = _IO_SYSSEEK (fp, offset, 0);
1176 if (result < 0)
1177 return EOF;
1179 if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
1180 /* One can fseek arbitrarily past the end of the file
1181 and it is meaningless until one attempts to read.
1182 Leave the buffer pointers in EOF state until underflow. */
1183 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
1184 else
1185 /* Adjust the read pointers to match the file position,
1186 but so the next read attempt will call underflow. */
1187 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
1188 fp->_IO_buf_base + offset);
1190 fp->_offset = result;
1192 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1194 return offset;
1197 static _IO_off64_t
1198 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1199 int mode)
1201 /* We only get here when we haven't tried to read anything yet.
1202 So there is nothing more useful for us to do here than just
1203 the underlying lseek call. */
1205 _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir);
1206 if (result < 0)
1207 return EOF;
1209 fp->_offset = result;
1210 return result;
1213 _IO_ssize_t
1214 _IO_file_read (fp, buf, size)
1215 _IO_FILE *fp;
1216 void *buf;
1217 _IO_ssize_t size;
1219 return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
1220 ? read_not_cancel (fp->_fileno, buf, size)
1221 : read (fp->_fileno, buf, size));
1223 INTDEF(_IO_file_read)
1225 _IO_off64_t
1226 _IO_file_seek (fp, offset, dir)
1227 _IO_FILE *fp;
1228 _IO_off64_t offset;
1229 int dir;
1231 #ifdef _G_LSEEK64
1232 return _G_LSEEK64 (fp->_fileno, offset, dir);
1233 #else
1234 return lseek (fp->_fileno, offset, dir);
1235 #endif
1237 INTDEF(_IO_file_seek)
1240 _IO_file_stat (fp, st)
1241 _IO_FILE *fp;
1242 void *st;
1244 #ifdef _G_FSTAT64
1245 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
1246 #else
1247 return fstat (fp->_fileno, (struct stat *) st);
1248 #endif
1250 INTDEF(_IO_file_stat)
1253 _IO_file_close_mmap (fp)
1254 _IO_FILE *fp;
1256 /* In addition to closing the file descriptor we have to unmap the file. */
1257 (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
1258 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
1259 /* Cancelling close should be avoided if possible since it leaves an
1260 unrecoverable state behind. */
1261 return close_not_cancel (fp->_fileno);
1265 _IO_file_close (fp)
1266 _IO_FILE *fp;
1268 /* Cancelling close should be avoided if possible since it leaves an
1269 unrecoverable state behind. */
1270 return close_not_cancel (fp->_fileno);
1272 INTDEF(_IO_file_close)
1274 _IO_ssize_t
1275 _IO_new_file_write (f, data, n)
1276 _IO_FILE *f;
1277 const void *data;
1278 _IO_ssize_t n;
1280 _IO_ssize_t to_do = n;
1281 while (to_do > 0)
1283 _IO_ssize_t count = (__builtin_expect (f->_flags2
1284 & _IO_FLAGS2_NOTCANCEL, 0)
1285 ? write_not_cancel (f->_fileno, data, to_do)
1286 : write (f->_fileno, data, to_do));
1287 if (count < 0)
1289 f->_flags |= _IO_ERR_SEEN;
1290 break;
1292 to_do -= count;
1293 data = (void *) ((char *) data + count);
1295 n -= to_do;
1296 if (f->_offset >= 0)
1297 f->_offset += n;
1298 return n;
1301 _IO_size_t
1302 _IO_new_file_xsputn (f, data, n)
1303 _IO_FILE *f;
1304 const void *data;
1305 _IO_size_t n;
1307 register const char *s = (const char *) data;
1308 _IO_size_t to_do = n;
1309 int must_flush = 0;
1310 _IO_size_t count = 0;
1312 if (n <= 0)
1313 return 0;
1314 /* This is an optimized implementation.
1315 If the amount to be written straddles a block boundary
1316 (or the filebuf is unbuffered), use sys_write directly. */
1318 /* First figure out how much space is available in the buffer. */
1319 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1321 count = f->_IO_buf_end - f->_IO_write_ptr;
1322 if (count >= n)
1324 register const char *p;
1325 for (p = s + n; p > s; )
1327 if (*--p == '\n')
1329 count = p - s + 1;
1330 must_flush = 1;
1331 break;
1336 else if (f->_IO_write_end > f->_IO_write_ptr)
1337 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1339 /* Then fill the buffer. */
1340 if (count > 0)
1342 if (count > to_do)
1343 count = to_do;
1344 #ifdef _LIBC
1345 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1346 #else
1347 memcpy (f->_IO_write_ptr, s, count);
1348 f->_IO_write_ptr += count;
1349 #endif
1350 s += count;
1351 to_do -= count;
1353 if (to_do + must_flush > 0)
1355 _IO_size_t block_size, do_write;
1356 /* Next flush the (full) buffer. */
1357 if (_IO_OVERFLOW (f, EOF) == EOF)
1358 /* If nothing else has to be written we must not signal the
1359 caller that everything has been written. */
1360 return to_do == 0 ? EOF : n - to_do;
1362 /* Try to maintain alignment: write a whole number of blocks.
1363 dont_write is what gets left over. */
1364 block_size = f->_IO_buf_end - f->_IO_buf_base;
1365 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
1367 if (do_write)
1369 count = new_do_write (f, s, do_write);
1370 to_do -= count;
1371 if (count < do_write)
1372 return n - to_do;
1375 /* Now write out the remainder. Normally, this will fit in the
1376 buffer, but it's somewhat messier for line-buffered files,
1377 so we let _IO_default_xsputn handle the general case. */
1378 if (to_do)
1379 to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do);
1381 return n - to_do;
1383 INTDEF2(_IO_new_file_xsputn, _IO_file_xsputn)
1385 _IO_size_t
1386 _IO_file_xsgetn (fp, data, n)
1387 _IO_FILE *fp;
1388 void *data;
1389 _IO_size_t n;
1391 register _IO_size_t want, have;
1392 register _IO_ssize_t count;
1393 register char *s = data;
1395 want = n;
1397 if (fp->_IO_buf_base == NULL)
1399 /* Maybe we already have a push back pointer. */
1400 if (fp->_IO_save_base != NULL)
1402 free (fp->_IO_save_base);
1403 fp->_flags &= ~_IO_IN_BACKUP;
1405 INTUSE(_IO_doallocbuf) (fp);
1408 while (want > 0)
1410 have = fp->_IO_read_end - fp->_IO_read_ptr;
1411 if (want <= have)
1413 memcpy (s, fp->_IO_read_ptr, want);
1414 fp->_IO_read_ptr += want;
1415 want = 0;
1417 else
1419 if (have > 0)
1421 #ifdef _LIBC
1422 s = __mempcpy (s, fp->_IO_read_ptr, have);
1423 #else
1424 memcpy (s, fp->_IO_read_ptr, have);
1425 s += have;
1426 #endif
1427 want -= have;
1428 fp->_IO_read_ptr += have;
1431 /* Check for backup and repeat */
1432 if (_IO_in_backup (fp))
1434 _IO_switch_to_main_get_area (fp);
1435 continue;
1438 /* If we now want less than a buffer, underflow and repeat
1439 the copy. Otherwise, _IO_SYSREAD directly to
1440 the user buffer. */
1441 if (fp->_IO_buf_base
1442 && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
1444 if (__underflow (fp) == EOF)
1445 break;
1447 continue;
1450 /* These must be set before the sysread as we might longjmp out
1451 waiting for input. */
1452 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1453 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1455 /* Try to maintain alignment: read a whole number of blocks. */
1456 count = want;
1457 if (fp->_IO_buf_base)
1459 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1460 if (block_size >= 128)
1461 count -= want % block_size;
1464 count = _IO_SYSREAD (fp, s, count);
1465 if (count <= 0)
1467 if (count == 0)
1468 fp->_flags |= _IO_EOF_SEEN;
1469 else
1470 fp->_flags |= _IO_ERR_SEEN;
1472 break;
1475 s += count;
1476 want -= count;
1477 if (fp->_offset != _IO_pos_BAD)
1478 _IO_pos_adjust (fp->_offset, count);
1482 return n - want;
1484 INTDEF(_IO_file_xsgetn)
1486 static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t);
1487 static _IO_size_t
1488 _IO_file_xsgetn_mmap (fp, data, n)
1489 _IO_FILE *fp;
1490 void *data;
1491 _IO_size_t n;
1493 register _IO_size_t have;
1494 char *read_ptr = fp->_IO_read_ptr;
1495 register char *s = (char *) data;
1497 have = fp->_IO_read_end - fp->_IO_read_ptr;
1499 if (have < n)
1501 if (__builtin_expect (_IO_in_backup (fp), 0))
1503 #ifdef _LIBC
1504 s = __mempcpy (s, read_ptr, have);
1505 #else
1506 memcpy (s, read_ptr, have);
1507 s += have;
1508 #endif
1509 n -= have;
1510 _IO_switch_to_main_get_area (fp);
1511 read_ptr = fp->_IO_read_ptr;
1512 have = fp->_IO_read_end - fp->_IO_read_ptr;
1515 if (have < n)
1517 /* Check that we are mapping all of the file, in case it grew. */
1518 if (__builtin_expect (mmap_remap_check (fp), 0))
1519 /* We punted mmap, so complete with the vanilla code. */
1520 return s - (char *) data + _IO_XSGETN (fp, data, n);
1522 read_ptr = fp->_IO_read_ptr;
1523 have = fp->_IO_read_end - read_ptr;
1527 if (have < n)
1528 fp->_flags |= _IO_EOF_SEEN;
1530 if (have != 0)
1532 have = MIN (have, n);
1533 #ifdef _LIBC
1534 s = __mempcpy (s, read_ptr, have);
1535 #else
1536 memcpy (s, read_ptr, have);
1537 s += have;
1538 #endif
1539 fp->_IO_read_ptr = read_ptr + have;
1542 return s - (char *) data;
1545 static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t);
1546 static _IO_size_t
1547 _IO_file_xsgetn_maybe_mmap (fp, data, n)
1548 _IO_FILE *fp;
1549 void *data;
1550 _IO_size_t n;
1552 /* We only get here if this is the first attempt to read something.
1553 Decide which operations to use and then punt to the chosen one. */
1555 decide_maybe_mmap (fp);
1556 return _IO_XSGETN (fp, data, n);
1559 #ifdef _LIBC
1560 # undef _IO_do_write
1561 # undef _IO_file_close_it
1562 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1563 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1564 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1565 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1566 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1567 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1568 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1569 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1570 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1571 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1572 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1573 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1574 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1575 #endif
1577 const struct _IO_jump_t _IO_file_jumps =
1579 JUMP_INIT_DUMMY,
1580 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1581 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1582 JUMP_INIT(underflow, INTUSE(_IO_file_underflow)),
1583 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1584 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1585 JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
1586 JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)),
1587 JUMP_INIT(seekoff, _IO_new_file_seekoff),
1588 JUMP_INIT(seekpos, _IO_default_seekpos),
1589 JUMP_INIT(setbuf, _IO_new_file_setbuf),
1590 JUMP_INIT(sync, _IO_new_file_sync),
1591 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1592 JUMP_INIT(read, INTUSE(_IO_file_read)),
1593 JUMP_INIT(write, _IO_new_file_write),
1594 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1595 JUMP_INIT(close, INTUSE(_IO_file_close)),
1596 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1597 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1598 JUMP_INIT(imbue, _IO_default_imbue)
1600 libc_hidden_data_def (_IO_file_jumps)
1602 const struct _IO_jump_t _IO_file_jumps_mmap =
1604 JUMP_INIT_DUMMY,
1605 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1606 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1607 JUMP_INIT(underflow, _IO_file_underflow_mmap),
1608 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1609 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1610 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1611 JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
1612 JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
1613 JUMP_INIT(seekpos, _IO_default_seekpos),
1614 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1615 JUMP_INIT(sync, _IO_file_sync_mmap),
1616 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1617 JUMP_INIT(read, INTUSE(_IO_file_read)),
1618 JUMP_INIT(write, _IO_new_file_write),
1619 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1620 JUMP_INIT(close, _IO_file_close_mmap),
1621 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1622 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1623 JUMP_INIT(imbue, _IO_default_imbue)
1626 const struct _IO_jump_t _IO_file_jumps_maybe_mmap =
1628 JUMP_INIT_DUMMY,
1629 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1630 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1631 JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
1632 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1633 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1634 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1635 JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
1636 JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
1637 JUMP_INIT(seekpos, _IO_default_seekpos),
1638 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1639 JUMP_INIT(sync, _IO_new_file_sync),
1640 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1641 JUMP_INIT(read, INTUSE(_IO_file_read)),
1642 JUMP_INIT(write, _IO_new_file_write),
1643 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1644 JUMP_INIT(close, _IO_file_close),
1645 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1646 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1647 JUMP_INIT(imbue, _IO_default_imbue)