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