i386: Move futex functions from lowlevellock.h to lowlevellock-futex.h.
[glibc.git] / libio / fileops.c
blobde519c585d28d5ca352d4e9c3911ee0ca1f1ec96
1 /* Copyright (C) 1993-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
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 #else
64 # define _IO_new_do_write _IO_do_write
65 # define _IO_new_file_attach _IO_file_attach
66 # define _IO_new_file_close_it _IO_file_close_it
67 # define _IO_new_file_finish _IO_file_finish
68 # define _IO_new_file_fopen _IO_file_fopen
69 # define _IO_new_file_init _IO_file_init
70 # define _IO_new_file_setbuf _IO_file_setbuf
71 # define _IO_new_file_sync _IO_file_sync
72 # define _IO_new_file_overflow _IO_file_overflow
73 # define _IO_new_file_seekoff _IO_file_seekoff
74 # define _IO_new_file_underflow _IO_file_underflow
75 # define _IO_new_file_write _IO_file_write
76 # define _IO_new_file_xsputn _IO_file_xsputn
77 #endif
80 #ifdef _LIBC
81 extern struct __gconv_trans_data __libio_translit attribute_hidden;
82 #endif
85 /* An fstream can be in at most one of put mode, get mode, or putback mode.
86 Putback mode is a variant of get mode.
88 In a filebuf, there is only one current position, instead of two
89 separate get and put pointers. In get mode, the current position
90 is that of gptr(); in put mode that of pptr().
92 The position in the buffer that corresponds to the position
93 in external file system is normally _IO_read_end, except in putback
94 mode, when it is _IO_save_end and also when the file is in append mode,
95 since switching from read to write mode automatically sends the position in
96 the external file system to the end of file.
97 If the field _fb._offset is >= 0, it gives the offset in
98 the file as a whole corresponding to eGptr(). (?)
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_buf_base.
107 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
108 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
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 (struct _IO_FILE_plus *fp)
144 /* POSIX.1 allows another file handle to be used to change the position
145 of our file descriptor. Hence we actually don't know the actual
146 position before we do the first fseek (and until a following fflush). */
147 fp->file._offset = _IO_pos_BAD;
148 fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
150 _IO_link_in (fp);
151 fp->file._fileno = -1;
153 libc_hidden_ver (_IO_new_file_init, _IO_file_init)
156 _IO_new_file_close_it (_IO_FILE *fp)
158 int write_status;
159 if (!_IO_file_is_open (fp))
160 return EOF;
162 if ((fp->_flags & _IO_NO_WRITES) == 0
163 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
164 write_status = _IO_do_flush (fp);
165 else
166 write_status = 0;
168 _IO_unsave_markers (fp);
170 int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
171 ? _IO_SYSCLOSE (fp) : 0);
173 /* Free buffer. */
174 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
175 if (fp->_mode > 0)
177 if (_IO_have_wbackup (fp))
178 _IO_free_wbackup_area (fp);
179 _IO_wsetb (fp, NULL, NULL, 0);
180 _IO_wsetg (fp, NULL, NULL, NULL);
181 _IO_wsetp (fp, NULL, NULL);
183 #endif
184 _IO_setb (fp, NULL, NULL, 0);
185 _IO_setg (fp, NULL, NULL, NULL);
186 _IO_setp (fp, NULL, NULL);
188 _IO_un_link ((struct _IO_FILE_plus *) fp);
189 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
190 fp->_fileno = -1;
191 fp->_offset = _IO_pos_BAD;
193 return close_status ? close_status : write_status;
195 libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it)
197 void
198 _IO_new_file_finish (_IO_FILE *fp, int dummy)
200 if (_IO_file_is_open (fp))
202 _IO_do_flush (fp);
203 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
204 _IO_SYSCLOSE (fp);
206 _IO_default_finish (fp, 0);
208 libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
210 _IO_FILE *
211 _IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot,
212 int read_write, int is32not64)
214 int fdesc;
215 #ifdef _LIBC
216 if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
217 fdesc = open_not_cancel (filename,
218 posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
219 else
220 fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
221 #else
222 fdesc = open (filename, posix_mode, prot);
223 #endif
224 if (fdesc < 0)
225 return NULL;
226 fp->_fileno = fdesc;
227 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
228 /* For append mode, send the file offset to the end of the file. Don't
229 update the offset cache though, since the file handle is not active. */
230 if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS))
231 == (_IO_IS_APPENDING | _IO_NO_READS))
233 _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end);
234 if (new_pos == _IO_pos_BAD && errno != ESPIPE)
236 close_not_cancel (fdesc);
237 return NULL;
240 _IO_link_in ((struct _IO_FILE_plus *) fp);
241 return fp;
243 libc_hidden_def (_IO_file_open)
245 _IO_FILE *
246 _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
247 int is32not64)
249 int oflags = 0, omode;
250 int read_write;
251 int oprot = 0666;
252 int i;
253 _IO_FILE *result;
254 #ifdef _LIBC
255 const char *cs;
256 const char *last_recognized;
257 #endif
259 if (_IO_file_is_open (fp))
260 return 0;
261 switch (*mode)
263 case 'r':
264 omode = O_RDONLY;
265 read_write = _IO_NO_WRITES;
266 break;
267 case 'w':
268 omode = O_WRONLY;
269 oflags = O_CREAT|O_TRUNC;
270 read_write = _IO_NO_READS;
271 break;
272 case 'a':
273 omode = O_WRONLY;
274 oflags = O_CREAT|O_APPEND;
275 read_write = _IO_NO_READS|_IO_IS_APPENDING;
276 break;
277 default:
278 __set_errno (EINVAL);
279 return NULL;
281 #ifdef _LIBC
282 last_recognized = mode;
283 #endif
284 for (i = 1; i < 7; ++i)
286 switch (*++mode)
288 case '\0':
289 break;
290 case '+':
291 omode = O_RDWR;
292 read_write &= _IO_IS_APPENDING;
293 #ifdef _LIBC
294 last_recognized = mode;
295 #endif
296 continue;
297 case 'x':
298 oflags |= O_EXCL;
299 #ifdef _LIBC
300 last_recognized = mode;
301 #endif
302 continue;
303 case 'b':
304 #ifdef _LIBC
305 last_recognized = mode;
306 #endif
307 continue;
308 case 'm':
309 fp->_flags2 |= _IO_FLAGS2_MMAP;
310 continue;
311 case 'c':
312 fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
313 continue;
314 case 'e':
315 #ifdef O_CLOEXEC
316 oflags |= O_CLOEXEC;
317 #endif
318 fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
319 continue;
320 default:
321 /* Ignore. */
322 continue;
324 break;
327 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
328 is32not64);
330 if (result != NULL)
332 #ifndef __ASSUME_O_CLOEXEC
333 if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0)
335 int fd = _IO_fileno (fp);
336 if (__have_o_cloexec == 0)
338 int flags = __fcntl (fd, F_GETFD);
339 __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
341 if (__have_o_cloexec < 0)
342 __fcntl (fd, F_SETFD, FD_CLOEXEC);
344 #endif
346 /* Test whether the mode string specifies the conversion. */
347 cs = strstr (last_recognized + 1, ",ccs=");
348 if (cs != NULL)
350 /* Yep. Load the appropriate conversions and set the orientation
351 to wide. */
352 struct gconv_fcts fcts;
353 struct _IO_codecvt *cc;
354 char *endp = __strchrnul (cs + 5, ',');
355 char ccs[endp - (cs + 5) + 3];
357 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
358 strip (ccs, ccs);
360 if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
361 ? upstr (ccs, cs + 5) : ccs) != 0)
363 /* Something went wrong, we cannot load the conversion modules.
364 This means we cannot proceed since the user explicitly asked
365 for these. */
366 (void) _IO_file_close_it (fp);
367 __set_errno (EINVAL);
368 return NULL;
371 assert (fcts.towc_nsteps == 1);
372 assert (fcts.tomb_nsteps == 1);
374 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
375 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
377 /* Clear the state. We start all over again. */
378 memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
379 memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
381 cc = fp->_codecvt = &fp->_wide_data->_codecvt;
383 /* The functions are always the same. */
384 *cc = __libio_codecvt;
386 cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
387 cc->__cd_in.__cd.__steps = fcts.towc;
389 cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
390 cc->__cd_in.__cd.__data[0].__internal_use = 1;
391 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
392 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
394 cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
395 cc->__cd_out.__cd.__steps = fcts.tomb;
397 cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
398 cc->__cd_out.__cd.__data[0].__internal_use = 1;
399 cc->__cd_out.__cd.__data[0].__flags
400 = __GCONV_IS_LAST | __GCONV_TRANSLIT;
401 cc->__cd_out.__cd.__data[0].__statep =
402 &result->_wide_data->_IO_state;
404 /* From now on use the wide character callback functions. */
405 ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
407 /* Set the mode now. */
408 result->_mode = 1;
412 return result;
414 libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
416 _IO_FILE *
417 _IO_new_file_attach (_IO_FILE *fp, int fd)
419 if (_IO_file_is_open (fp))
420 return NULL;
421 fp->_fileno = fd;
422 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
423 fp->_flags |= _IO_DELETE_DONT_CLOSE;
424 /* Get the current position of the file. */
425 /* We have to do that since that may be junk. */
426 fp->_offset = _IO_pos_BAD;
427 int save_errno = errno;
428 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
429 == _IO_pos_BAD && errno != ESPIPE)
430 return NULL;
431 __set_errno (save_errno);
432 return fp;
434 libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
436 _IO_FILE *
437 _IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
439 if (_IO_default_setbuf (fp, p, len) == NULL)
440 return NULL;
442 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
443 = fp->_IO_buf_base;
444 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
446 return fp;
448 libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
451 _IO_FILE *
452 _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
454 _IO_FILE *result;
456 /* Change the function table. */
457 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
458 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
460 /* And perform the normal operation. */
461 result = _IO_new_file_setbuf (fp, p, len);
463 /* If the call failed, restore to using mmap. */
464 if (result == NULL)
466 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
467 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
470 return result;
473 static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
475 /* Write TO_DO bytes from DATA to FP.
476 Then mark FP as having empty buffers. */
479 _IO_new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
481 return (to_do == 0
482 || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
484 libc_hidden_ver (_IO_new_do_write, _IO_do_write)
486 static
487 _IO_size_t
488 new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
490 _IO_size_t count;
491 if (fp->_flags & _IO_IS_APPENDING)
492 /* On a system without a proper O_APPEND implementation,
493 you would need to sys_seek(0, SEEK_END) here, but is
494 not needed nor desirable for Unix- or Posix-like systems.
495 Instead, just indicate that offset (before and after) is
496 unpredictable. */
497 fp->_offset = _IO_pos_BAD;
498 else if (fp->_IO_read_end != fp->_IO_write_base)
500 _IO_off64_t new_pos
501 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
502 if (new_pos == _IO_pos_BAD)
503 return 0;
504 fp->_offset = new_pos;
506 count = _IO_SYSWRITE (fp, data, to_do);
507 if (fp->_cur_column && count)
508 fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
509 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
510 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
511 fp->_IO_write_end = (fp->_mode <= 0
512 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
513 ? fp->_IO_buf_base : fp->_IO_buf_end);
514 return count;
518 _IO_new_file_underflow (_IO_FILE *fp)
520 _IO_ssize_t count;
521 #if 0
522 /* SysV does not make this test; take it out for compatibility */
523 if (fp->_flags & _IO_EOF_SEEN)
524 return (EOF);
525 #endif
527 if (fp->_flags & _IO_NO_READS)
529 fp->_flags |= _IO_ERR_SEEN;
530 __set_errno (EBADF);
531 return EOF;
533 if (fp->_IO_read_ptr < fp->_IO_read_end)
534 return *(unsigned char *) fp->_IO_read_ptr;
536 if (fp->_IO_buf_base == NULL)
538 /* Maybe we already have a push back pointer. */
539 if (fp->_IO_save_base != NULL)
541 free (fp->_IO_save_base);
542 fp->_flags &= ~_IO_IN_BACKUP;
544 _IO_doallocbuf (fp);
547 /* Flush all line buffered files before reading. */
548 /* FIXME This can/should be moved to genops ?? */
549 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
551 #if 0
552 _IO_flush_all_linebuffered ();
553 #else
554 /* We used to flush all line-buffered stream. This really isn't
555 required by any standard. My recollection is that
556 traditional Unix systems did this for stdout. stderr better
557 not be line buffered. So we do just that here
558 explicitly. --drepper */
559 _IO_acquire_lock (_IO_stdout);
561 if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
562 == (_IO_LINKED | _IO_LINE_BUF))
563 _IO_OVERFLOW (_IO_stdout, EOF);
565 _IO_release_lock (_IO_stdout);
566 #endif
569 _IO_switch_to_get_mode (fp);
571 /* This is very tricky. We have to adjust those
572 pointers before we call _IO_SYSREAD () since
573 we may longjump () out while waiting for
574 input. Those pointers may be screwed up. H.J. */
575 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
576 fp->_IO_read_end = fp->_IO_buf_base;
577 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
578 = fp->_IO_buf_base;
580 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
581 fp->_IO_buf_end - fp->_IO_buf_base);
582 if (count <= 0)
584 if (count == 0)
585 fp->_flags |= _IO_EOF_SEEN;
586 else
587 fp->_flags |= _IO_ERR_SEEN, count = 0;
589 fp->_IO_read_end += count;
590 if (count == 0)
592 /* If a stream is read to EOF, the calling application may switch active
593 handles. As a result, our offset cache would no longer be valid, so
594 unset it. */
595 fp->_offset = _IO_pos_BAD;
596 return EOF;
598 if (fp->_offset != _IO_pos_BAD)
599 _IO_pos_adjust (fp->_offset, count);
600 return *(unsigned char *) fp->_IO_read_ptr;
602 libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
604 /* Guts of underflow callback if we mmap the file. This stats the file and
605 updates the stream state to match. In the normal case we return zero.
606 If the file is no longer eligible for mmap, its jump tables are reset to
607 the vanilla ones and we return nonzero. */
608 static int
609 mmap_remap_check (_IO_FILE *fp)
611 struct stat64 st;
613 if (_IO_SYSSTAT (fp, &st) == 0
614 && S_ISREG (st.st_mode) && st.st_size != 0
615 /* Limit the file size to 1MB for 32-bit machines. */
616 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024))
618 const size_t pagesize = __getpagesize ();
619 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1))
620 if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end
621 - fp->_IO_buf_base))
623 /* We can trim off some pages past the end of the file. */
624 (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size),
625 ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base)
626 - ROUNDED (st.st_size));
627 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
629 else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
630 - fp->_IO_buf_base))
632 /* The file added some pages. We need to remap it. */
633 void *p;
634 #ifdef _G_HAVE_MREMAP
635 p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
636 - fp->_IO_buf_base),
637 ROUNDED (st.st_size), MREMAP_MAYMOVE);
638 if (p == MAP_FAILED)
640 (void) __munmap (fp->_IO_buf_base,
641 fp->_IO_buf_end - fp->_IO_buf_base);
642 goto punt;
644 #else
645 (void) __munmap (fp->_IO_buf_base,
646 fp->_IO_buf_end - fp->_IO_buf_base);
647 p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
648 fp->_fileno, 0);
649 if (p == MAP_FAILED)
650 goto punt;
651 #endif
652 fp->_IO_buf_base = p;
653 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
655 else
657 /* The number of pages didn't change. */
658 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
660 # undef ROUNDED
662 fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
663 _IO_setg (fp, fp->_IO_buf_base,
664 fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
665 ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
666 fp->_IO_buf_end);
668 /* If we are already positioned at or past the end of the file, don't
669 change the current offset. If not, seek past what we have mapped,
670 mimicking the position left by a normal underflow reading into its
671 buffer until EOF. */
673 if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
675 if (__lseek64 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base,
676 SEEK_SET)
677 != fp->_IO_buf_end - fp->_IO_buf_base)
678 fp->_flags |= _IO_ERR_SEEN;
679 else
680 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
683 return 0;
685 else
687 /* Life is no longer good for mmap. Punt it. */
688 (void) __munmap (fp->_IO_buf_base,
689 fp->_IO_buf_end - fp->_IO_buf_base);
690 punt:
691 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
692 _IO_setg (fp, NULL, NULL, NULL);
693 if (fp->_mode <= 0)
694 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
695 else
696 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
697 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
699 return 1;
703 /* Special callback replacing the underflow callbacks if we mmap the file. */
705 _IO_file_underflow_mmap (_IO_FILE *fp)
707 if (fp->_IO_read_ptr < fp->_IO_read_end)
708 return *(unsigned char *) fp->_IO_read_ptr;
710 if (__glibc_unlikely (mmap_remap_check (fp)))
711 /* We punted to the regular file functions. */
712 return _IO_UNDERFLOW (fp);
714 if (fp->_IO_read_ptr < fp->_IO_read_end)
715 return *(unsigned char *) fp->_IO_read_ptr;
717 fp->_flags |= _IO_EOF_SEEN;
718 return EOF;
721 static void
722 decide_maybe_mmap (_IO_FILE *fp)
724 /* We use the file in read-only mode. This could mean we can
725 mmap the file and use it without any copying. But not all
726 file descriptors are for mmap-able objects and on 32-bit
727 machines we don't want to map files which are too large since
728 this would require too much virtual memory. */
729 struct stat64 st;
731 if (_IO_SYSSTAT (fp, &st) == 0
732 && S_ISREG (st.st_mode) && st.st_size != 0
733 /* Limit the file size to 1MB for 32-bit machines. */
734 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)
735 /* Sanity check. */
736 && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
738 /* Try to map the file. */
739 void *p;
741 p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
742 if (p != MAP_FAILED)
744 /* OK, we managed to map the file. Set the buffer up and use a
745 special jump table with simplified underflow functions which
746 never tries to read anything from the file. */
748 if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
750 (void) __munmap (p, st.st_size);
751 fp->_offset = _IO_pos_BAD;
753 else
755 _IO_setb (fp, p, (char *) p + st.st_size, 0);
757 if (fp->_offset == _IO_pos_BAD)
758 fp->_offset = 0;
760 _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
761 fp->_offset = st.st_size;
763 if (fp->_mode <= 0)
764 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap;
765 else
766 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap;
767 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
769 return;
774 /* We couldn't use mmap, so revert to the vanilla file operations. */
776 if (fp->_mode <= 0)
777 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
778 else
779 _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
780 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
784 _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
786 /* This is the first read attempt. Choose mmap or vanilla operations
787 and then punt to the chosen underflow routine. */
788 decide_maybe_mmap (fp);
789 return _IO_UNDERFLOW (fp);
794 _IO_new_file_overflow (_IO_FILE *f, int ch)
796 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
798 f->_flags |= _IO_ERR_SEEN;
799 __set_errno (EBADF);
800 return EOF;
802 /* If currently reading or no buffer allocated. */
803 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
805 /* Allocate a buffer if needed. */
806 if (f->_IO_write_base == NULL)
808 _IO_doallocbuf (f);
809 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
811 /* Otherwise must be currently reading.
812 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
813 logically slide the buffer forwards one block (by setting the
814 read pointers to all point at the beginning of the block). This
815 makes room for subsequent output.
816 Otherwise, set the read pointers to _IO_read_end (leaving that
817 alone, so it can continue to correspond to the external position). */
818 if (__glibc_unlikely (_IO_in_backup (f)))
820 size_t nbackup = f->_IO_read_end - f->_IO_read_ptr;
821 _IO_free_backup_area (f);
822 f->_IO_read_base -= MIN (nbackup,
823 f->_IO_read_base - f->_IO_buf_base);
824 f->_IO_read_ptr = f->_IO_read_base;
827 if (f->_IO_read_ptr == f->_IO_buf_end)
828 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
829 f->_IO_write_ptr = f->_IO_read_ptr;
830 f->_IO_write_base = f->_IO_write_ptr;
831 f->_IO_write_end = f->_IO_buf_end;
832 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
834 f->_flags |= _IO_CURRENTLY_PUTTING;
835 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
836 f->_IO_write_end = f->_IO_write_ptr;
838 if (ch == EOF)
839 return _IO_do_write (f, f->_IO_write_base,
840 f->_IO_write_ptr - f->_IO_write_base);
841 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
842 if (_IO_do_flush (f) == EOF)
843 return EOF;
844 *f->_IO_write_ptr++ = ch;
845 if ((f->_flags & _IO_UNBUFFERED)
846 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
847 if (_IO_do_write (f, f->_IO_write_base,
848 f->_IO_write_ptr - f->_IO_write_base) == EOF)
849 return EOF;
850 return (unsigned char) ch;
852 libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow)
855 _IO_new_file_sync (_IO_FILE *fp)
857 _IO_ssize_t delta;
858 int retval = 0;
860 /* char* ptr = cur_ptr(); */
861 if (fp->_IO_write_ptr > fp->_IO_write_base)
862 if (_IO_do_flush(fp)) return EOF;
863 delta = fp->_IO_read_ptr - fp->_IO_read_end;
864 if (delta != 0)
866 #ifdef TODO
867 if (_IO_in_backup (fp))
868 delta -= eGptr () - Gbase ();
869 #endif
870 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
871 if (new_pos != (_IO_off64_t) EOF)
872 fp->_IO_read_end = fp->_IO_read_ptr;
873 #ifdef ESPIPE
874 else if (errno == ESPIPE)
875 ; /* Ignore error from unseekable devices. */
876 #endif
877 else
878 retval = EOF;
880 if (retval != EOF)
881 fp->_offset = _IO_pos_BAD;
882 /* FIXME: Cleanup - can this be shared? */
883 /* setg(base(), ptr, ptr); */
884 return retval;
886 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
888 static int
889 _IO_file_sync_mmap (_IO_FILE *fp)
891 if (fp->_IO_read_ptr != fp->_IO_read_end)
893 #ifdef TODO
894 if (_IO_in_backup (fp))
895 delta -= eGptr () - Gbase ();
896 #endif
897 if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base,
898 SEEK_SET)
899 != fp->_IO_read_ptr - fp->_IO_buf_base)
901 fp->_flags |= _IO_ERR_SEEN;
902 return EOF;
905 fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
906 fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
907 return 0;
910 /* ftell{,o} implementation. The only time we modify the state of the stream
911 is when we have unflushed writes. In that case we seek to the end and
912 record that offset in the stream object. */
913 static _IO_off64_t
914 do_ftell (_IO_FILE *fp)
916 _IO_off64_t result, offset = 0;
918 /* No point looking at unflushed data if we haven't allocated buffers
919 yet. */
920 if (fp->_IO_buf_base != NULL)
922 bool unflushed_writes = fp->_IO_write_ptr > fp->_IO_write_base;
924 bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
926 /* When we have unflushed writes in append mode, seek to the end of the
927 file and record that offset. This is the only time we change the file
928 stream state and it is safe since the file handle is active. */
929 if (unflushed_writes && append_mode)
931 result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
932 if (result == _IO_pos_BAD)
933 return EOF;
934 else
935 fp->_offset = result;
938 /* Adjust for unflushed data. */
939 if (!unflushed_writes)
940 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
941 /* We don't trust _IO_read_end to represent the current file offset when
942 writing in append mode because the value would have to be shifted to
943 the end of the file during a flush. Use the write base instead, along
944 with the new offset we got above when we did a seek to the end of the
945 file. */
946 else if (append_mode)
947 offset += fp->_IO_write_ptr - fp->_IO_write_base;
948 /* For all other modes, _IO_read_end represents the file offset. */
949 else
950 offset += fp->_IO_write_ptr - fp->_IO_read_end;
953 if (fp->_offset != _IO_pos_BAD)
954 result = fp->_offset;
955 else
956 result = _IO_SYSSEEK (fp, 0, _IO_seek_cur);
958 if (result == EOF)
959 return result;
961 result += offset;
963 if (result < 0)
965 __set_errno (EINVAL);
966 return EOF;
969 return result;
972 _IO_off64_t
973 _IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
975 _IO_off64_t result;
976 _IO_off64_t delta, new_offset;
977 long count;
979 /* Short-circuit into a separate function. We don't want to mix any
980 functionality and we don't want to touch anything inside the FILE
981 object. */
982 if (mode == 0)
983 return do_ftell (fp);
985 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
986 offset of the underlying file must be exact. */
987 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
988 && fp->_IO_write_base == fp->_IO_write_ptr);
990 bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
991 || _IO_in_put_mode (fp));
993 /* Flush unwritten characters.
994 (This may do an unneeded write if we seek within the buffer.
995 But to be able to switch to reading, we would need to set
996 egptr to pptr. That can't be done in the current design,
997 which assumes file_ptr() is eGptr. Anyway, since we probably
998 end up flushing when we close(), it doesn't make much difference.)
999 FIXME: simulate mem-mapped files. */
1000 if (was_writing && _IO_switch_to_get_mode (fp))
1001 return EOF;
1003 if (fp->_IO_buf_base == NULL)
1005 /* It could be that we already have a pushback buffer. */
1006 if (fp->_IO_read_base != NULL)
1008 free (fp->_IO_read_base);
1009 fp->_flags &= ~_IO_IN_BACKUP;
1011 _IO_doallocbuf (fp);
1012 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1013 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1016 switch (dir)
1018 case _IO_seek_cur:
1019 /* Adjust for read-ahead (bytes is buffer). */
1020 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
1022 if (fp->_offset == _IO_pos_BAD)
1023 goto dumb;
1024 /* Make offset absolute, assuming current pointer is file_ptr(). */
1025 offset += fp->_offset;
1026 if (offset < 0)
1028 __set_errno (EINVAL);
1029 return EOF;
1032 dir = _IO_seek_set;
1033 break;
1034 case _IO_seek_set:
1035 break;
1036 case _IO_seek_end:
1038 struct stat64 st;
1039 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1041 offset += st.st_size;
1042 dir = _IO_seek_set;
1044 else
1045 goto dumb;
1048 /* At this point, dir==_IO_seek_set. */
1050 /* If destination is within current buffer, optimize: */
1051 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
1052 && !_IO_in_backup (fp))
1054 _IO_off64_t start_offset = (fp->_offset
1055 - (fp->_IO_read_end - fp->_IO_buf_base));
1056 if (offset >= start_offset && offset < fp->_offset)
1058 _IO_setg (fp, fp->_IO_buf_base,
1059 fp->_IO_buf_base + (offset - start_offset),
1060 fp->_IO_read_end);
1061 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1063 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1064 goto resync;
1068 if (fp->_flags & _IO_NO_READS)
1069 goto dumb;
1071 /* Try to seek to a block boundary, to improve kernel page management. */
1072 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
1073 delta = offset - new_offset;
1074 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
1076 new_offset = offset;
1077 delta = 0;
1079 result = _IO_SYSSEEK (fp, new_offset, 0);
1080 if (result < 0)
1081 return EOF;
1082 if (delta == 0)
1083 count = 0;
1084 else
1086 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
1087 (must_be_exact
1088 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
1089 if (count < delta)
1091 /* We weren't allowed to read, but try to seek the remainder. */
1092 offset = count == EOF ? delta : delta-count;
1093 dir = _IO_seek_cur;
1094 goto dumb;
1097 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
1098 fp->_IO_buf_base + count);
1099 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1100 fp->_offset = result + count;
1101 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1102 return offset;
1103 dumb:
1105 _IO_unsave_markers (fp);
1106 result = _IO_SYSSEEK (fp, offset, dir);
1107 if (result != EOF)
1109 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1110 fp->_offset = result;
1111 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1112 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1114 return result;
1116 resync:
1117 /* We need to do it since it is possible that the file offset in
1118 the kernel may be changed behind our back. It may happen when
1119 we fopen a file and then do a fork. One process may access the
1120 file and the kernel file offset will be changed. */
1121 if (fp->_offset >= 0)
1122 _IO_SYSSEEK (fp, fp->_offset, 0);
1124 return offset;
1126 libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
1128 _IO_off64_t
1129 _IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
1131 _IO_off64_t result;
1133 /* If we are only interested in the current position, calculate it and
1134 return right now. This calculation does the right thing when we are
1135 using a pushback buffer, but in the usual case has the same value as
1136 (fp->_IO_read_ptr - fp->_IO_buf_base). */
1137 if (mode == 0)
1138 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
1140 switch (dir)
1142 case _IO_seek_cur:
1143 /* Adjust for read-ahead (bytes is buffer). */
1144 offset += fp->_IO_read_ptr - fp->_IO_read_base;
1145 break;
1146 case _IO_seek_set:
1147 break;
1148 case _IO_seek_end:
1149 offset += fp->_IO_buf_end - fp->_IO_buf_base;
1150 break;
1152 /* At this point, dir==_IO_seek_set. */
1154 if (offset < 0)
1156 /* No negative offsets are valid. */
1157 __set_errno (EINVAL);
1158 return EOF;
1161 result = _IO_SYSSEEK (fp, offset, 0);
1162 if (result < 0)
1163 return EOF;
1165 if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
1166 /* One can fseek arbitrarily past the end of the file
1167 and it is meaningless until one attempts to read.
1168 Leave the buffer pointers in EOF state until underflow. */
1169 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
1170 else
1171 /* Adjust the read pointers to match the file position,
1172 but so the next read attempt will call underflow. */
1173 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
1174 fp->_IO_buf_base + offset);
1176 fp->_offset = result;
1178 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1180 return offset;
1183 static _IO_off64_t
1184 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1185 int mode)
1187 /* We only get here when we haven't tried to read anything yet.
1188 So there is nothing more useful for us to do here than just
1189 the underlying lseek call. */
1191 _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir);
1192 if (result < 0)
1193 return EOF;
1195 fp->_offset = result;
1196 return result;
1199 _IO_ssize_t
1200 _IO_file_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
1202 return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
1203 ? read_not_cancel (fp->_fileno, buf, size)
1204 : read (fp->_fileno, buf, size));
1206 libc_hidden_def (_IO_file_read)
1208 _IO_off64_t
1209 _IO_file_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1211 return __lseek64 (fp->_fileno, offset, dir);
1213 libc_hidden_def (_IO_file_seek)
1216 _IO_file_stat (_IO_FILE *fp, void *st)
1218 return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st);
1220 libc_hidden_def (_IO_file_stat)
1223 _IO_file_close_mmap (_IO_FILE *fp)
1225 /* In addition to closing the file descriptor we have to unmap the file. */
1226 (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
1227 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
1228 /* Cancelling close should be avoided if possible since it leaves an
1229 unrecoverable state behind. */
1230 return close_not_cancel (fp->_fileno);
1234 _IO_file_close (_IO_FILE *fp)
1236 /* Cancelling close should be avoided if possible since it leaves an
1237 unrecoverable state behind. */
1238 return close_not_cancel (fp->_fileno);
1240 libc_hidden_def (_IO_file_close)
1242 _IO_ssize_t
1243 _IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n)
1245 _IO_ssize_t to_do = n;
1246 while (to_do > 0)
1248 _IO_ssize_t count = (__builtin_expect (f->_flags2
1249 & _IO_FLAGS2_NOTCANCEL, 0)
1250 ? write_not_cancel (f->_fileno, data, to_do)
1251 : write (f->_fileno, data, to_do));
1252 if (count < 0)
1254 f->_flags |= _IO_ERR_SEEN;
1255 break;
1257 to_do -= count;
1258 data = (void *) ((char *) data + count);
1260 n -= to_do;
1261 if (f->_offset >= 0)
1262 f->_offset += n;
1263 return n;
1266 _IO_size_t
1267 _IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
1269 const char *s = (const char *) data;
1270 _IO_size_t to_do = n;
1271 int must_flush = 0;
1272 _IO_size_t count = 0;
1274 if (n <= 0)
1275 return 0;
1276 /* This is an optimized implementation.
1277 If the amount to be written straddles a block boundary
1278 (or the filebuf is unbuffered), use sys_write directly. */
1280 /* First figure out how much space is available in the buffer. */
1281 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1283 count = f->_IO_buf_end - f->_IO_write_ptr;
1284 if (count >= n)
1286 const char *p;
1287 for (p = s + n; p > s; )
1289 if (*--p == '\n')
1291 count = p - s + 1;
1292 must_flush = 1;
1293 break;
1298 else if (f->_IO_write_end > f->_IO_write_ptr)
1299 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1301 /* Then fill the buffer. */
1302 if (count > 0)
1304 if (count > to_do)
1305 count = to_do;
1306 #ifdef _LIBC
1307 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1308 #else
1309 memcpy (f->_IO_write_ptr, s, count);
1310 f->_IO_write_ptr += count;
1311 #endif
1312 s += count;
1313 to_do -= count;
1315 if (to_do + must_flush > 0)
1317 _IO_size_t block_size, do_write;
1318 /* Next flush the (full) buffer. */
1319 if (_IO_OVERFLOW (f, EOF) == EOF)
1320 /* If nothing else has to be written we must not signal the
1321 caller that everything has been written. */
1322 return to_do == 0 ? EOF : n - to_do;
1324 /* Try to maintain alignment: write a whole number of blocks. */
1325 block_size = f->_IO_buf_end - f->_IO_buf_base;
1326 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
1328 if (do_write)
1330 count = new_do_write (f, s, do_write);
1331 to_do -= count;
1332 if (count < do_write)
1333 return n - to_do;
1336 /* Now write out the remainder. Normally, this will fit in the
1337 buffer, but it's somewhat messier for line-buffered files,
1338 so we let _IO_default_xsputn handle the general case. */
1339 if (to_do)
1340 to_do -= _IO_default_xsputn (f, s+do_write, to_do);
1342 return n - to_do;
1344 libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
1346 _IO_size_t
1347 _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
1349 _IO_size_t want, have;
1350 _IO_ssize_t count;
1351 char *s = data;
1353 want = n;
1355 if (fp->_IO_buf_base == NULL)
1357 /* Maybe we already have a push back pointer. */
1358 if (fp->_IO_save_base != NULL)
1360 free (fp->_IO_save_base);
1361 fp->_flags &= ~_IO_IN_BACKUP;
1363 _IO_doallocbuf (fp);
1366 while (want > 0)
1368 have = fp->_IO_read_end - fp->_IO_read_ptr;
1369 if (want <= have)
1371 memcpy (s, fp->_IO_read_ptr, want);
1372 fp->_IO_read_ptr += want;
1373 want = 0;
1375 else
1377 if (have > 0)
1379 #ifdef _LIBC
1380 s = __mempcpy (s, fp->_IO_read_ptr, have);
1381 #else
1382 memcpy (s, fp->_IO_read_ptr, have);
1383 s += have;
1384 #endif
1385 want -= have;
1386 fp->_IO_read_ptr += have;
1389 /* Check for backup and repeat */
1390 if (_IO_in_backup (fp))
1392 _IO_switch_to_main_get_area (fp);
1393 continue;
1396 /* If we now want less than a buffer, underflow and repeat
1397 the copy. Otherwise, _IO_SYSREAD directly to
1398 the user buffer. */
1399 if (fp->_IO_buf_base
1400 && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
1402 if (__underflow (fp) == EOF)
1403 break;
1405 continue;
1408 /* These must be set before the sysread as we might longjmp out
1409 waiting for input. */
1410 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1411 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1413 /* Try to maintain alignment: read a whole number of blocks. */
1414 count = want;
1415 if (fp->_IO_buf_base)
1417 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1418 if (block_size >= 128)
1419 count -= want % block_size;
1422 count = _IO_SYSREAD (fp, s, count);
1423 if (count <= 0)
1425 if (count == 0)
1426 fp->_flags |= _IO_EOF_SEEN;
1427 else
1428 fp->_flags |= _IO_ERR_SEEN;
1430 break;
1433 s += count;
1434 want -= count;
1435 if (fp->_offset != _IO_pos_BAD)
1436 _IO_pos_adjust (fp->_offset, count);
1440 return n - want;
1442 libc_hidden_def (_IO_file_xsgetn)
1444 static _IO_size_t
1445 _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
1447 _IO_size_t have;
1448 char *read_ptr = fp->_IO_read_ptr;
1449 char *s = (char *) data;
1451 have = fp->_IO_read_end - fp->_IO_read_ptr;
1453 if (have < n)
1455 if (__glibc_unlikely (_IO_in_backup (fp)))
1457 #ifdef _LIBC
1458 s = __mempcpy (s, read_ptr, have);
1459 #else
1460 memcpy (s, read_ptr, have);
1461 s += have;
1462 #endif
1463 n -= have;
1464 _IO_switch_to_main_get_area (fp);
1465 read_ptr = fp->_IO_read_ptr;
1466 have = fp->_IO_read_end - fp->_IO_read_ptr;
1469 if (have < n)
1471 /* Check that we are mapping all of the file, in case it grew. */
1472 if (__glibc_unlikely (mmap_remap_check (fp)))
1473 /* We punted mmap, so complete with the vanilla code. */
1474 return s - (char *) data + _IO_XSGETN (fp, data, n);
1476 read_ptr = fp->_IO_read_ptr;
1477 have = fp->_IO_read_end - read_ptr;
1481 if (have < n)
1482 fp->_flags |= _IO_EOF_SEEN;
1484 if (have != 0)
1486 have = MIN (have, n);
1487 #ifdef _LIBC
1488 s = __mempcpy (s, read_ptr, have);
1489 #else
1490 memcpy (s, read_ptr, have);
1491 s += have;
1492 #endif
1493 fp->_IO_read_ptr = read_ptr + have;
1496 return s - (char *) data;
1499 static _IO_size_t
1500 _IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
1502 /* We only get here if this is the first attempt to read something.
1503 Decide which operations to use and then punt to the chosen one. */
1505 decide_maybe_mmap (fp);
1506 return _IO_XSGETN (fp, data, n);
1509 #ifdef _LIBC
1510 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1511 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1512 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1513 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1514 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1515 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1516 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1517 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1518 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1519 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1520 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1521 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1522 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1523 #endif
1525 const struct _IO_jump_t _IO_file_jumps =
1527 JUMP_INIT_DUMMY,
1528 JUMP_INIT(finish, _IO_file_finish),
1529 JUMP_INIT(overflow, _IO_file_overflow),
1530 JUMP_INIT(underflow, _IO_file_underflow),
1531 JUMP_INIT(uflow, _IO_default_uflow),
1532 JUMP_INIT(pbackfail, _IO_default_pbackfail),
1533 JUMP_INIT(xsputn, _IO_file_xsputn),
1534 JUMP_INIT(xsgetn, _IO_file_xsgetn),
1535 JUMP_INIT(seekoff, _IO_new_file_seekoff),
1536 JUMP_INIT(seekpos, _IO_default_seekpos),
1537 JUMP_INIT(setbuf, _IO_new_file_setbuf),
1538 JUMP_INIT(sync, _IO_new_file_sync),
1539 JUMP_INIT(doallocate, _IO_file_doallocate),
1540 JUMP_INIT(read, _IO_file_read),
1541 JUMP_INIT(write, _IO_new_file_write),
1542 JUMP_INIT(seek, _IO_file_seek),
1543 JUMP_INIT(close, _IO_file_close),
1544 JUMP_INIT(stat, _IO_file_stat),
1545 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1546 JUMP_INIT(imbue, _IO_default_imbue)
1548 libc_hidden_data_def (_IO_file_jumps)
1550 const struct _IO_jump_t _IO_file_jumps_mmap =
1552 JUMP_INIT_DUMMY,
1553 JUMP_INIT(finish, _IO_file_finish),
1554 JUMP_INIT(overflow, _IO_file_overflow),
1555 JUMP_INIT(underflow, _IO_file_underflow_mmap),
1556 JUMP_INIT(uflow, _IO_default_uflow),
1557 JUMP_INIT(pbackfail, _IO_default_pbackfail),
1558 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1559 JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
1560 JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
1561 JUMP_INIT(seekpos, _IO_default_seekpos),
1562 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1563 JUMP_INIT(sync, _IO_file_sync_mmap),
1564 JUMP_INIT(doallocate, _IO_file_doallocate),
1565 JUMP_INIT(read, _IO_file_read),
1566 JUMP_INIT(write, _IO_new_file_write),
1567 JUMP_INIT(seek, _IO_file_seek),
1568 JUMP_INIT(close, _IO_file_close_mmap),
1569 JUMP_INIT(stat, _IO_file_stat),
1570 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1571 JUMP_INIT(imbue, _IO_default_imbue)
1574 const struct _IO_jump_t _IO_file_jumps_maybe_mmap =
1576 JUMP_INIT_DUMMY,
1577 JUMP_INIT(finish, _IO_file_finish),
1578 JUMP_INIT(overflow, _IO_file_overflow),
1579 JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
1580 JUMP_INIT(uflow, _IO_default_uflow),
1581 JUMP_INIT(pbackfail, _IO_default_pbackfail),
1582 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1583 JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
1584 JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
1585 JUMP_INIT(seekpos, _IO_default_seekpos),
1586 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1587 JUMP_INIT(sync, _IO_new_file_sync),
1588 JUMP_INIT(doallocate, _IO_file_doallocate),
1589 JUMP_INIT(read, _IO_file_read),
1590 JUMP_INIT(write, _IO_new_file_write),
1591 JUMP_INIT(seek, _IO_file_seek),
1592 JUMP_INIT(close, _IO_file_close),
1593 JUMP_INIT(stat, _IO_file_stat),
1594 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1595 JUMP_INIT(imbue, _IO_default_imbue)