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