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