Remove miscellaneous __STDC__ conditionals.
[glibc.git] / libio / fileops.c
blob201d063bc0c87e85d16e52f2118329fd8ba728c9
1 /* Copyright (C) 1993, 1995, 1997-2005, 2006, 2007, 2008, 2009, 2011-2012
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Per Bothner <bothner@cygnus.com>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 As a special exception, if you link the code in this file with
22 files compiled with a GNU compiler to produce an executable,
23 that does not cause the resulting executable to be covered by
24 the GNU Lesser General Public License. This exception does not
25 however invalidate any other reasons why the executable file
26 might be covered by the GNU Lesser General Public License.
27 This exception applies to code released by its copyright holders
28 in files containing the exception. */
31 #ifndef _POSIX_SOURCE
32 # define _POSIX_SOURCE
33 #endif
34 #include "libioP.h"
35 #include <assert.h>
36 #include <fcntl.h>
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <string.h>
41 #include <errno.h>
42 #include <unistd.h>
43 #include <stdlib.h>
44 #if _LIBC
45 # include "../wcsmbs/wcsmbsload.h"
46 # include "../iconv/gconv_charset.h"
47 # include "../iconv/gconv_int.h"
48 # include <shlib-compat.h>
49 # include <not-cancel.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 # define _IO_do_write _IO_new_do_write /* For macro uses. */
65 # define _IO_file_close_it _IO_new_file_close_it
66 #else
67 # define _IO_new_do_write _IO_do_write
68 # define _IO_new_file_attach _IO_file_attach
69 # define _IO_new_file_close_it _IO_file_close_it
70 # define _IO_new_file_finish _IO_file_finish
71 # define _IO_new_file_fopen _IO_file_fopen
72 # define _IO_new_file_init _IO_file_init
73 # define _IO_new_file_setbuf _IO_file_setbuf
74 # define _IO_new_file_sync _IO_file_sync
75 # define _IO_new_file_overflow _IO_file_overflow
76 # define _IO_new_file_seekoff _IO_file_seekoff
77 # define _IO_new_file_underflow _IO_file_underflow
78 # define _IO_new_file_write _IO_file_write
79 # define _IO_new_file_xsputn _IO_file_xsputn
80 #endif
83 #ifdef _LIBC
84 extern struct __gconv_trans_data __libio_translit attribute_hidden;
85 #endif
88 /* An fstream can be in at most one of put mode, get mode, or putback mode.
89 Putback mode is a variant of get mode.
91 In a filebuf, there is only one current position, instead of two
92 separate get and put pointers. In get mode, the current position
93 is that of gptr(); in put mode that of pptr().
95 The position in the buffer that corresponds to the position
96 in external file system is normally _IO_read_end, except in putback
97 mode, when it is _IO_save_end.
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_base_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 (fp)
144 struct _IO_FILE_plus *fp;
146 /* POSIX.1 allows another file handle to be used to change the position
147 of our file descriptor. Hence we actually don't know the actual
148 position before we do the first fseek (and until a following fflush). */
149 fp->file._offset = _IO_pos_BAD;
150 fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
152 INTUSE(_IO_link_in) (fp);
153 fp->file._fileno = -1;
155 INTDEF2(_IO_new_file_init, _IO_file_init)
158 _IO_new_file_close_it (fp)
159 _IO_FILE *fp;
161 if (!_IO_file_is_open (fp))
162 return EOF;
164 int write_status;
165 if (_IO_in_put_mode (fp))
166 write_status = _IO_do_flush (fp);
167 else if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
168 && !_IO_in_backup (fp))
170 off64_t o = _IO_SEEKOFF (fp, 0, _IO_seek_cur, 0);
171 if (o == WEOF)
172 write_status = EOF;
173 else
174 write_status = _IO_SYSSEEK (fp, o, SEEK_SET) < 0 ? EOF : 0;
176 else
177 write_status = 0;
179 INTUSE(_IO_unsave_markers) (fp);
181 int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
182 ? _IO_SYSCLOSE (fp) : 0);
184 /* Free buffer. */
185 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
186 if (fp->_mode > 0)
188 if (_IO_have_wbackup (fp))
189 INTUSE(_IO_free_wbackup_area) (fp);
190 INTUSE(_IO_wsetb) (fp, NULL, NULL, 0);
191 _IO_wsetg (fp, NULL, NULL, NULL);
192 _IO_wsetp (fp, NULL, NULL);
194 #endif
195 INTUSE(_IO_setb) (fp, NULL, NULL, 0);
196 _IO_setg (fp, NULL, NULL, NULL);
197 _IO_setp (fp, NULL, NULL);
199 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
200 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
201 fp->_fileno = -1;
202 fp->_offset = _IO_pos_BAD;
204 return close_status ? close_status : write_status;
206 INTDEF2(_IO_new_file_close_it, _IO_file_close_it)
208 void
209 _IO_new_file_finish (fp, dummy)
210 _IO_FILE *fp;
211 int dummy;
213 if (_IO_file_is_open (fp))
215 _IO_do_flush (fp);
216 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
217 _IO_SYSCLOSE (fp);
219 INTUSE(_IO_default_finish) (fp, 0);
221 INTDEF2(_IO_new_file_finish, _IO_file_finish)
223 _IO_FILE *
224 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
225 _IO_FILE *fp;
226 const char *filename;
227 int posix_mode;
228 int prot;
229 int read_write;
230 int is32not64;
232 int fdesc;
233 #ifdef _LIBC
234 if (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0))
235 fdesc = open_not_cancel (filename,
236 posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
237 else
238 fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
239 #else
240 fdesc = open (filename, posix_mode, prot);
241 #endif
242 if (fdesc < 0)
243 return NULL;
244 fp->_fileno = fdesc;
245 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
246 if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS))
247 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
248 == _IO_pos_BAD && errno != ESPIPE)
250 close_not_cancel (fdesc);
251 return NULL;
253 INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp);
254 return fp;
256 libc_hidden_def (_IO_file_open)
258 _IO_FILE *
259 _IO_new_file_fopen (fp, filename, mode, is32not64)
260 _IO_FILE *fp;
261 const char *filename;
262 const char *mode;
263 int is32not64;
265 int oflags = 0, omode;
266 int read_write;
267 int oprot = 0666;
268 int i;
269 _IO_FILE *result;
270 #ifdef _LIBC
271 const char *cs;
272 const char *last_recognized;
273 #endif
275 if (_IO_file_is_open (fp))
276 return 0;
277 switch (*mode)
279 case 'r':
280 omode = O_RDONLY;
281 read_write = _IO_NO_WRITES;
282 break;
283 case 'w':
284 omode = O_WRONLY;
285 oflags = O_CREAT|O_TRUNC;
286 read_write = _IO_NO_READS;
287 break;
288 case 'a':
289 omode = O_WRONLY;
290 oflags = O_CREAT|O_APPEND;
291 read_write = _IO_NO_READS|_IO_IS_APPENDING;
292 break;
293 default:
294 __set_errno (EINVAL);
295 return NULL;
297 #ifdef _LIBC
298 last_recognized = mode;
299 #endif
300 for (i = 1; i < 7; ++i)
302 switch (*++mode)
304 case '\0':
305 break;
306 case '+':
307 omode = O_RDWR;
308 read_write &= _IO_IS_APPENDING;
309 #ifdef _LIBC
310 last_recognized = mode;
311 #endif
312 continue;
313 case 'x':
314 oflags |= O_EXCL;
315 #ifdef _LIBC
316 last_recognized = mode;
317 #endif
318 continue;
319 case 'b':
320 #ifdef _LIBC
321 last_recognized = mode;
322 #endif
323 continue;
324 case 'm':
325 fp->_flags2 |= _IO_FLAGS2_MMAP;
326 continue;
327 case 'c':
328 fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
329 continue;
330 case 'e':
331 #ifdef O_CLOEXEC
332 oflags |= O_CLOEXEC;
333 #endif
334 fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
335 continue;
336 default:
337 /* Ignore. */
338 continue;
340 break;
343 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
344 is32not64);
346 if (result != NULL)
348 #ifndef __ASSUME_O_CLOEXEC
349 if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0)
351 int fd = _IO_fileno (fp);
352 if (__have_o_cloexec == 0)
354 int flags = __fcntl (fd, F_GETFD);
355 __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
357 if (__have_o_cloexec < 0)
358 __fcntl (fd, F_SETFD, FD_CLOEXEC);
360 #endif
362 /* Test whether the mode string specifies the conversion. */
363 cs = strstr (last_recognized + 1, ",ccs=");
364 if (cs != NULL)
366 /* Yep. Load the appropriate conversions and set the orientation
367 to wide. */
368 struct gconv_fcts fcts;
369 struct _IO_codecvt *cc;
370 char *endp = __strchrnul (cs + 5, ',');
371 char ccs[endp - (cs + 5) + 3];
373 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
374 strip (ccs, ccs);
376 if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
377 ? upstr (ccs, cs + 5) : ccs) != 0)
379 /* Something went wrong, we cannot load the conversion modules.
380 This means we cannot proceed since the user explicitly asked
381 for these. */
382 (void) INTUSE(_IO_file_close_it) (fp);
383 __set_errno (EINVAL);
384 return NULL;
387 assert (fcts.towc_nsteps == 1);
388 assert (fcts.tomb_nsteps == 1);
390 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
391 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
393 /* Clear the state. We start all over again. */
394 memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
395 memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
397 cc = fp->_codecvt = &fp->_wide_data->_codecvt;
399 /* The functions are always the same. */
400 *cc = __libio_codecvt;
402 cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
403 cc->__cd_in.__cd.__steps = fcts.towc;
405 cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
406 cc->__cd_in.__cd.__data[0].__internal_use = 1;
407 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
408 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
410 /* XXX For now no transliteration. */
411 cc->__cd_in.__cd.__data[0].__trans = NULL;
413 cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
414 cc->__cd_out.__cd.__steps = fcts.tomb;
416 cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
417 cc->__cd_out.__cd.__data[0].__internal_use = 1;
418 cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
419 cc->__cd_out.__cd.__data[0].__statep =
420 &result->_wide_data->_IO_state;
422 /* And now the transliteration. */
423 cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
425 /* From now on use the wide character callback functions. */
426 ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
428 /* Set the mode now. */
429 result->_mode = 1;
433 return result;
435 INTDEF2(_IO_new_file_fopen, _IO_file_fopen)
437 _IO_FILE *
438 _IO_new_file_attach (fp, fd)
439 _IO_FILE *fp;
440 int fd;
442 if (_IO_file_is_open (fp))
443 return NULL;
444 fp->_fileno = fd;
445 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
446 fp->_flags |= _IO_DELETE_DONT_CLOSE;
447 /* Get the current position of the file. */
448 /* We have to do that since that may be junk. */
449 fp->_offset = _IO_pos_BAD;
450 int save_errno = errno;
451 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
452 == _IO_pos_BAD && errno != ESPIPE)
453 return NULL;
454 __set_errno (save_errno);
455 return fp;
457 INTDEF2(_IO_new_file_attach, _IO_file_attach)
459 _IO_FILE *
460 _IO_new_file_setbuf (fp, p, len)
461 _IO_FILE *fp;
462 char *p;
463 _IO_ssize_t len;
465 if (_IO_default_setbuf (fp, p, len) == NULL)
466 return NULL;
468 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
469 = fp->_IO_buf_base;
470 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
472 return fp;
474 INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf)
477 _IO_FILE *
478 _IO_file_setbuf_mmap (fp, p, len)
479 _IO_FILE *fp;
480 char *p;
481 _IO_ssize_t len;
483 _IO_FILE *result;
485 /* Change the function table. */
486 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
487 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
489 /* And perform the normal operation. */
490 result = _IO_new_file_setbuf (fp, p, len);
492 /* If the call failed, restore to using mmap. */
493 if (result == NULL)
495 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
496 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
499 return result;
502 static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
504 /* Write TO_DO bytes from DATA to FP.
505 Then mark FP as having empty buffers. */
508 _IO_new_do_write (fp, data, to_do)
509 _IO_FILE *fp;
510 const char *data;
511 _IO_size_t to_do;
513 return (to_do == 0
514 || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
516 INTDEF2(_IO_new_do_write, _IO_do_write)
518 static
519 _IO_size_t
520 new_do_write (fp, data, to_do)
521 _IO_FILE *fp;
522 const char *data;
523 _IO_size_t to_do;
525 _IO_size_t count;
526 if (fp->_flags & _IO_IS_APPENDING)
527 /* On a system without a proper O_APPEND implementation,
528 you would need to sys_seek(0, SEEK_END) here, but is
529 not needed nor desirable for Unix- or Posix-like systems.
530 Instead, just indicate that offset (before and after) is
531 unpredictable. */
532 fp->_offset = _IO_pos_BAD;
533 else if (fp->_IO_read_end != fp->_IO_write_base)
535 _IO_off64_t new_pos
536 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
537 if (new_pos == _IO_pos_BAD)
538 return 0;
539 fp->_offset = new_pos;
541 count = _IO_SYSWRITE (fp, data, to_do);
542 if (fp->_cur_column && count)
543 fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
544 count) + 1;
545 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
546 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
547 fp->_IO_write_end = (fp->_mode <= 0
548 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
549 ? fp->_IO_buf_base : fp->_IO_buf_end);
550 return count;
554 _IO_new_file_underflow (fp)
555 _IO_FILE *fp;
557 _IO_ssize_t count;
558 #if 0
559 /* SysV does not make this test; take it out for compatibility */
560 if (fp->_flags & _IO_EOF_SEEN)
561 return (EOF);
562 #endif
564 if (fp->_flags & _IO_NO_READS)
566 fp->_flags |= _IO_ERR_SEEN;
567 __set_errno (EBADF);
568 return EOF;
570 if (fp->_IO_read_ptr < fp->_IO_read_end)
571 return *(unsigned char *) fp->_IO_read_ptr;
573 if (fp->_IO_buf_base == NULL)
575 /* Maybe we already have a push back pointer. */
576 if (fp->_IO_save_base != NULL)
578 free (fp->_IO_save_base);
579 fp->_flags &= ~_IO_IN_BACKUP;
581 INTUSE(_IO_doallocbuf) (fp);
584 /* Flush all line buffered files before reading. */
585 /* FIXME This can/should be moved to genops ?? */
586 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
588 #if 0
589 INTUSE(_IO_flush_all_linebuffered) ();
590 #else
591 /* We used to flush all line-buffered stream. This really isn't
592 required by any standard. My recollection is that
593 traditional Unix systems did this for stdout. stderr better
594 not be line buffered. So we do just that here
595 explicitly. --drepper */
596 _IO_acquire_lock (_IO_stdout);
598 if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
599 == (_IO_LINKED | _IO_LINE_BUF))
600 _IO_OVERFLOW (_IO_stdout, EOF);
602 _IO_release_lock (_IO_stdout);
603 #endif
606 INTUSE(_IO_switch_to_get_mode) (fp);
608 /* This is very tricky. We have to adjust those
609 pointers before we call _IO_SYSREAD () since
610 we may longjump () out while waiting for
611 input. Those pointers may be screwed up. H.J. */
612 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
613 fp->_IO_read_end = fp->_IO_buf_base;
614 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
615 = fp->_IO_buf_base;
617 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
618 fp->_IO_buf_end - fp->_IO_buf_base);
619 if (count <= 0)
621 if (count == 0)
622 fp->_flags |= _IO_EOF_SEEN;
623 else
624 fp->_flags |= _IO_ERR_SEEN, count = 0;
626 fp->_IO_read_end += count;
627 if (count == 0)
628 return EOF;
629 if (fp->_offset != _IO_pos_BAD)
630 _IO_pos_adjust (fp->_offset, count);
631 return *(unsigned char *) fp->_IO_read_ptr;
633 INTDEF2(_IO_new_file_underflow, _IO_file_underflow)
635 /* Guts of underflow callback if we mmap the file. This stats the file and
636 updates the stream state to match. In the normal case we return zero.
637 If the file is no longer eligible for mmap, its jump tables are reset to
638 the vanilla ones and we return nonzero. */
639 static int
640 mmap_remap_check (_IO_FILE *fp)
642 struct _G_stat64 st;
644 if (_IO_SYSSTAT (fp, &st) == 0
645 && S_ISREG (st.st_mode) && st.st_size != 0
646 /* Limit the file size to 1MB for 32-bit machines. */
647 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024))
649 const size_t pagesize = __getpagesize ();
650 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
651 if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end
652 - fp->_IO_buf_base))
654 /* We can trim off some pages past the end of the file. */
655 (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size),
656 ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base)
657 - ROUNDED (st.st_size));
658 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
660 else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
661 - fp->_IO_buf_base))
663 /* The file added some pages. We need to remap it. */
664 void *p;
665 #ifdef _G_HAVE_MREMAP
666 p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
667 - fp->_IO_buf_base),
668 ROUNDED (st.st_size), MREMAP_MAYMOVE);
669 if (p == MAP_FAILED)
671 (void) __munmap (fp->_IO_buf_base,
672 fp->_IO_buf_end - fp->_IO_buf_base);
673 goto punt;
675 #else
676 (void) __munmap (fp->_IO_buf_base,
677 fp->_IO_buf_end - fp->_IO_buf_base);
678 # ifdef _G_MMAP64
679 p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
680 fp->_fileno, 0);
681 # else
682 p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED,
683 fp->_fileno, 0);
684 # endif
685 if (p == MAP_FAILED)
686 goto punt;
687 #endif
688 fp->_IO_buf_base = p;
689 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
691 else
693 /* The number of pages didn't change. */
694 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
696 # undef ROUNDED
698 fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
699 _IO_setg (fp, fp->_IO_buf_base,
700 fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
701 ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
702 fp->_IO_buf_end);
704 /* If we are already positioned at or past the end of the file, don't
705 change the current offset. If not, seek past what we have mapped,
706 mimicking the position left by a normal underflow reading into its
707 buffer until EOF. */
709 if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
711 if (
712 # ifdef _G_LSEEK64
713 _G_LSEEK64
714 # else
715 __lseek
716 # endif
717 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET)
718 != fp->_IO_buf_end - fp->_IO_buf_base)
719 fp->_flags |= _IO_ERR_SEEN;
720 else
721 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
724 return 0;
726 else
728 /* Life is no longer good for mmap. Punt it. */
729 (void) __munmap (fp->_IO_buf_base,
730 fp->_IO_buf_end - fp->_IO_buf_base);
731 punt:
732 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
733 _IO_setg (fp, NULL, NULL, NULL);
734 if (fp->_mode <= 0)
735 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
736 else
737 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
738 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
740 return 1;
744 /* Special callback replacing the underflow callbacks if we mmap the file. */
746 _IO_file_underflow_mmap (_IO_FILE *fp)
748 if (fp->_IO_read_ptr < fp->_IO_read_end)
749 return *(unsigned char *) fp->_IO_read_ptr;
751 if (__builtin_expect (mmap_remap_check (fp), 0))
752 /* We punted to the regular file functions. */
753 return _IO_UNDERFLOW (fp);
755 if (fp->_IO_read_ptr < fp->_IO_read_end)
756 return *(unsigned char *) fp->_IO_read_ptr;
758 fp->_flags |= _IO_EOF_SEEN;
759 return EOF;
762 static void
763 decide_maybe_mmap (_IO_FILE *fp)
765 /* We use the file in read-only mode. This could mean we can
766 mmap the file and use it without any copying. But not all
767 file descriptors are for mmap-able objects and on 32-bit
768 machines we don't want to map files which are too large since
769 this would require too much virtual memory. */
770 struct _G_stat64 st;
772 if (_IO_SYSSTAT (fp, &st) == 0
773 && S_ISREG (st.st_mode) && st.st_size != 0
774 /* Limit the file size to 1MB for 32-bit machines. */
775 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)
776 /* Sanity check. */
777 && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
779 /* Try to map the file. */
780 void *p;
782 # ifdef _G_MMAP64
783 p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
784 # else
785 p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
786 # endif
787 if (p != MAP_FAILED)
789 /* OK, we managed to map the file. Set the buffer up and use a
790 special jump table with simplified underflow functions which
791 never tries to read anything from the file. */
793 if (
794 # ifdef _G_LSEEK64
795 _G_LSEEK64
796 # else
797 __lseek
798 # endif
799 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
801 (void) __munmap (p, st.st_size);
802 fp->_offset = _IO_pos_BAD;
804 else
806 INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0);
808 if (fp->_offset == _IO_pos_BAD)
809 fp->_offset = 0;
811 _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
812 fp->_offset = st.st_size;
814 if (fp->_mode <= 0)
815 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap;
816 else
817 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap;
818 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
820 return;
825 /* We couldn't use mmap, so revert to the vanilla file operations. */
827 if (fp->_mode <= 0)
828 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
829 else
830 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
831 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
835 _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
837 /* This is the first read attempt. Choose mmap or vanilla operations
838 and then punt to the chosen underflow routine. */
839 decide_maybe_mmap (fp);
840 return _IO_UNDERFLOW (fp);
845 _IO_new_file_overflow (f, ch)
846 _IO_FILE *f;
847 int ch;
849 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
851 f->_flags |= _IO_ERR_SEEN;
852 __set_errno (EBADF);
853 return EOF;
855 /* If currently reading or no buffer allocated. */
856 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
858 /* Allocate a buffer if needed. */
859 if (f->_IO_write_base == NULL)
861 INTUSE(_IO_doallocbuf) (f);
862 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
864 /* Otherwise must be currently reading.
865 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
866 logically slide the buffer forwards one block (by setting the
867 read pointers to all point at the beginning of the block). This
868 makes room for subsequent output.
869 Otherwise, set the read pointers to _IO_read_end (leaving that
870 alone, so it can continue to correspond to the external position). */
871 if (__builtin_expect (_IO_in_backup (f), 0))
873 size_t nbackup = f->_IO_read_end - f->_IO_read_ptr;
874 INTUSE(_IO_free_backup_area) (f);
875 f->_IO_read_base -= MIN (nbackup,
876 f->_IO_read_base - f->_IO_buf_base);
877 f->_IO_read_ptr = f->_IO_read_base;
880 if (f->_IO_read_ptr == f->_IO_buf_end)
881 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
882 f->_IO_write_ptr = f->_IO_read_ptr;
883 f->_IO_write_base = f->_IO_write_ptr;
884 f->_IO_write_end = f->_IO_buf_end;
885 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
887 f->_flags |= _IO_CURRENTLY_PUTTING;
888 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
889 f->_IO_write_end = f->_IO_write_ptr;
891 if (ch == EOF)
892 return INTUSE(_IO_do_write) (f, f->_IO_write_base,
893 f->_IO_write_ptr - f->_IO_write_base);
894 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
895 if (_IO_do_flush (f) == EOF)
896 return EOF;
897 *f->_IO_write_ptr++ = ch;
898 if ((f->_flags & _IO_UNBUFFERED)
899 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
900 if (INTUSE(_IO_do_write) (f, f->_IO_write_base,
901 f->_IO_write_ptr - f->_IO_write_base) == EOF)
902 return EOF;
903 return (unsigned char) ch;
905 INTDEF2(_IO_new_file_overflow, _IO_file_overflow)
908 _IO_new_file_sync (fp)
909 _IO_FILE *fp;
911 _IO_ssize_t delta;
912 int retval = 0;
914 /* char* ptr = cur_ptr(); */
915 if (fp->_IO_write_ptr > fp->_IO_write_base)
916 if (_IO_do_flush(fp)) return EOF;
917 delta = fp->_IO_read_ptr - fp->_IO_read_end;
918 if (delta != 0)
920 #ifdef TODO
921 if (_IO_in_backup (fp))
922 delta -= eGptr () - Gbase ();
923 #endif
924 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
925 if (new_pos != (_IO_off64_t) EOF)
926 fp->_IO_read_end = fp->_IO_read_ptr;
927 #ifdef ESPIPE
928 else if (errno == ESPIPE)
929 ; /* Ignore error from unseekable devices. */
930 #endif
931 else
932 retval = EOF;
934 if (retval != EOF)
935 fp->_offset = _IO_pos_BAD;
936 /* FIXME: Cleanup - can this be shared? */
937 /* setg(base(), ptr, ptr); */
938 return retval;
940 INTDEF2(_IO_new_file_sync, _IO_file_sync)
942 static int
943 _IO_file_sync_mmap (_IO_FILE *fp)
945 if (fp->_IO_read_ptr != fp->_IO_read_end)
947 #ifdef TODO
948 if (_IO_in_backup (fp))
949 delta -= eGptr () - Gbase ();
950 #endif
951 if (
952 # ifdef _G_LSEEK64
953 _G_LSEEK64
954 # else
955 __lseek
956 # endif
957 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, SEEK_SET)
958 != fp->_IO_read_ptr - fp->_IO_buf_base)
960 fp->_flags |= _IO_ERR_SEEN;
961 return EOF;
964 fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
965 fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
966 return 0;
970 _IO_off64_t
971 _IO_new_file_seekoff (fp, offset, dir, mode)
972 _IO_FILE *fp;
973 _IO_off64_t offset;
974 int dir;
975 int mode;
977 _IO_off64_t result;
978 _IO_off64_t delta, new_offset;
979 long count;
980 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
981 offset of the underlying file must be exact. */
982 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
983 && fp->_IO_write_base == fp->_IO_write_ptr);
985 if (mode == 0)
986 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
988 /* Flush unwritten characters.
989 (This may do an unneeded write if we seek within the buffer.
990 But to be able to switch to reading, we would need to set
991 egptr to ptr. That can't be done in the current design,
992 which assumes file_ptr() is eGptr. Anyway, since we probably
993 end up flushing when we close(), it doesn't make much difference.)
994 FIXME: simulate mem-papped files. */
996 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
997 if (INTUSE(_IO_switch_to_get_mode) (fp))
998 return EOF;
1000 if (fp->_IO_buf_base == NULL)
1002 /* It could be that we already have a pushback buffer. */
1003 if (fp->_IO_read_base != NULL)
1005 free (fp->_IO_read_base);
1006 fp->_flags &= ~_IO_IN_BACKUP;
1008 INTUSE(_IO_doallocbuf) (fp);
1009 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1010 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1013 switch (dir)
1015 case _IO_seek_cur:
1016 /* Adjust for read-ahead (bytes is buffer). */
1017 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
1018 if (fp->_offset == _IO_pos_BAD)
1020 if (mode != 0)
1021 goto dumb;
1022 else
1024 result = _IO_SYSSEEK (fp, 0, dir);
1025 if (result == EOF)
1026 return result;
1028 fp->_offset = result;
1031 /* Make offset absolute, assuming current pointer is file_ptr(). */
1032 offset += fp->_offset;
1033 if (offset < 0)
1035 __set_errno (EINVAL);
1036 return EOF;
1039 dir = _IO_seek_set;
1040 break;
1041 case _IO_seek_set:
1042 break;
1043 case _IO_seek_end:
1045 struct _G_stat64 st;
1046 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1048 offset += st.st_size;
1049 dir = _IO_seek_set;
1051 else
1052 goto dumb;
1055 /* At this point, dir==_IO_seek_set. */
1057 /* If we are only interested in the current position we've found it now. */
1058 if (mode == 0)
1059 return offset;
1061 /* If destination is within current buffer, optimize: */
1062 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
1063 && !_IO_in_backup (fp))
1065 _IO_off64_t start_offset = (fp->_offset
1066 - (fp->_IO_read_end - fp->_IO_buf_base));
1067 if (offset >= start_offset && offset < fp->_offset)
1069 _IO_setg (fp, fp->_IO_buf_base,
1070 fp->_IO_buf_base + (offset - start_offset),
1071 fp->_IO_read_end);
1072 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1074 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1075 goto resync;
1079 if (fp->_flags & _IO_NO_READS)
1080 goto dumb;
1082 /* Try to seek to a block boundary, to improve kernel page management. */
1083 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
1084 delta = offset - new_offset;
1085 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
1087 new_offset = offset;
1088 delta = 0;
1090 result = _IO_SYSSEEK (fp, new_offset, 0);
1091 if (result < 0)
1092 return EOF;
1093 if (delta == 0)
1094 count = 0;
1095 else
1097 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
1098 (must_be_exact
1099 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
1100 if (count < delta)
1102 /* We weren't allowed to read, but try to seek the remainder. */
1103 offset = count == EOF ? delta : delta-count;
1104 dir = _IO_seek_cur;
1105 goto dumb;
1108 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
1109 fp->_IO_buf_base + count);
1110 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1111 fp->_offset = result + count;
1112 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1113 return offset;
1114 dumb:
1116 INTUSE(_IO_unsave_markers) (fp);
1117 result = _IO_SYSSEEK (fp, offset, dir);
1118 if (result != EOF)
1120 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1121 fp->_offset = result;
1122 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1123 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1125 return result;
1127 resync:
1128 /* We need to do it since it is possible that the file offset in
1129 the kernel may be changed behind our back. It may happen when
1130 we fopen a file and then do a fork. One process may access the
1131 file and the kernel file offset will be changed. */
1132 if (fp->_offset >= 0)
1133 _IO_SYSSEEK (fp, fp->_offset, 0);
1135 return offset;
1137 INTDEF2(_IO_new_file_seekoff, _IO_file_seekoff)
1139 _IO_off64_t
1140 _IO_file_seekoff_mmap (fp, offset, dir, mode)
1141 _IO_FILE *fp;
1142 _IO_off64_t offset;
1143 int dir;
1144 int mode;
1146 _IO_off64_t result;
1148 /* If we are only interested in the current position, calculate it and
1149 return right now. This calculation does the right thing when we are
1150 using a pushback buffer, but in the usual case has the same value as
1151 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1152 if (mode == 0)
1153 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
1155 switch (dir)
1157 case _IO_seek_cur:
1158 /* Adjust for read-ahead (bytes is buffer). */
1159 offset += fp->_IO_read_ptr - fp->_IO_read_base;
1160 break;
1161 case _IO_seek_set:
1162 break;
1163 case _IO_seek_end:
1164 offset += fp->_IO_buf_end - fp->_IO_buf_base;
1165 break;
1167 /* At this point, dir==_IO_seek_set. */
1169 if (offset < 0)
1171 /* No negative offsets are valid. */
1172 __set_errno (EINVAL);
1173 return EOF;
1176 result = _IO_SYSSEEK (fp, offset, 0);
1177 if (result < 0)
1178 return EOF;
1180 if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
1181 /* One can fseek arbitrarily past the end of the file
1182 and it is meaningless until one attempts to read.
1183 Leave the buffer pointers in EOF state until underflow. */
1184 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
1185 else
1186 /* Adjust the read pointers to match the file position,
1187 but so the next read attempt will call underflow. */
1188 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
1189 fp->_IO_buf_base + offset);
1191 fp->_offset = result;
1193 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1195 return offset;
1198 static _IO_off64_t
1199 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1200 int mode)
1202 /* We only get here when we haven't tried to read anything yet.
1203 So there is nothing more useful for us to do here than just
1204 the underlying lseek call. */
1206 _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir);
1207 if (result < 0)
1208 return EOF;
1210 fp->_offset = result;
1211 return result;
1214 _IO_ssize_t
1215 _IO_file_read (fp, buf, size)
1216 _IO_FILE *fp;
1217 void *buf;
1218 _IO_ssize_t size;
1220 return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
1221 ? read_not_cancel (fp->_fileno, buf, size)
1222 : read (fp->_fileno, buf, size));
1224 INTDEF(_IO_file_read)
1226 _IO_off64_t
1227 _IO_file_seek (fp, offset, dir)
1228 _IO_FILE *fp;
1229 _IO_off64_t offset;
1230 int dir;
1232 #ifdef _G_LSEEK64
1233 return _G_LSEEK64 (fp->_fileno, offset, dir);
1234 #else
1235 return lseek (fp->_fileno, offset, dir);
1236 #endif
1238 INTDEF(_IO_file_seek)
1241 _IO_file_stat (fp, st)
1242 _IO_FILE *fp;
1243 void *st;
1245 #ifdef _G_FSTAT64
1246 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
1247 #else
1248 return fstat (fp->_fileno, (struct stat *) st);
1249 #endif
1251 INTDEF(_IO_file_stat)
1254 _IO_file_close_mmap (fp)
1255 _IO_FILE *fp;
1257 /* In addition to closing the file descriptor we have to unmap the file. */
1258 (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
1259 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
1260 /* Cancelling close should be avoided if possible since it leaves an
1261 unrecoverable state behind. */
1262 return close_not_cancel (fp->_fileno);
1266 _IO_file_close (fp)
1267 _IO_FILE *fp;
1269 /* Cancelling close should be avoided if possible since it leaves an
1270 unrecoverable state behind. */
1271 return close_not_cancel (fp->_fileno);
1273 INTDEF(_IO_file_close)
1275 _IO_ssize_t
1276 _IO_new_file_write (f, data, n)
1277 _IO_FILE *f;
1278 const void *data;
1279 _IO_ssize_t n;
1281 _IO_ssize_t to_do = n;
1282 while (to_do > 0)
1284 _IO_ssize_t count = (__builtin_expect (f->_flags2
1285 & _IO_FLAGS2_NOTCANCEL, 0)
1286 ? write_not_cancel (f->_fileno, data, to_do)
1287 : write (f->_fileno, data, to_do));
1288 if (count < 0)
1290 f->_flags |= _IO_ERR_SEEN;
1291 break;
1293 to_do -= count;
1294 data = (void *) ((char *) data + count);
1296 n -= to_do;
1297 if (f->_offset >= 0)
1298 f->_offset += n;
1299 return n;
1302 _IO_size_t
1303 _IO_new_file_xsputn (f, data, n)
1304 _IO_FILE *f;
1305 const void *data;
1306 _IO_size_t n;
1308 register const char *s = (const char *) data;
1309 _IO_size_t to_do = n;
1310 int must_flush = 0;
1311 _IO_size_t count = 0;
1313 if (n <= 0)
1314 return 0;
1315 /* This is an optimized implementation.
1316 If the amount to be written straddles a block boundary
1317 (or the filebuf is unbuffered), use sys_write directly. */
1319 /* First figure out how much space is available in the buffer. */
1320 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1322 count = f->_IO_buf_end - f->_IO_write_ptr;
1323 if (count >= n)
1325 register const char *p;
1326 for (p = s + n; p > s; )
1328 if (*--p == '\n')
1330 count = p - s + 1;
1331 must_flush = 1;
1332 break;
1337 else if (f->_IO_write_end > f->_IO_write_ptr)
1338 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1340 /* Then fill the buffer. */
1341 if (count > 0)
1343 if (count > to_do)
1344 count = to_do;
1345 if (count > 20)
1347 #ifdef _LIBC
1348 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1349 #else
1350 memcpy (f->_IO_write_ptr, s, count);
1351 f->_IO_write_ptr += count;
1352 #endif
1353 s += count;
1355 else
1357 register char *p = f->_IO_write_ptr;
1358 register int i = (int) count;
1359 while (--i >= 0)
1360 *p++ = *s++;
1361 f->_IO_write_ptr = p;
1363 to_do -= count;
1365 if (to_do + must_flush > 0)
1367 _IO_size_t block_size, do_write;
1368 /* Next flush the (full) buffer. */
1369 if (_IO_OVERFLOW (f, EOF) == EOF)
1370 /* If nothing else has to be written we must not signal the
1371 caller that everything has been written. */
1372 return to_do == 0 ? EOF : n - to_do;
1374 /* Try to maintain alignment: write a whole number of blocks.
1375 dont_write is what gets left over. */
1376 block_size = f->_IO_buf_end - f->_IO_buf_base;
1377 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
1379 if (do_write)
1381 count = new_do_write (f, s, do_write);
1382 to_do -= count;
1383 if (count < do_write)
1384 return n - to_do;
1387 /* Now write out the remainder. Normally, this will fit in the
1388 buffer, but it's somewhat messier for line-buffered files,
1389 so we let _IO_default_xsputn handle the general case. */
1390 if (to_do)
1391 to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do);
1393 return n - to_do;
1395 INTDEF2(_IO_new_file_xsputn, _IO_file_xsputn)
1397 _IO_size_t
1398 _IO_file_xsgetn (fp, data, n)
1399 _IO_FILE *fp;
1400 void *data;
1401 _IO_size_t n;
1403 register _IO_size_t want, have;
1404 register _IO_ssize_t count;
1405 register char *s = data;
1407 want = n;
1409 if (fp->_IO_buf_base == NULL)
1411 /* Maybe we already have a push back pointer. */
1412 if (fp->_IO_save_base != NULL)
1414 free (fp->_IO_save_base);
1415 fp->_flags &= ~_IO_IN_BACKUP;
1417 INTUSE(_IO_doallocbuf) (fp);
1420 while (want > 0)
1422 have = fp->_IO_read_end - fp->_IO_read_ptr;
1423 if (want <= have)
1425 memcpy (s, fp->_IO_read_ptr, want);
1426 fp->_IO_read_ptr += want;
1427 want = 0;
1429 else
1431 if (have > 0)
1433 #ifdef _LIBC
1434 s = __mempcpy (s, fp->_IO_read_ptr, have);
1435 #else
1436 memcpy (s, fp->_IO_read_ptr, have);
1437 s += have;
1438 #endif
1439 want -= have;
1440 fp->_IO_read_ptr += have;
1443 /* Check for backup and repeat */
1444 if (_IO_in_backup (fp))
1446 _IO_switch_to_main_get_area (fp);
1447 continue;
1450 /* If we now want less than a buffer, underflow and repeat
1451 the copy. Otherwise, _IO_SYSREAD directly to
1452 the user buffer. */
1453 if (fp->_IO_buf_base
1454 && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
1456 if (__underflow (fp) == EOF)
1457 break;
1459 continue;
1462 /* These must be set before the sysread as we might longjmp out
1463 waiting for input. */
1464 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1465 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1467 /* Try to maintain alignment: read a whole number of blocks. */
1468 count = want;
1469 if (fp->_IO_buf_base)
1471 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1472 if (block_size >= 128)
1473 count -= want % block_size;
1476 count = _IO_SYSREAD (fp, s, count);
1477 if (count <= 0)
1479 if (count == 0)
1480 fp->_flags |= _IO_EOF_SEEN;
1481 else
1482 fp->_flags |= _IO_ERR_SEEN;
1484 break;
1487 s += count;
1488 want -= count;
1489 if (fp->_offset != _IO_pos_BAD)
1490 _IO_pos_adjust (fp->_offset, count);
1494 return n - want;
1496 INTDEF(_IO_file_xsgetn)
1498 static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t);
1499 static _IO_size_t
1500 _IO_file_xsgetn_mmap (fp, data, n)
1501 _IO_FILE *fp;
1502 void *data;
1503 _IO_size_t n;
1505 register _IO_size_t have;
1506 char *read_ptr = fp->_IO_read_ptr;
1507 register char *s = (char *) data;
1509 have = fp->_IO_read_end - fp->_IO_read_ptr;
1511 if (have < n)
1513 if (__builtin_expect (_IO_in_backup (fp), 0))
1515 #ifdef _LIBC
1516 s = __mempcpy (s, read_ptr, have);
1517 #else
1518 memcpy (s, read_ptr, have);
1519 s += have;
1520 #endif
1521 n -= have;
1522 _IO_switch_to_main_get_area (fp);
1523 read_ptr = fp->_IO_read_ptr;
1524 have = fp->_IO_read_end - fp->_IO_read_ptr;
1527 if (have < n)
1529 /* Check that we are mapping all of the file, in case it grew. */
1530 if (__builtin_expect (mmap_remap_check (fp), 0))
1531 /* We punted mmap, so complete with the vanilla code. */
1532 return s - (char *) data + _IO_XSGETN (fp, data, n);
1534 read_ptr = fp->_IO_read_ptr;
1535 have = fp->_IO_read_end - read_ptr;
1539 if (have < n)
1540 fp->_flags |= _IO_EOF_SEEN;
1542 if (have != 0)
1544 have = MIN (have, n);
1545 #ifdef _LIBC
1546 s = __mempcpy (s, read_ptr, have);
1547 #else
1548 memcpy (s, read_ptr, have);
1549 s += have;
1550 #endif
1551 fp->_IO_read_ptr = read_ptr + have;
1554 return s - (char *) data;
1557 static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t);
1558 static _IO_size_t
1559 _IO_file_xsgetn_maybe_mmap (fp, data, n)
1560 _IO_FILE *fp;
1561 void *data;
1562 _IO_size_t n;
1564 /* We only get here if this is the first attempt to read something.
1565 Decide which operations to use and then punt to the chosen one. */
1567 decide_maybe_mmap (fp);
1568 return _IO_XSGETN (fp, data, n);
1571 #ifdef _LIBC
1572 # undef _IO_do_write
1573 # undef _IO_file_close_it
1574 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1575 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1576 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1577 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1578 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1579 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1580 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1581 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1582 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1583 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1584 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1585 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1586 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1587 #endif
1589 const struct _IO_jump_t _IO_file_jumps =
1591 JUMP_INIT_DUMMY,
1592 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1593 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1594 JUMP_INIT(underflow, INTUSE(_IO_file_underflow)),
1595 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1596 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1597 JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)),
1598 JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)),
1599 JUMP_INIT(seekoff, _IO_new_file_seekoff),
1600 JUMP_INIT(seekpos, _IO_default_seekpos),
1601 JUMP_INIT(setbuf, _IO_new_file_setbuf),
1602 JUMP_INIT(sync, _IO_new_file_sync),
1603 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1604 JUMP_INIT(read, INTUSE(_IO_file_read)),
1605 JUMP_INIT(write, _IO_new_file_write),
1606 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1607 JUMP_INIT(close, INTUSE(_IO_file_close)),
1608 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1609 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1610 JUMP_INIT(imbue, _IO_default_imbue)
1612 libc_hidden_data_def (_IO_file_jumps)
1614 const struct _IO_jump_t _IO_file_jumps_mmap =
1616 JUMP_INIT_DUMMY,
1617 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1618 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1619 JUMP_INIT(underflow, _IO_file_underflow_mmap),
1620 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1621 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1622 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1623 JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
1624 JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
1625 JUMP_INIT(seekpos, _IO_default_seekpos),
1626 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1627 JUMP_INIT(sync, _IO_file_sync_mmap),
1628 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1629 JUMP_INIT(read, INTUSE(_IO_file_read)),
1630 JUMP_INIT(write, _IO_new_file_write),
1631 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1632 JUMP_INIT(close, _IO_file_close_mmap),
1633 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1634 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1635 JUMP_INIT(imbue, _IO_default_imbue)
1638 const struct _IO_jump_t _IO_file_jumps_maybe_mmap =
1640 JUMP_INIT_DUMMY,
1641 JUMP_INIT(finish, INTUSE(_IO_file_finish)),
1642 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)),
1643 JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
1644 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)),
1645 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)),
1646 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1647 JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
1648 JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
1649 JUMP_INIT(seekpos, _IO_default_seekpos),
1650 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1651 JUMP_INIT(sync, _IO_new_file_sync),
1652 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)),
1653 JUMP_INIT(read, INTUSE(_IO_file_read)),
1654 JUMP_INIT(write, _IO_new_file_write),
1655 JUMP_INIT(seek, INTUSE(_IO_file_seek)),
1656 JUMP_INIT(close, _IO_file_close),
1657 JUMP_INIT(stat, INTUSE(_IO_file_stat)),
1658 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1659 JUMP_INIT(imbue, _IO_default_imbue)