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