Setup LOCPATH for tst-ftell-active-handler and tst-ftell-partial-wide in libio
[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.
95    If the field _fb._offset is >= 0, it gives the offset in
96    the file as a whole corresponding to eGptr(). (?)
97
98    PUT MODE:
99    If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
100    and _IO_read_base are equal to each other.  These are usually equal
101    to _IO_buf_base, though not necessarily if we have switched from
102    get mode to put mode.  (The reason is to maintain the invariant
103    that _IO_read_end corresponds to the external file position.)
104    _IO_write_base is non-NULL and usually equal to _IO_buf_base.
105    We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
106    The un-flushed character are those between _IO_write_base and _IO_write_ptr.
107
108    GET MODE:
109    If a filebuf is in get or putback mode, eback() != egptr().
110    In get mode, the unread characters are between gptr() and egptr().
111    The OS file position corresponds to that of egptr().
112
113    PUTBACK MODE:
114    Putback mode is used to remember "excess" characters that have
115    been sputbackc'd in a separate putback buffer.
116    In putback mode, the get buffer points to the special putback buffer.
117    The unread characters are the characters between gptr() and egptr()
118    in the putback buffer, as well as the area between save_gptr()
119    and save_egptr(), which point into the original reserve buffer.
120    (The pointers save_gptr() and save_egptr() are the values
121    of gptr() and egptr() at the time putback mode was entered.)
122    The OS position corresponds to that of save_egptr().
123
124    LINE BUFFERED OUTPUT:
125    During line buffered output, _IO_write_base==base() && epptr()==base().
126    However, ptr() may be anywhere between base() and ebuf().
127    This forces a call to filebuf::overflow(int C) on every put.
128    If there is more space in the buffer, and C is not a '\n',
129    then C is inserted, and pptr() incremented.
130
131    UNBUFFERED STREAMS:
132    If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
133 */
134
135 #define CLOSED_FILEBUF_FLAGS \
136   (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
137
138
139 void
140 _IO_new_file_init (fp)
141      struct _IO_FILE_plus *fp;
142 {
143   /* POSIX.1 allows another file handle to be used to change the position
144      of our file descriptor.  Hence we actually don't know the actual
145      position before we do the first fseek (and until a following fflush). */
146   fp->file._offset = _IO_pos_BAD;
147   fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
148
149   _IO_link_in (fp);
150   fp->file._fileno = -1;
151 }
152 libc_hidden_ver (_IO_new_file_init, _IO_file_init)
153
154 int
155 _IO_new_file_close_it (fp)
156      _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 (fp, dummy)
199      _IO_FILE *fp;
200      int dummy;
201 {
202   if (_IO_file_is_open (fp))
203     {
204       _IO_do_flush (fp);
205       if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
206         _IO_SYSCLOSE (fp);
207     }
208   _IO_default_finish (fp, 0);
209 }
210 libc_hidden_ver (_IO_new_file_finish, _IO_file_finish)
211
212 _IO_FILE *
213 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
214      _IO_FILE *fp;
215      const char *filename;
216      int posix_mode;
217      int prot;
218      int read_write;
219      int is32not64;
220 {
221   int fdesc;
222 #ifdef _LIBC
223   if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
224     fdesc = open_not_cancel (filename,
225                              posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
226   else
227     fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
228 #else
229   fdesc = open (filename, posix_mode, prot);
230 #endif
231   if (fdesc < 0)
232     return NULL;
233   fp->_fileno = fdesc;
234   _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
235   /* For append mode, send the file offset to the end of the file.  Don't
236      update the offset cache though, since the file handle is not active.  */
237   if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS))
238       == (_IO_IS_APPENDING | _IO_NO_READS))
239     {
240       _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end);
241       if (new_pos == _IO_pos_BAD && errno != ESPIPE)
242         {
243           close_not_cancel (fdesc);
244           return NULL;
245         }
246     }
247   _IO_link_in ((struct _IO_FILE_plus *) fp);
248   return fp;
249 }
250 libc_hidden_def (_IO_file_open)
251
252 _IO_FILE *
253 _IO_new_file_fopen (fp, filename, mode, is32not64)
254      _IO_FILE *fp;
255      const char *filename;
256      const char *mode;
257      int is32not64;
258 {
259   int oflags = 0, omode;
260   int read_write;
261   int oprot = 0666;
262   int i;
263   _IO_FILE *result;
264 #ifdef _LIBC
265   const char *cs;
266   const char *last_recognized;
267 #endif
268
269   if (_IO_file_is_open (fp))
270     return 0;
271   switch (*mode)
272     {
273     case 'r':
274       omode = O_RDONLY;
275       read_write = _IO_NO_WRITES;
276       break;
277     case 'w':
278       omode = O_WRONLY;
279       oflags = O_CREAT|O_TRUNC;
280       read_write = _IO_NO_READS;
281       break;
282     case 'a':
283       omode = O_WRONLY;
284       oflags = O_CREAT|O_APPEND;
285       read_write = _IO_NO_READS|_IO_IS_APPENDING;
286       break;
287     default:
288       __set_errno (EINVAL);
289       return NULL;
290     }
291 #ifdef _LIBC
292   last_recognized = mode;
293 #endif
294   for (i = 1; i < 7; ++i)
295     {
296       switch (*++mode)
297         {
298         case '\0':
299           break;
300         case '+':
301           omode = O_RDWR;
302           read_write &= _IO_IS_APPENDING;
303 #ifdef _LIBC
304           last_recognized = mode;
305 #endif
306           continue;
307         case 'x':
308           oflags |= O_EXCL;
309 #ifdef _LIBC
310           last_recognized = mode;
311 #endif
312           continue;
313         case 'b':
314 #ifdef _LIBC
315           last_recognized = mode;
316 #endif
317           continue;
318         case 'm':
319           fp->_flags2 |= _IO_FLAGS2_MMAP;
320           continue;
321         case 'c':
322           fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
323           continue;
324         case 'e':
325 #ifdef O_CLOEXEC
326           oflags |= O_CLOEXEC;
327 #endif
328           fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
329           continue;
330         default:
331           /* Ignore.  */
332           continue;
333         }
334       break;
335     }
336
337   result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
338                           is32not64);
339
340   if (result != NULL)
341     {
342 #ifndef __ASSUME_O_CLOEXEC
343       if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0)
344         {
345           int fd = _IO_fileno (fp);
346           if (__have_o_cloexec == 0)
347             {
348               int flags = __fcntl (fd, F_GETFD);
349               __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
350             }
351           if (__have_o_cloexec < 0)
352             __fcntl (fd, F_SETFD, FD_CLOEXEC);
353         }
354 #endif
355
356       /* Test whether the mode string specifies the conversion.  */
357       cs = strstr (last_recognized + 1, ",ccs=");
358       if (cs != NULL)
359         {
360           /* Yep.  Load the appropriate conversions and set the orientation
361              to wide.  */
362           struct gconv_fcts fcts;
363           struct _IO_codecvt *cc;
364           char *endp = __strchrnul (cs + 5, ',');
365           char ccs[endp - (cs + 5) + 3];
366
367           *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
368           strip (ccs, ccs);
369
370           if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
371                                    ? upstr (ccs, cs + 5) : ccs) != 0)
372             {
373               /* Something went wrong, we cannot load the conversion modules.
374                  This means we cannot proceed since the user explicitly asked
375                  for these.  */
376               (void) _IO_file_close_it (fp);
377               __set_errno (EINVAL);
378               return NULL;
379             }
380
381           assert (fcts.towc_nsteps == 1);
382           assert (fcts.tomb_nsteps == 1);
383
384           fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
385           fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
386
387           /* Clear the state.  We start all over again.  */
388           memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
389           memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
390
391           cc = fp->_codecvt = &fp->_wide_data->_codecvt;
392
393           /* The functions are always the same.  */
394           *cc = __libio_codecvt;
395
396           cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
397           cc->__cd_in.__cd.__steps = fcts.towc;
398
399           cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
400           cc->__cd_in.__cd.__data[0].__internal_use = 1;
401           cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
402           cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
403
404           /* XXX For now no transliteration.  */
405           cc->__cd_in.__cd.__data[0].__trans = NULL;
406
407           cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
408           cc->__cd_out.__cd.__steps = fcts.tomb;
409
410           cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
411           cc->__cd_out.__cd.__data[0].__internal_use = 1;
412           cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
413           cc->__cd_out.__cd.__data[0].__statep =
414             &result->_wide_data->_IO_state;
415
416           /* And now the transliteration.  */
417           cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
418
419           /* From now on use the wide character callback functions.  */
420           ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
421
422           /* Set the mode now.  */
423           result->_mode = 1;
424         }
425     }
426
427   return result;
428 }
429 libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen)
430
431 _IO_FILE *
432 _IO_new_file_attach (fp, fd)
433      _IO_FILE *fp;
434      int fd;
435 {
436   if (_IO_file_is_open (fp))
437     return NULL;
438   fp->_fileno = fd;
439   fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
440   fp->_flags |= _IO_DELETE_DONT_CLOSE;
441   /* Get the current position of the file. */
442   /* We have to do that since that may be junk. */
443   fp->_offset = _IO_pos_BAD;
444   int save_errno = errno;
445   if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
446       == _IO_pos_BAD && errno != ESPIPE)
447     return NULL;
448   __set_errno (save_errno);
449   return fp;
450 }
451 libc_hidden_ver (_IO_new_file_attach, _IO_file_attach)
452
453 _IO_FILE *
454 _IO_new_file_setbuf (fp, p, len)
455      _IO_FILE *fp;
456      char *p;
457      _IO_ssize_t len;
458 {
459   if (_IO_default_setbuf (fp, p, len) == NULL)
460     return NULL;
461
462   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
463     = fp->_IO_buf_base;
464   _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
465
466   return fp;
467 }
468 libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf)
469
470
471 _IO_FILE *
472 _IO_file_setbuf_mmap (fp, p, len)
473      _IO_FILE *fp;
474      char *p;
475      _IO_ssize_t len;
476 {
477   _IO_FILE *result;
478
479   /* Change the function table.  */
480   _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
481   fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
482
483   /* And perform the normal operation.  */
484   result = _IO_new_file_setbuf (fp, p, len);
485
486   /* If the call failed, restore to using mmap.  */
487   if (result == NULL)
488     {
489       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
490       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
491     }
492
493   return result;
494 }
495
496 static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
497
498 /* Write TO_DO bytes from DATA to FP.
499    Then mark FP as having empty buffers. */
500
501 int
502 _IO_new_do_write (fp, data, to_do)
503      _IO_FILE *fp;
504      const char *data;
505      _IO_size_t to_do;
506 {
507   return (to_do == 0
508           || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
509 }
510 libc_hidden_ver (_IO_new_do_write, _IO_do_write)
511
512 static
513 _IO_size_t
514 new_do_write (fp, data, to_do)
515      _IO_FILE *fp;
516      const char *data;
517      _IO_size_t to_do;
518 {
519   _IO_size_t count;
520   if (fp->_flags & _IO_IS_APPENDING)
521     /* On a system without a proper O_APPEND implementation,
522        you would need to sys_seek(0, SEEK_END) here, but is
523        not needed nor desirable for Unix- or Posix-like systems.
524        Instead, just indicate that offset (before and after) is
525        unpredictable. */
526     fp->_offset = _IO_pos_BAD;
527   else if (fp->_IO_read_end != fp->_IO_write_base)
528     {
529       _IO_off64_t new_pos
530         = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
531       if (new_pos == _IO_pos_BAD)
532         return 0;
533       fp->_offset = new_pos;
534     }
535   count = _IO_SYSWRITE (fp, data, to_do);
536   if (fp->_cur_column && count)
537     fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
538   _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
539   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
540   fp->_IO_write_end = (fp->_mode <= 0
541                        && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
542                        ? fp->_IO_buf_base : fp->_IO_buf_end);
543   return count;
544 }
545
546 int
547 _IO_new_file_underflow (fp)
548      _IO_FILE *fp;
549 {
550   _IO_ssize_t count;
551 #if 0
552   /* SysV does not make this test; take it out for compatibility */
553   if (fp->_flags & _IO_EOF_SEEN)
554     return (EOF);
555 #endif
556
557   if (fp->_flags & _IO_NO_READS)
558     {
559       fp->_flags |= _IO_ERR_SEEN;
560       __set_errno (EBADF);
561       return EOF;
562     }
563   if (fp->_IO_read_ptr < fp->_IO_read_end)
564     return *(unsigned char *) fp->_IO_read_ptr;
565
566   if (fp->_IO_buf_base == NULL)
567     {
568       /* Maybe we already have a push back pointer.  */
569       if (fp->_IO_save_base != NULL)
570         {
571           free (fp->_IO_save_base);
572           fp->_flags &= ~_IO_IN_BACKUP;
573         }
574       _IO_doallocbuf (fp);
575     }
576
577   /* Flush all line buffered files before reading. */
578   /* FIXME This can/should be moved to genops ?? */
579   if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
580     {
581 #if 0
582       _IO_flush_all_linebuffered ();
583 #else
584       /* We used to flush all line-buffered stream.  This really isn't
585          required by any standard.  My recollection is that
586          traditional Unix systems did this for stdout.  stderr better
587          not be line buffered.  So we do just that here
588          explicitly.  --drepper */
589       _IO_acquire_lock (_IO_stdout);
590
591       if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
592           == (_IO_LINKED | _IO_LINE_BUF))
593         _IO_OVERFLOW (_IO_stdout, EOF);
594
595       _IO_release_lock (_IO_stdout);
596 #endif
597     }
598
599   _IO_switch_to_get_mode (fp);
600
601   /* This is very tricky. We have to adjust those
602      pointers before we call _IO_SYSREAD () since
603      we may longjump () out while waiting for
604      input. Those pointers may be screwed up. H.J. */
605   fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
606   fp->_IO_read_end = fp->_IO_buf_base;
607   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
608     = fp->_IO_buf_base;
609
610   count = _IO_SYSREAD (fp, fp->_IO_buf_base,
611                        fp->_IO_buf_end - fp->_IO_buf_base);
612   if (count <= 0)
613     {
614       if (count == 0)
615         fp->_flags |= _IO_EOF_SEEN;
616       else
617         fp->_flags |= _IO_ERR_SEEN, count = 0;
618   }
619   fp->_IO_read_end += count;
620   if (count == 0)
621     return EOF;
622   if (fp->_offset != _IO_pos_BAD)
623     _IO_pos_adjust (fp->_offset, count);
624   return *(unsigned char *) fp->_IO_read_ptr;
625 }
626 libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow)
627
628 /* Guts of underflow callback if we mmap the file.  This stats the file and
629    updates the stream state to match.  In the normal case we return zero.
630    If the file is no longer eligible for mmap, its jump tables are reset to
631    the vanilla ones and we return nonzero.  */
632 static int
633 mmap_remap_check (_IO_FILE *fp)
634 {
635   struct stat64 st;
636
637   if (_IO_SYSSTAT (fp, &st) == 0
638       && S_ISREG (st.st_mode) && st.st_size != 0
639       /* Limit the file size to 1MB for 32-bit machines.  */
640       && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024))
641     {
642       const size_t pagesize = __getpagesize ();
643 # define ROUNDED(x)     (((x) + pagesize - 1) & ~(pagesize - 1))
644       if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end
645                                           - fp->_IO_buf_base))
646         {
647           /* We can trim off some pages past the end of the file.  */
648           (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size),
649                            ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base)
650                            - ROUNDED (st.st_size));
651           fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
652         }
653       else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end
654                                                - fp->_IO_buf_base))
655         {
656           /* The file added some pages.  We need to remap it.  */
657           void *p;
658 #ifdef _G_HAVE_MREMAP
659           p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end
660                                                    - fp->_IO_buf_base),
661                         ROUNDED (st.st_size), MREMAP_MAYMOVE);
662           if (p == MAP_FAILED)
663             {
664               (void) __munmap (fp->_IO_buf_base,
665                                fp->_IO_buf_end - fp->_IO_buf_base);
666               goto punt;
667             }
668 #else
669           (void) __munmap (fp->_IO_buf_base,
670                            fp->_IO_buf_end - fp->_IO_buf_base);
671           p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED,
672                         fp->_fileno, 0);
673           if (p == MAP_FAILED)
674             goto punt;
675 #endif
676           fp->_IO_buf_base = p;
677           fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
678         }
679       else
680         {
681           /* The number of pages didn't change.  */
682           fp->_IO_buf_end = fp->_IO_buf_base + st.st_size;
683         }
684 # undef ROUNDED
685
686       fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr;
687       _IO_setg (fp, fp->_IO_buf_base,
688                 fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base
689                 ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end,
690                 fp->_IO_buf_end);
691
692       /* If we are already positioned at or past the end of the file, don't
693          change the current offset.  If not, seek past what we have mapped,
694          mimicking the position left by a normal underflow reading into its
695          buffer until EOF.  */
696
697       if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base)
698         {
699           if (__lseek64 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base,
700                          SEEK_SET)
701               != fp->_IO_buf_end - fp->_IO_buf_base)
702             fp->_flags |= _IO_ERR_SEEN;
703           else
704             fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base;
705         }
706
707       return 0;
708     }
709   else
710     {
711       /* Life is no longer good for mmap.  Punt it.  */
712       (void) __munmap (fp->_IO_buf_base,
713                        fp->_IO_buf_end - fp->_IO_buf_base);
714     punt:
715       fp->_IO_buf_base = fp->_IO_buf_end = NULL;
716       _IO_setg (fp, NULL, NULL, NULL);
717       if (fp->_mode <= 0)
718         _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
719       else
720         _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
721       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
722
723       return 1;
724     }
725 }
726
727 /* Special callback replacing the underflow callbacks if we mmap the file.  */
728 int
729 _IO_file_underflow_mmap (_IO_FILE *fp)
730 {
731   if (fp->_IO_read_ptr < fp->_IO_read_end)
732     return *(unsigned char *) fp->_IO_read_ptr;
733
734   if (__glibc_unlikely (mmap_remap_check (fp)))
735     /* We punted to the regular file functions.  */
736     return _IO_UNDERFLOW (fp);
737
738   if (fp->_IO_read_ptr < fp->_IO_read_end)
739     return *(unsigned char *) fp->_IO_read_ptr;
740
741   fp->_flags |= _IO_EOF_SEEN;
742   return EOF;
743 }
744
745 static void
746 decide_maybe_mmap (_IO_FILE *fp)
747 {
748   /* We use the file in read-only mode.  This could mean we can
749      mmap the file and use it without any copying.  But not all
750      file descriptors are for mmap-able objects and on 32-bit
751      machines we don't want to map files which are too large since
752      this would require too much virtual memory.  */
753   struct stat64 st;
754
755   if (_IO_SYSSTAT (fp, &st) == 0
756       && S_ISREG (st.st_mode) && st.st_size != 0
757       /* Limit the file size to 1MB for 32-bit machines.  */
758       && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)
759       /* Sanity check.  */
760       && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size))
761     {
762       /* Try to map the file.  */
763       void *p;
764
765       p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0);
766       if (p != MAP_FAILED)
767         {
768           /* OK, we managed to map the file.  Set the buffer up and use a
769              special jump table with simplified underflow functions which
770              never tries to read anything from the file.  */
771
772           if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size)
773             {
774               (void) __munmap (p, st.st_size);
775               fp->_offset = _IO_pos_BAD;
776             }
777           else
778             {
779               _IO_setb (fp, p, (char *) p + st.st_size, 0);
780
781               if (fp->_offset == _IO_pos_BAD)
782                 fp->_offset = 0;
783
784               _IO_setg (fp, p, p + fp->_offset, p + st.st_size);
785               fp->_offset = st.st_size;
786
787               if (fp->_mode <= 0)
788                 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap;
789               else
790                 _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap;
791               fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
792
793               return;
794             }
795         }
796     }
797
798   /* We couldn't use mmap, so revert to the vanilla file operations.  */
799
800   if (fp->_mode <= 0)
801     _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
802   else
803     _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
804   fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
805 }
806
807 int
808 _IO_file_underflow_maybe_mmap (_IO_FILE *fp)
809 {
810   /* This is the first read attempt.  Choose mmap or vanilla operations
811      and then punt to the chosen underflow routine.  */
812   decide_maybe_mmap (fp);
813   return _IO_UNDERFLOW (fp);
814 }
815
816
817 int
818 _IO_new_file_overflow (f, ch)
819       _IO_FILE *f;
820       int ch;
821 {
822   if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
823     {
824       f->_flags |= _IO_ERR_SEEN;
825       __set_errno (EBADF);
826       return EOF;
827     }
828   /* If currently reading or no buffer allocated. */
829   if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL)
830     {
831       /* Allocate a buffer if needed. */
832       if (f->_IO_write_base == NULL)
833         {
834           _IO_doallocbuf (f);
835           _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
836         }
837       /* Otherwise must be currently reading.
838          If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
839          logically slide the buffer forwards one block (by setting the
840          read pointers to all point at the beginning of the block).  This
841          makes room for subsequent output.
842          Otherwise, set the read pointers to _IO_read_end (leaving that
843          alone, so it can continue to correspond to the external position). */
844       if (__glibc_unlikely (_IO_in_backup (f)))
845         {
846           size_t nbackup = f->_IO_read_end - f->_IO_read_ptr;
847           _IO_free_backup_area (f);
848           f->_IO_read_base -= MIN (nbackup,
849                                    f->_IO_read_base - f->_IO_buf_base);
850           f->_IO_read_ptr = f->_IO_read_base;
851         }
852
853       if (f->_IO_read_ptr == f->_IO_buf_end)
854         f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
855       f->_IO_write_ptr = f->_IO_read_ptr;
856       f->_IO_write_base = f->_IO_write_ptr;
857       f->_IO_write_end = f->_IO_buf_end;
858       f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
859
860       f->_flags |= _IO_CURRENTLY_PUTTING;
861       if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
862         f->_IO_write_end = f->_IO_write_ptr;
863     }
864   if (ch == EOF)
865     return _IO_do_write (f, f->_IO_write_base,
866                          f->_IO_write_ptr - f->_IO_write_base);
867   if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
868     if (_IO_do_flush (f) == EOF)
869       return EOF;
870   *f->_IO_write_ptr++ = ch;
871   if ((f->_flags & _IO_UNBUFFERED)
872       || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
873     if (_IO_do_write (f, f->_IO_write_base,
874                       f->_IO_write_ptr - f->_IO_write_base) == EOF)
875       return EOF;
876   return (unsigned char) ch;
877 }
878 libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow)
879
880 int
881 _IO_new_file_sync (fp)
882      _IO_FILE *fp;
883 {
884   _IO_ssize_t delta;
885   int retval = 0;
886
887   /*    char* ptr = cur_ptr(); */
888   if (fp->_IO_write_ptr > fp->_IO_write_base)
889     if (_IO_do_flush(fp)) return EOF;
890   delta = fp->_IO_read_ptr - fp->_IO_read_end;
891   if (delta != 0)
892     {
893 #ifdef TODO
894       if (_IO_in_backup (fp))
895         delta -= eGptr () - Gbase ();
896 #endif
897       _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
898       if (new_pos != (_IO_off64_t) EOF)
899         fp->_IO_read_end = fp->_IO_read_ptr;
900 #ifdef ESPIPE
901       else if (errno == ESPIPE)
902         ; /* Ignore error from unseekable devices. */
903 #endif
904       else
905         retval = EOF;
906     }
907   if (retval != EOF)
908     fp->_offset = _IO_pos_BAD;
909   /* FIXME: Cleanup - can this be shared? */
910   /*    setg(base(), ptr, ptr); */
911   return retval;
912 }
913 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
914
915 static int
916 _IO_file_sync_mmap (_IO_FILE *fp)
917 {
918   if (fp->_IO_read_ptr != fp->_IO_read_end)
919     {
920 #ifdef TODO
921       if (_IO_in_backup (fp))
922         delta -= eGptr () - Gbase ();
923 #endif
924       if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base,
925                      SEEK_SET)
926           != fp->_IO_read_ptr - fp->_IO_buf_base)
927         {
928           fp->_flags |= _IO_ERR_SEEN;
929           return EOF;
930         }
931     }
932   fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
933   fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
934   return 0;
935 }
936
937 /* ftell{,o} implementation.  The only time we modify the state of the stream
938    is when we have unflushed writes.  In that case we seek to the end and
939    record that offset in the stream object.  */
940 static _IO_off64_t
941 do_ftell (_IO_FILE *fp)
942 {
943   _IO_off64_t result, offset = 0;
944
945   /* No point looking at unflushed data if we haven't allocated buffers
946      yet.  */
947   if (fp->_IO_buf_base != NULL)
948     {
949       bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
950                           || _IO_in_put_mode (fp));
951
952       bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING;
953
954       /* When we have unflushed writes in append mode, seek to the end of the
955          file and record that offset.  This is the only time we change the file
956          stream state and it is safe since the file handle is active.  */
957       if (was_writing && append_mode)
958         {
959           result = _IO_SYSSEEK (fp, 0, _IO_seek_end);
960           if (result == _IO_pos_BAD)
961             return EOF;
962           else
963             fp->_offset = result;
964         }
965
966       /* Adjust for unflushed data.  */
967       if (!was_writing)
968         offset -= fp->_IO_read_end - fp->_IO_read_ptr;
969       else
970         offset += fp->_IO_write_ptr - fp->_IO_read_end;
971     }
972
973   if (fp->_offset != _IO_pos_BAD)
974     result = fp->_offset;
975   else
976     result = _IO_SYSSEEK (fp, 0, _IO_seek_cur);
977
978   if (result == EOF)
979     return result;
980
981   result += offset;
982
983   if (result < 0)
984     {
985       __set_errno (EINVAL);
986       return EOF;
987     }
988
989   return result;
990 }
991
992 _IO_off64_t
993 _IO_new_file_seekoff (fp, offset, dir, mode)
994      _IO_FILE *fp;
995      _IO_off64_t offset;
996      int dir;
997      int mode;
998 {
999   _IO_off64_t result;
1000   _IO_off64_t delta, new_offset;
1001   long count;
1002
1003   /* Short-circuit into a separate function.  We don't want to mix any
1004      functionality and we don't want to touch anything inside the FILE
1005      object. */
1006   if (mode == 0)
1007     return do_ftell (fp);
1008
1009   /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
1010      offset of the underlying file must be exact.  */
1011   int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
1012                        && fp->_IO_write_base == fp->_IO_write_ptr);
1013
1014   bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base
1015                       || _IO_in_put_mode (fp));
1016
1017   /* Flush unwritten characters.
1018      (This may do an unneeded write if we seek within the buffer.
1019      But to be able to switch to reading, we would need to set
1020      egptr to pptr.  That can't be done in the current design,
1021      which assumes file_ptr() is eGptr.  Anyway, since we probably
1022      end up flushing when we close(), it doesn't make much difference.)
1023      FIXME: simulate mem-mapped files. */
1024   if (was_writing && _IO_switch_to_get_mode (fp))
1025     return EOF;
1026
1027   if (fp->_IO_buf_base == NULL)
1028     {
1029       /* It could be that we already have a pushback buffer.  */
1030       if (fp->_IO_read_base != NULL)
1031         {
1032           free (fp->_IO_read_base);
1033           fp->_flags &= ~_IO_IN_BACKUP;
1034         }
1035       _IO_doallocbuf (fp);
1036       _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1037       _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1038     }
1039
1040   switch (dir)
1041     {
1042     case _IO_seek_cur:
1043       /* Adjust for read-ahead (bytes is buffer). */
1044       offset -= fp->_IO_read_end - fp->_IO_read_ptr;
1045
1046       if (fp->_offset == _IO_pos_BAD)
1047         goto dumb;
1048       /* Make offset absolute, assuming current pointer is file_ptr(). */
1049       offset += fp->_offset;
1050       if (offset < 0)
1051         {
1052           __set_errno (EINVAL);
1053           return EOF;
1054         }
1055
1056       dir = _IO_seek_set;
1057       break;
1058     case _IO_seek_set:
1059       break;
1060     case _IO_seek_end:
1061       {
1062         struct stat64 st;
1063         if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
1064           {
1065             offset += st.st_size;
1066             dir = _IO_seek_set;
1067           }
1068         else
1069           goto dumb;
1070       }
1071     }
1072   /* At this point, dir==_IO_seek_set. */
1073
1074   /* If destination is within current buffer, optimize: */
1075   if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
1076       && !_IO_in_backup (fp))
1077     {
1078       _IO_off64_t start_offset = (fp->_offset
1079                                   - (fp->_IO_read_end - fp->_IO_buf_base));
1080       if (offset >= start_offset && offset < fp->_offset)
1081         {
1082           _IO_setg (fp, fp->_IO_buf_base,
1083                     fp->_IO_buf_base + (offset - start_offset),
1084                     fp->_IO_read_end);
1085           _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1086
1087           _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1088           goto resync;
1089         }
1090     }
1091
1092   if (fp->_flags & _IO_NO_READS)
1093     goto dumb;
1094
1095   /* Try to seek to a block boundary, to improve kernel page management. */
1096   new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
1097   delta = offset - new_offset;
1098   if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
1099     {
1100       new_offset = offset;
1101       delta = 0;
1102     }
1103   result = _IO_SYSSEEK (fp, new_offset, 0);
1104   if (result < 0)
1105     return EOF;
1106   if (delta == 0)
1107     count = 0;
1108   else
1109     {
1110       count = _IO_SYSREAD (fp, fp->_IO_buf_base,
1111                            (must_be_exact
1112                             ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
1113       if (count < delta)
1114         {
1115           /* We weren't allowed to read, but try to seek the remainder. */
1116           offset = count == EOF ? delta : delta-count;
1117           dir = _IO_seek_cur;
1118           goto dumb;
1119         }
1120     }
1121   _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
1122             fp->_IO_buf_base + count);
1123   _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1124   fp->_offset = result + count;
1125   _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1126   return offset;
1127  dumb:
1128
1129   _IO_unsave_markers (fp);
1130   result = _IO_SYSSEEK (fp, offset, dir);
1131   if (result != EOF)
1132     {
1133       _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1134       fp->_offset = result;
1135       _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1136       _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1137     }
1138   return result;
1139
1140 resync:
1141   /* We need to do it since it is possible that the file offset in
1142      the kernel may be changed behind our back. It may happen when
1143      we fopen a file and then do a fork. One process may access the
1144      file and the kernel file offset will be changed. */
1145   if (fp->_offset >= 0)
1146     _IO_SYSSEEK (fp, fp->_offset, 0);
1147
1148   return offset;
1149 }
1150 libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff)
1151
1152 _IO_off64_t
1153 _IO_file_seekoff_mmap (fp, offset, dir, mode)
1154      _IO_FILE *fp;
1155      _IO_off64_t offset;
1156      int dir;
1157      int mode;
1158 {
1159   _IO_off64_t result;
1160
1161   /* If we are only interested in the current position, calculate it and
1162      return right now.  This calculation does the right thing when we are
1163      using a pushback buffer, but in the usual case has the same value as
1164      (fp->_IO_read_ptr - fp->_IO_buf_base).  */
1165   if (mode == 0)
1166     return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr);
1167
1168   switch (dir)
1169     {
1170     case _IO_seek_cur:
1171       /* Adjust for read-ahead (bytes is buffer). */
1172       offset += fp->_IO_read_ptr - fp->_IO_read_base;
1173       break;
1174     case _IO_seek_set:
1175       break;
1176     case _IO_seek_end:
1177       offset += fp->_IO_buf_end - fp->_IO_buf_base;
1178       break;
1179     }
1180   /* At this point, dir==_IO_seek_set. */
1181
1182   if (offset < 0)
1183     {
1184       /* No negative offsets are valid.  */
1185       __set_errno (EINVAL);
1186       return EOF;
1187     }
1188
1189   result = _IO_SYSSEEK (fp, offset, 0);
1190   if (result < 0)
1191     return EOF;
1192
1193   if (offset > fp->_IO_buf_end - fp->_IO_buf_base)
1194     /* One can fseek arbitrarily past the end of the file
1195        and it is meaningless until one attempts to read.
1196        Leave the buffer pointers in EOF state until underflow.  */
1197     _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end);
1198   else
1199     /* Adjust the read pointers to match the file position,
1200        but so the next read attempt will call underflow.  */
1201     _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset,
1202               fp->_IO_buf_base + offset);
1203
1204   fp->_offset = result;
1205
1206   _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
1207
1208   return offset;
1209 }
1210
1211 static _IO_off64_t
1212 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
1213                              int mode)
1214 {
1215   /* We only get here when we haven't tried to read anything yet.
1216      So there is nothing more useful for us to do here than just
1217      the underlying lseek call.  */
1218
1219   _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir);
1220   if (result < 0)
1221     return EOF;
1222
1223   fp->_offset = result;
1224   return result;
1225 }
1226
1227 _IO_ssize_t
1228 _IO_file_read (fp, buf, size)
1229      _IO_FILE *fp;
1230      void *buf;
1231      _IO_ssize_t size;
1232 {
1233   return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0)
1234           ? read_not_cancel (fp->_fileno, buf, size)
1235           : read (fp->_fileno, buf, size));
1236 }
1237 libc_hidden_def (_IO_file_read)
1238
1239 _IO_off64_t
1240 _IO_file_seek (fp, offset, dir)
1241      _IO_FILE *fp;
1242      _IO_off64_t offset;
1243      int dir;
1244 {
1245   return __lseek64 (fp->_fileno, offset, dir);
1246 }
1247 libc_hidden_def (_IO_file_seek)
1248
1249 int
1250 _IO_file_stat (fp, st)
1251      _IO_FILE *fp;
1252      void *st;
1253 {
1254   return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st);
1255 }
1256 libc_hidden_def (_IO_file_stat)
1257
1258 int
1259 _IO_file_close_mmap (fp)
1260      _IO_FILE *fp;
1261 {
1262   /* In addition to closing the file descriptor we have to unmap the file.  */
1263   (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base);
1264   fp->_IO_buf_base = fp->_IO_buf_end = NULL;
1265   /* Cancelling close should be avoided if possible since it leaves an
1266      unrecoverable state behind.  */
1267   return close_not_cancel (fp->_fileno);
1268 }
1269
1270 int
1271 _IO_file_close (fp)
1272      _IO_FILE *fp;
1273 {
1274   /* Cancelling close should be avoided if possible since it leaves an
1275      unrecoverable state behind.  */
1276   return close_not_cancel (fp->_fileno);
1277 }
1278 libc_hidden_def (_IO_file_close)
1279
1280 _IO_ssize_t
1281 _IO_new_file_write (f, data, n)
1282      _IO_FILE *f;
1283      const void *data;
1284      _IO_ssize_t n;
1285 {
1286   _IO_ssize_t to_do = n;
1287   while (to_do > 0)
1288     {
1289       _IO_ssize_t count = (__builtin_expect (f->_flags2
1290                                              & _IO_FLAGS2_NOTCANCEL, 0)
1291                            ? write_not_cancel (f->_fileno, data, to_do)
1292                            : write (f->_fileno, data, to_do));
1293       if (count < 0)
1294         {
1295           f->_flags |= _IO_ERR_SEEN;
1296           break;
1297         }
1298       to_do -= count;
1299       data = (void *) ((char *) data + count);
1300     }
1301   n -= to_do;
1302   if (f->_offset >= 0)
1303     f->_offset += n;
1304   return n;
1305 }
1306
1307 _IO_size_t
1308 _IO_new_file_xsputn (f, data, n)
1309      _IO_FILE *f;
1310      const void *data;
1311      _IO_size_t n;
1312 {
1313   const char *s = (const char *) data;
1314   _IO_size_t to_do = n;
1315   int must_flush = 0;
1316   _IO_size_t count = 0;
1317
1318   if (n <= 0)
1319     return 0;
1320   /* This is an optimized implementation.
1321      If the amount to be written straddles a block boundary
1322      (or the filebuf is unbuffered), use sys_write directly. */
1323
1324   /* First figure out how much space is available in the buffer. */
1325   if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
1326     {
1327       count = f->_IO_buf_end - f->_IO_write_ptr;
1328       if (count >= n)
1329         {
1330           const char *p;
1331           for (p = s + n; p > s; )
1332             {
1333               if (*--p == '\n')
1334                 {
1335                   count = p - s + 1;
1336                   must_flush = 1;
1337                   break;
1338                 }
1339             }
1340         }
1341     }
1342   else if (f->_IO_write_end > f->_IO_write_ptr)
1343     count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
1344
1345   /* Then fill the buffer. */
1346   if (count > 0)
1347     {
1348       if (count > to_do)
1349         count = to_do;
1350 #ifdef _LIBC
1351       f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
1352 #else
1353       memcpy (f->_IO_write_ptr, s, count);
1354       f->_IO_write_ptr += count;
1355 #endif
1356       s += count;
1357       to_do -= count;
1358     }
1359   if (to_do + must_flush > 0)
1360     {
1361       _IO_size_t block_size, do_write;
1362       /* Next flush the (full) buffer. */
1363       if (_IO_OVERFLOW (f, EOF) == EOF)
1364         /* If nothing else has to be written we must not signal the
1365            caller that everything has been written.  */
1366         return to_do == 0 ? EOF : n - to_do;
1367
1368       /* Try to maintain alignment: write a whole number of blocks.  */
1369       block_size = f->_IO_buf_end - f->_IO_buf_base;
1370       do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
1371
1372       if (do_write)
1373         {
1374           count = new_do_write (f, s, do_write);
1375           to_do -= count;
1376           if (count < do_write)
1377             return n - to_do;
1378         }
1379
1380       /* Now write out the remainder.  Normally, this will fit in the
1381          buffer, but it's somewhat messier for line-buffered files,
1382          so we let _IO_default_xsputn handle the general case. */
1383       if (to_do)
1384         to_do -= _IO_default_xsputn (f, s+do_write, to_do);
1385     }
1386   return n - to_do;
1387 }
1388 libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn)
1389
1390 _IO_size_t
1391 _IO_file_xsgetn (fp, data, n)
1392      _IO_FILE *fp;
1393      void *data;
1394      _IO_size_t n;
1395 {
1396   _IO_size_t want, have;
1397   _IO_ssize_t count;
1398   char *s = data;
1399
1400   want = n;
1401
1402   if (fp->_IO_buf_base == NULL)
1403     {
1404       /* Maybe we already have a push back pointer.  */
1405       if (fp->_IO_save_base != NULL)
1406         {
1407           free (fp->_IO_save_base);
1408           fp->_flags &= ~_IO_IN_BACKUP;
1409         }
1410       _IO_doallocbuf (fp);
1411     }
1412
1413   while (want > 0)
1414     {
1415       have = fp->_IO_read_end - fp->_IO_read_ptr;
1416       if (want <= have)
1417         {
1418           memcpy (s, fp->_IO_read_ptr, want);
1419           fp->_IO_read_ptr += want;
1420           want = 0;
1421         }
1422       else
1423         {
1424           if (have > 0)
1425             {
1426 #ifdef _LIBC
1427               s = __mempcpy (s, fp->_IO_read_ptr, have);
1428 #else
1429               memcpy (s, fp->_IO_read_ptr, have);
1430               s += have;
1431 #endif
1432               want -= have;
1433               fp->_IO_read_ptr += have;
1434             }
1435
1436           /* Check for backup and repeat */
1437           if (_IO_in_backup (fp))
1438             {
1439               _IO_switch_to_main_get_area (fp);
1440               continue;
1441             }
1442
1443           /* If we now want less than a buffer, underflow and repeat
1444              the copy.  Otherwise, _IO_SYSREAD directly to
1445              the user buffer. */
1446           if (fp->_IO_buf_base
1447               && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base))
1448             {
1449               if (__underflow (fp) == EOF)
1450                 break;
1451
1452               continue;
1453             }
1454
1455           /* These must be set before the sysread as we might longjmp out
1456              waiting for input. */
1457           _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
1458           _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
1459
1460           /* Try to maintain alignment: read a whole number of blocks.  */
1461           count = want;
1462           if (fp->_IO_buf_base)
1463             {
1464               _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
1465               if (block_size >= 128)
1466                 count -= want % block_size;
1467             }
1468
1469           count = _IO_SYSREAD (fp, s, count);
1470           if (count <= 0)
1471             {
1472               if (count == 0)
1473                 fp->_flags |= _IO_EOF_SEEN;
1474               else
1475                 fp->_flags |= _IO_ERR_SEEN;
1476
1477               break;
1478             }
1479
1480           s += count;
1481           want -= count;
1482           if (fp->_offset != _IO_pos_BAD)
1483             _IO_pos_adjust (fp->_offset, count);
1484         }
1485     }
1486
1487   return n - want;
1488 }
1489 libc_hidden_def (_IO_file_xsgetn)
1490
1491 static _IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *, void *, _IO_size_t);
1492 static _IO_size_t
1493 _IO_file_xsgetn_mmap (fp, data, n)
1494      _IO_FILE *fp;
1495      void *data;
1496      _IO_size_t n;
1497 {
1498   _IO_size_t have;
1499   char *read_ptr = fp->_IO_read_ptr;
1500   char *s = (char *) data;
1501
1502   have = fp->_IO_read_end - fp->_IO_read_ptr;
1503
1504   if (have < n)
1505     {
1506       if (__glibc_unlikely (_IO_in_backup (fp)))
1507         {
1508 #ifdef _LIBC
1509           s = __mempcpy (s, read_ptr, have);
1510 #else
1511           memcpy (s, read_ptr, have);
1512           s += have;
1513 #endif
1514           n -= have;
1515           _IO_switch_to_main_get_area (fp);
1516           read_ptr = fp->_IO_read_ptr;
1517           have = fp->_IO_read_end - fp->_IO_read_ptr;
1518         }
1519
1520       if (have < n)
1521         {
1522           /* Check that we are mapping all of the file, in case it grew.  */
1523           if (__glibc_unlikely (mmap_remap_check (fp)))
1524             /* We punted mmap, so complete with the vanilla code.  */
1525             return s - (char *) data + _IO_XSGETN (fp, data, n);
1526
1527           read_ptr = fp->_IO_read_ptr;
1528           have = fp->_IO_read_end - read_ptr;
1529         }
1530     }
1531
1532   if (have < n)
1533     fp->_flags |= _IO_EOF_SEEN;
1534
1535   if (have != 0)
1536     {
1537       have = MIN (have, n);
1538 #ifdef _LIBC
1539       s = __mempcpy (s, read_ptr, have);
1540 #else
1541       memcpy (s, read_ptr, have);
1542       s += have;
1543 #endif
1544       fp->_IO_read_ptr = read_ptr + have;
1545     }
1546
1547   return s - (char *) data;
1548 }
1549
1550 static _IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *, void *, _IO_size_t);
1551 static _IO_size_t
1552 _IO_file_xsgetn_maybe_mmap (fp, data, n)
1553      _IO_FILE *fp;
1554      void *data;
1555      _IO_size_t n;
1556 {
1557   /* We only get here if this is the first attempt to read something.
1558      Decide which operations to use and then punt to the chosen one.  */
1559
1560   decide_maybe_mmap (fp);
1561   return _IO_XSGETN (fp, data, n);
1562 }
1563
1564 #ifdef _LIBC
1565 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1566 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1567 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1568 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1569 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1570 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1571 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1572 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1573 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1574 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1575 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1576 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1577 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1578 #endif
1579
1580 const struct _IO_jump_t _IO_file_jumps =
1581 {
1582   JUMP_INIT_DUMMY,
1583   JUMP_INIT(finish, _IO_file_finish),
1584   JUMP_INIT(overflow, _IO_file_overflow),
1585   JUMP_INIT(underflow, _IO_file_underflow),
1586   JUMP_INIT(uflow, _IO_default_uflow),
1587   JUMP_INIT(pbackfail, _IO_default_pbackfail),
1588   JUMP_INIT(xsputn, _IO_file_xsputn),
1589   JUMP_INIT(xsgetn, _IO_file_xsgetn),
1590   JUMP_INIT(seekoff, _IO_new_file_seekoff),
1591   JUMP_INIT(seekpos, _IO_default_seekpos),
1592   JUMP_INIT(setbuf, _IO_new_file_setbuf),
1593   JUMP_INIT(sync, _IO_new_file_sync),
1594   JUMP_INIT(doallocate, _IO_file_doallocate),
1595   JUMP_INIT(read, _IO_file_read),
1596   JUMP_INIT(write, _IO_new_file_write),
1597   JUMP_INIT(seek, _IO_file_seek),
1598   JUMP_INIT(close, _IO_file_close),
1599   JUMP_INIT(stat, _IO_file_stat),
1600   JUMP_INIT(showmanyc, _IO_default_showmanyc),
1601   JUMP_INIT(imbue, _IO_default_imbue)
1602 };
1603 libc_hidden_data_def (_IO_file_jumps)
1604
1605 const struct _IO_jump_t _IO_file_jumps_mmap =
1606 {
1607   JUMP_INIT_DUMMY,
1608   JUMP_INIT(finish, _IO_file_finish),
1609   JUMP_INIT(overflow, _IO_file_overflow),
1610   JUMP_INIT(underflow, _IO_file_underflow_mmap),
1611   JUMP_INIT(uflow, _IO_default_uflow),
1612   JUMP_INIT(pbackfail, _IO_default_pbackfail),
1613   JUMP_INIT(xsputn, _IO_new_file_xsputn),
1614   JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
1615   JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
1616   JUMP_INIT(seekpos, _IO_default_seekpos),
1617   JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1618   JUMP_INIT(sync, _IO_file_sync_mmap),
1619   JUMP_INIT(doallocate, _IO_file_doallocate),
1620   JUMP_INIT(read, _IO_file_read),
1621   JUMP_INIT(write, _IO_new_file_write),
1622   JUMP_INIT(seek, _IO_file_seek),
1623   JUMP_INIT(close, _IO_file_close_mmap),
1624   JUMP_INIT(stat, _IO_file_stat),
1625   JUMP_INIT(showmanyc, _IO_default_showmanyc),
1626   JUMP_INIT(imbue, _IO_default_imbue)
1627 };
1628
1629 const struct _IO_jump_t _IO_file_jumps_maybe_mmap =
1630 {
1631   JUMP_INIT_DUMMY,
1632   JUMP_INIT(finish, _IO_file_finish),
1633   JUMP_INIT(overflow, _IO_file_overflow),
1634   JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
1635   JUMP_INIT(uflow, _IO_default_uflow),
1636   JUMP_INIT(pbackfail, _IO_default_pbackfail),
1637   JUMP_INIT(xsputn, _IO_new_file_xsputn),
1638   JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
1639   JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
1640   JUMP_INIT(seekpos, _IO_default_seekpos),
1641   JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
1642   JUMP_INIT(sync, _IO_new_file_sync),
1643   JUMP_INIT(doallocate, _IO_file_doallocate),
1644   JUMP_INIT(read, _IO_file_read),
1645   JUMP_INIT(write, _IO_new_file_write),
1646   JUMP_INIT(seek, _IO_file_seek),
1647   JUMP_INIT(close, _IO_file_close),
1648   JUMP_INIT(stat, _IO_file_stat),
1649   JUMP_INIT(showmanyc, _IO_default_showmanyc),
1650   JUMP_INIT(imbue, _IO_default_imbue)
1651 };