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