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