libio: Fix variable aligment in tst-ftell-active-handler
[platform/upstream/glibc.git] / libio / fileops.c
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>.
4
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.
9
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.
14
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/>.
18
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.  */
27
28
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
56
57
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
78
79
80 #ifdef _LIBC
81 extern struct __gconv_trans_data __libio_translit attribute_hidden;
82 #endif
83
84
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.
87
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().
91
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(). (?)
99
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.
109
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().
114
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().
125
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.
132
133    UNBUFFERED STREAMS:
134    If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
135 */
136
137 #define CLOSED_FILEBUF_FLAGS \
138   (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
139
140
141 void
142 _IO_new_file_init (struct _IO_FILE_plus *fp)
143 {
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;
149
150   _IO_link_in (fp);
151   fp->file._fileno = -1;
152 }
153 libc_hidden_ver (_IO_new_file_init, _IO_file_init)
154
155 int
156 _IO_new_file_close_it (_IO_FILE *fp)
157 {
158   int write_status;
159   if (!_IO_file_is_open (fp))
160     return EOF;
161
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;
167
168   _IO_unsave_markers (fp);
169
170   int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0
171                       ? _IO_SYSCLOSE (fp) : 0);
172
173   /* Free buffer. */
174 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
175   if (fp->_mode > 0)
176     {
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);
182     }
183 #endif
184   _IO_setb (fp, NULL, NULL, 0);
185   _IO_setg (fp, NULL, NULL, NULL);
186   _IO_setp (fp, NULL, NULL);
187
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;
192
193   return close_status ? close_status : write_status;
194 }
195 libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it)
196
197 void
198 _IO_new_file_finish (_IO_FILE *fp, int dummy)
199 {
200   if (_IO_file_is_open (fp))
201     {
202       _IO_do_flush (fp);
203       if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
204         _IO_SYSCLOSE (fp);
205     }
206   _IO_default_finish (fp, 0);
207 }
208 libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
209
210 _IO_FILE *
211 _IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot,
212                int read_write, int is32not64)
213 {
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))
232     {
233       _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end);
234       if (new_pos == _IO_pos_BAD && errno != ESPIPE)
235         {
236           close_not_cancel (fdesc);
237           return NULL;
238         }
239     }
240   _IO_link_in ((struct _IO_FILE_plus *) fp);
241   return fp;
242 }
243 libc_hidden_def (_IO_file_open)
244
245 _IO_FILE *
246 _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
247                     int is32not64)
248 {
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
258
259   if (_IO_file_is_open (fp))
260     return 0;
261   switch (*mode)
262     {
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;
280     }
281 #ifdef _LIBC
282   last_recognized = mode;
283 #endif
284   for (i = 1; i < 7; ++i)
285     {
286       switch (*++mode)
287         {
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;
323         }
324       break;
325     }
326
327   result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
328                           is32not64);
329
330   if (result != NULL)
331     {
332 #ifndef __ASSUME_O_CLOEXEC
333       if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0)
334         {
335           int fd = _IO_fileno (fp);
336           if (__have_o_cloexec == 0)
337             {
338               int flags = __fcntl (fd, F_GETFD);
339               __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
340             }
341           if (__have_o_cloexec < 0)
342             __fcntl (fd, F_SETFD, FD_CLOEXEC);
343         }
344 #endif
345
346       /* Test whether the mode string specifies the conversion.  */
347       cs = strstr (last_recognized + 1, ",ccs=");
348       if (cs != NULL)
349         {
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];
356
357           *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
358           strip (ccs, ccs);
359
360           if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
361                                    ? upstr (ccs, cs + 5) : ccs) != 0)
362             {
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;
369             }
370
371           assert (fcts.towc_nsteps == 1);
372           assert (fcts.tomb_nsteps == 1);
373
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;
376
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));
380
381           cc = fp->_codecvt = &fp->_wide_data->_codecvt;
382
383           /* The functions are always the same.  */
384           *cc = __libio_codecvt;
385
386           cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
387           cc->__cd_in.__cd.__steps = fcts.towc;
388
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;
393
394           cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
395           cc->__cd_out.__cd.__steps = fcts.tomb;
396
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;
403
404           /* From now on use the wide character callback functions.  */
405           ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
406
407           /* Set the mode now.  */
408           result->_mode = 1;
409         }
410     }
411
412   return result;
413 }
414 libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
415
416 _IO_FILE *
417 _IO_new_file_attach (_IO_FILE *fp, int fd)
418 {
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;
433 }
434 libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
435
436 _IO_FILE *
437 _IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
438 {
439   if (_IO_default_setbuf (fp, p, len) == NULL)
440     return NULL;
441
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);
445
446   return fp;
447 }
448 libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
449
450
451 _IO_FILE *
452 _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
453 {
454   _IO_FILE *result;
455
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;
459
460   /* And perform the normal operation.  */
461   result = _IO_new_file_setbuf (fp, p, len);
462
463   /* If the call failed, restore to using mmap.  */
464   if (result == NULL)
465     {
466       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
467       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
468     }
469
470   return result;
471 }
472
473 static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
474
475 /* Write TO_DO bytes from DATA to FP.
476    Then mark FP as having empty buffers. */
477
478 int
479 _IO_new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
480 {
481   return (to_do == 0
482           || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
483 }
484 libc_hidden_ver (_IO_new_do_write, _IO_do_write)
485
486 static
487 _IO_size_t
488 new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do)
489 {
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)
499     {
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;
505     }
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;
515 }
516
517 int
518 _IO_new_file_underflow (_IO_FILE *fp)
519 {
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
526
527   if (fp->_flags & _IO_NO_READS)
528     {
529       fp->_flags |= _IO_ERR_SEEN;
530       __set_errno (EBADF);
531       return EOF;
532     }
533   if (fp->_IO_read_ptr < fp->_IO_read_end)
534     return *(unsigned char *) fp->_IO_read_ptr;
535
536   if (fp->_IO_buf_base == NULL)
537     {
538       /* Maybe we already have a push back pointer.  */
539       if (fp->_IO_save_base != NULL)
540         {
541           free (fp->_IO_save_base);
542           fp->_flags &= ~_IO_IN_BACKUP;
543         }
544       _IO_doallocbuf (fp);
545     }
546
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))
550     {
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);
560
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);
564
565       _IO_release_lock (_IO_stdout);
566 #endif
567     }
568
569   _IO_switch_to_get_mode (fp);
570
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;
579
580   count = _IO_SYSREAD (fp, fp->_IO_buf_base,
581                        fp->_IO_buf_end - fp->_IO_buf_base);
582   if (count <= 0)
583     {
584       if (count == 0)
585         fp->_flags |= _IO_EOF_SEEN;
586       else
587         fp->_flags |= _IO_ERR_SEEN, count = 0;
588   }
589   fp->_IO_read_end += count;
590   if (count == 0)
591     {
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;
597     }
598   if (fp->_offset != _IO_pos_BAD)
599     _IO_pos_adjust (fp->_offset, count);
600   return *(unsigned char *) fp->_IO_read_ptr;
601 }
602 libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
603
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)
610 {
611   struct stat64 st;
612
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))
617     {
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))
622         {
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;
628         }
629       else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
630                                                - fp->_IO_buf_base))
631         {
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)
639             {
640               (void) __munmap (fp->_IO_buf_base,
641                                fp->_IO_buf_end - fp->_IO_buf_base);
642               goto punt;
643             }
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;
654         }
655       else
656         {
657           /* The number of pages didn't change.  */
658           fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
659         }
660 # undef ROUNDED
661
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);
667
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.  */
672
673       if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
674         {
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;
681         }
682
683       return 0;
684     }
685   else
686     {
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;
698
699       return 1;
700     }
701 }
702
703 /* Special callback replacing the underflow callbacks if we mmap the file.  */
704 int
705 _IO_file_underflow_mmap (_IO_FILE *fp)
706 {
707   if (fp->_IO_read_ptr < fp->_IO_read_end)
708     return *(unsigned char *) fp->_IO_read_ptr;
709
710   if (__glibc_unlikely (mmap_remap_check (fp)))
711     /* We punted to the regular file functions.  */
712     return _IO_UNDERFLOW (fp);
713
714   if (fp->_IO_read_ptr < fp->_IO_read_end)
715     return *(unsigned char *) fp->_IO_read_ptr;
716
717   fp->_flags |= _IO_EOF_SEEN;
718   return EOF;
719 }
720
721 static void
722 decide_maybe_mmap (_IO_FILE *fp)
723 {
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;
730
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))
737     {
738       /* Try to map the file.  */
739       void *p;
740
741       p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
742       if (p != MAP_FAILED)
743         {
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.  */
747
748           if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
749             {
750               (void) __munmap (p, st.st_size);
751               fp->_offset = _IO_pos_BAD;
752             }
753           else
754             {
755               _IO_setb (fp, p, (char *) p + st.st_size, 0);
756
757               if (fp->_offset == _IO_pos_BAD)
758                 fp->_offset = 0;
759
760               _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
761               fp->_offset = st.st_size;
762
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;
768
769               return;
770             }
771         }
772     }
773
774   /* We couldn't use mmap, so revert to the vanilla file operations.  */
775
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;
781 }
782
783 int
784 _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
785 {
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);
790 }
791
792
793 int
794 _IO_new_file_overflow (_IO_FILE *f, int ch)
795 {
796   if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
797     {
798       f->_flags |= _IO_ERR_SEEN;
799       __set_errno (EBADF);
800       return EOF;
801     }
802   /* If currently reading or no buffer allocated. */
803   if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
804     {
805       /* Allocate a buffer if needed. */
806       if (f->_IO_write_base == NULL)
807         {
808           _IO_doallocbuf (f);
809           _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
810         }
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)))
819         {
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;
825         }
826
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;
833
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;
837     }
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;
851 }
852 libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow)
853
854 int
855 _IO_new_file_sync (_IO_FILE *fp)
856 {
857   _IO_ssize_t delta;
858   int retval = 0;
859
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)
865     {
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;
879     }
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;
885 }
886 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
887
888 static int
889 _IO_file_sync_mmap (_IO_FILE *fp)
890 {
891   if (fp->_IO_read_ptr != fp->_IO_read_end)
892     {
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)
900         {
901           fp->_flags |= _IO_ERR_SEEN;
902           return EOF;
903         }
904     }
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;
908 }
909
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)
915 {
916   _IO_off64_t result, offset = 0;
917
918   /* No point looking at unflushed data if we haven't allocated buffers
919      yet.  */
920   if (fp->_IO_buf_base != NULL)
921     {
922       bool unflushed_writes = fp->_IO_write_ptr > fp->_IO_write_base;
923
924       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
925
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)
930         {
931           result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
932           if (result == _IO_pos_BAD)
933             return EOF;
934           else
935             fp->_offset = result;
936         }
937
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;
951     }
952
953   if (fp->_offset != _IO_pos_BAD)
954     result = fp->_offset;
955   else
956     result = _IO_SYSSEEK (fp, 0, _IO_seek_cur);
957
958   if (result == EOF)
959     return result;
960
961   result += offset;
962
963   if (result < 0)
964     {
965       __set_errno (EINVAL);
966       return EOF;
967     }
968
969   return result;
970 }
971
972 _IO_off64_t
973 _IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
974 {
975   _IO_off64_t result;
976   _IO_off64_t delta, new_offset;
977   long count;
978
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);
984
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);
989
990   bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
991                       || _IO_in_put_mode (fp));
992
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;
1002
1003   if (fp->_IO_buf_base == NULL)
1004     {
1005       /* It could be that we already have a pushback buffer.  */
1006       if (fp->_IO_read_base != NULL)
1007         {
1008           free (fp->_IO_read_base);
1009           fp->_flags &= ~_IO_IN_BACKUP;
1010         }
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);
1014     }
1015
1016   switch (dir)
1017     {
1018     case _IO_seek_cur:
1019       /* Adjust for read-ahead (bytes is buffer). */
1020       offset -= fp->_IO_read_end - fp->_IO_read_ptr;
1021
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)
1027         {
1028           __set_errno (EINVAL);
1029           return EOF;
1030         }
1031
1032       dir = _IO_seek_set;
1033       break;
1034     case _IO_seek_set:
1035       break;
1036     case _IO_seek_end:
1037       {
1038         struct stat64 st;
1039         if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1040           {
1041             offset += st.st_size;
1042             dir = _IO_seek_set;
1043           }
1044         else
1045           goto dumb;
1046       }
1047     }
1048   /* At this point, dir==_IO_seek_set. */
1049
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))
1053     {
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)
1057         {
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);
1062
1063           _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1064           goto resync;
1065         }
1066     }
1067
1068   if (fp->_flags & _IO_NO_READS)
1069     goto dumb;
1070
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)
1075     {
1076       new_offset = offset;
1077       delta = 0;
1078     }
1079   result = _IO_SYSSEEK (fp, new_offset, 0);
1080   if (result < 0)
1081     return EOF;
1082   if (delta == 0)
1083     count = 0;
1084   else
1085     {
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)
1090         {
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;
1095         }
1096     }
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:
1104
1105   _IO_unsave_markers (fp);
1106   result = _IO_SYSSEEK (fp, offset, dir);
1107   if (result != EOF)
1108     {
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);
1113     }
1114   return result;
1115
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);
1123
1124   return offset;
1125 }
1126 libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
1127
1128 _IO_off64_t
1129 _IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
1130 {
1131   _IO_off64_t result;
1132
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);
1139
1140   switch (dir)
1141     {
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;
1151     }
1152   /* At this point, dir==_IO_seek_set. */
1153
1154   if (offset < 0)
1155     {
1156       /* No negative offsets are valid.  */
1157       __set_errno (EINVAL);
1158       return EOF;
1159     }
1160
1161   result = _IO_SYSSEEK (fp, offset, 0);
1162   if (result < 0)
1163     return EOF;
1164
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);
1175
1176   fp->_offset = result;
1177
1178   _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1179
1180   return offset;
1181 }
1182
1183 static _IO_off64_t
1184 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1185                              int mode)
1186 {
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.  */
1190
1191   _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir);
1192   if (result < 0)
1193     return EOF;
1194
1195   fp->_offset = result;
1196   return result;
1197 }
1198
1199 _IO_ssize_t
1200 _IO_file_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
1201 {
1202   return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
1203           ? read_not_cancel (fp->_fileno, buf, size)
1204           : read (fp->_fileno, buf, size));
1205 }
1206 libc_hidden_def (_IO_file_read)
1207
1208 _IO_off64_t
1209 _IO_file_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1210 {
1211   return __lseek64 (fp->_fileno, offset, dir);
1212 }
1213 libc_hidden_def (_IO_file_seek)
1214
1215 int
1216 _IO_file_stat (_IO_FILE *fp, void *st)
1217 {
1218   return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st);
1219 }
1220 libc_hidden_def (_IO_file_stat)
1221
1222 int
1223 _IO_file_close_mmap (_IO_FILE *fp)
1224 {
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);
1231 }
1232
1233 int
1234 _IO_file_close (_IO_FILE *fp)
1235 {
1236   /* Cancelling close should be avoided if possible since it leaves an
1237      unrecoverable state behind.  */
1238   return close_not_cancel (fp->_fileno);
1239 }
1240 libc_hidden_def (_IO_file_close)
1241
1242 _IO_ssize_t
1243 _IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n)
1244 {
1245   _IO_ssize_t to_do = n;
1246   while (to_do > 0)
1247     {
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)
1253         {
1254           f->_flags |= _IO_ERR_SEEN;
1255           break;
1256         }
1257       to_do -= count;
1258       data = (void *) ((char *) data + count);
1259     }
1260   n -= to_do;
1261   if (f->_offset >= 0)
1262     f->_offset += n;
1263   return n;
1264 }
1265
1266 _IO_size_t
1267 _IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
1268 {
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;
1273
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. */
1279
1280   /* First figure out how much space is available in the buffer. */
1281   if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1282     {
1283       count = f->_IO_buf_end - f->_IO_write_ptr;
1284       if (count >= n)
1285         {
1286           const char *p;
1287           for (p = s + n; p > s; )
1288             {
1289               if (*--p == '\n')
1290                 {
1291                   count = p - s + 1;
1292                   must_flush = 1;
1293                   break;
1294                 }
1295             }
1296         }
1297     }
1298   else if (f->_IO_write_end > f->_IO_write_ptr)
1299     count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1300
1301   /* Then fill the buffer. */
1302   if (count > 0)
1303     {
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;
1314     }
1315   if (to_do + must_flush > 0)
1316     {
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;
1323
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);
1327
1328       if (do_write)
1329         {
1330           count = new_do_write (f, s, do_write);
1331           to_do -= count;
1332           if (count < do_write)
1333             return n - to_do;
1334         }
1335
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);
1341     }
1342   return n - to_do;
1343 }
1344 libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
1345
1346 _IO_size_t
1347 _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
1348 {
1349   _IO_size_t want, have;
1350   _IO_ssize_t count;
1351   char *s = data;
1352
1353   want = n;
1354
1355   if (fp->_IO_buf_base == NULL)
1356     {
1357       /* Maybe we already have a push back pointer.  */
1358       if (fp->_IO_save_base != NULL)
1359         {
1360           free (fp->_IO_save_base);
1361           fp->_flags &= ~_IO_IN_BACKUP;
1362         }
1363       _IO_doallocbuf (fp);
1364     }
1365
1366   while (want > 0)
1367     {
1368       have = fp->_IO_read_end - fp->_IO_read_ptr;
1369       if (want <= have)
1370         {
1371           memcpy (s, fp->_IO_read_ptr, want);
1372           fp->_IO_read_ptr += want;
1373           want = 0;
1374         }
1375       else
1376         {
1377           if (have > 0)
1378             {
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;
1387             }
1388
1389           /* Check for backup and repeat */
1390           if (_IO_in_backup (fp))
1391             {
1392               _IO_switch_to_main_get_area (fp);
1393               continue;
1394             }
1395
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))
1401             {
1402               if (__underflow (fp) == EOF)
1403                 break;
1404
1405               continue;
1406             }
1407
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);
1412
1413           /* Try to maintain alignment: read a whole number of blocks.  */
1414           count = want;
1415           if (fp->_IO_buf_base)
1416             {
1417               _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1418               if (block_size >= 128)
1419                 count -= want % block_size;
1420             }
1421
1422           count = _IO_SYSREAD (fp, s, count);
1423           if (count <= 0)
1424             {
1425               if (count == 0)
1426                 fp->_flags |= _IO_EOF_SEEN;
1427               else
1428                 fp->_flags |= _IO_ERR_SEEN;
1429
1430               break;
1431             }
1432
1433           s += count;
1434           want -= count;
1435           if (fp->_offset != _IO_pos_BAD)
1436             _IO_pos_adjust (fp->_offset, count);
1437         }
1438     }
1439
1440   return n - want;
1441 }
1442 libc_hidden_def (_IO_file_xsgetn)
1443
1444 static _IO_size_t
1445 _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
1446 {
1447   _IO_size_t have;
1448   char *read_ptr = fp->_IO_read_ptr;
1449   char *s = (char *) data;
1450
1451   have = fp->_IO_read_end - fp->_IO_read_ptr;
1452
1453   if (have < n)
1454     {
1455       if (__glibc_unlikely (_IO_in_backup (fp)))
1456         {
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;
1467         }
1468
1469       if (have < n)
1470         {
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);
1475
1476           read_ptr = fp->_IO_read_ptr;
1477           have = fp->_IO_read_end - read_ptr;
1478         }
1479     }
1480
1481   if (have < n)
1482     fp->_flags |= _IO_EOF_SEEN;
1483
1484   if (have != 0)
1485     {
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;
1494     }
1495
1496   return s - (char *) data;
1497 }
1498
1499 static _IO_size_t
1500 _IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
1501 {
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.  */
1504
1505   decide_maybe_mmap (fp);
1506   return _IO_XSGETN (fp, data, n);
1507 }
1508
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
1524
1525 const struct _IO_jump_t _IO_file_jumps =
1526 {
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)
1547 };
1548 libc_hidden_data_def (_IO_file_jumps)
1549
1550 const struct _IO_jump_t _IO_file_jumps_mmap =
1551 {
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)
1572 };
1573
1574 const struct _IO_jump_t _IO_file_jumps_maybe_mmap =
1575 {
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)
1596 };