* sysdeps/unix/sysv/linux/m68k/sysdep.h (INLINE_SYSCALL): Don't
[glibc.git] / libio / fileops.c
blob03f71d71c073cb41b38274e1385ac4fe9b60da9c
1 /* Copyright (C) 1993, 1995, 1997-2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Written by Per Bothner <bothner@cygnus.com>.
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.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
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.
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. */
30 #ifndef _POSIX_SOURCE
31 # define _POSIX_SOURCE
32 #endif
33 #include "libioP.h"
34 #include <fcntl.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <string.h>
38 #include <errno.h>
39 #include <unistd.h>
40 #ifdef __STDC__
41 #include <stdlib.h>
42 #endif
43 #if _LIBC
44 # include "../wcsmbs/wcsmbsload.h"
45 # include <shlib-compat.h>
46 #endif
47 #ifndef errno
48 extern int errno;
49 #endif
50 #ifndef __set_errno
51 # define __set_errno(Val) errno = (Val)
52 #endif
55 #ifdef _LIBC
56 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
57 # define close(FD) __close (FD)
58 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
59 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
60 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
61 #else
62 # define _IO_new_do_write _IO_do_write
63 # define _IO_new_file_attach _IO_file_attach
64 # define _IO_new_file_close_it _IO_file_close_it
65 # define _IO_new_file_finish _IO_file_finish
66 # define _IO_new_file_fopen _IO_file_fopen
67 # define _IO_new_file_init _IO_file_init
68 # define _IO_new_file_setbuf _IO_file_setbuf
69 # define _IO_new_file_sync _IO_file_sync
70 # define _IO_new_file_overflow _IO_file_overflow
71 # define _IO_new_file_seekoff _IO_file_seekoff
72 # define _IO_new_file_underflow _IO_file_underflow
73 # define _IO_new_file_write _IO_file_write
74 # define _IO_new_file_xsputn _IO_file_xsputn
75 #endif
77 /* An fstream can be in at most one of put mode, get mode, or putback mode.
78 Putback mode is a variant of get mode.
80 In a filebuf, there is only one current position, instead of two
81 separate get and put pointers. In get mode, the current position
82 is that of gptr(); in put mode that of pptr().
84 The position in the buffer that corresponds to the position
85 in external file system is normally _IO_read_end, except in putback
86 mode, when it is _IO_save_end.
87 If the field _fb._offset is >= 0, it gives the offset in
88 the file as a whole corresponding to eGptr(). (?)
90 PUT MODE:
91 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
92 and _IO_read_base are equal to each other. These are usually equal
93 to _IO_buf_base, though not necessarily if we have switched from
94 get mode to put mode. (The reason is to maintain the invariant
95 that _IO_read_end corresponds to the external file position.)
96 _IO_write_base is non-NULL and usually equal to _IO_base_base.
97 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
98 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
100 GET MODE:
101 If a filebuf is in get or putback mode, eback() != egptr().
102 In get mode, the unread characters are between gptr() and egptr().
103 The OS file position corresponds to that of egptr().
105 PUTBACK MODE:
106 Putback mode is used to remember "excess" characters that have
107 been sputbackc'd in a separate putback buffer.
108 In putback mode, the get buffer points to the special putback buffer.
109 The unread characters are the characters between gptr() and egptr()
110 in the putback buffer, as well as the area between save_gptr()
111 and save_egptr(), which point into the original reserve buffer.
112 (The pointers save_gptr() and save_egptr() are the values
113 of gptr() and egptr() at the time putback mode was entered.)
114 The OS position corresponds to that of save_egptr().
116 LINE BUFFERED OUTPUT:
117 During line buffered output, _IO_write_base==base() && epptr()==base().
118 However, ptr() may be anywhere between base() and ebuf().
119 This forces a call to filebuf::overflow(int C) on every put.
120 If there is more space in the buffer, and C is not a '\n',
121 then C is inserted, and pptr() incremented.
123 UNBUFFERED STREAMS:
124 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
127 #define CLOSED_FILEBUF_FLAGS \
128 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
131 void
132 _IO_new_file_init (fp)
133 struct _IO_FILE_plus *fp;
135 /* POSIX.1 allows another file handle to be used to change the position
136 of our file descriptor. Hence we actually don't know the actual
137 position before we do the first fseek (and until a following fflush). */
138 fp->file._offset = _IO_pos_BAD;
139 fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
141 _IO_link_in (fp);
142 fp->file._fileno = -1;
146 _IO_new_file_close_it (fp)
147 _IO_FILE *fp;
149 int write_status, close_status;
150 if (!_IO_file_is_open (fp))
151 return EOF;
153 write_status = _IO_do_flush (fp);
155 _IO_unsave_markers(fp);
157 close_status = _IO_SYSCLOSE (fp);
159 /* Free buffer. */
160 if (fp->_mode <= 0)
162 _IO_setb (fp, NULL, NULL, 0);
163 _IO_setg (fp, NULL, NULL, NULL);
164 _IO_setp (fp, NULL, NULL);
166 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
167 else
169 _IO_wsetb (fp, NULL, NULL, 0);
170 _IO_wsetg (fp, NULL, NULL, NULL);
171 _IO_wsetp (fp, NULL, NULL);
173 #endif
175 _IO_un_link ((struct _IO_FILE_plus *) fp);
176 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
177 fp->_fileno = -1;
178 fp->_offset = _IO_pos_BAD;
180 return close_status ? close_status : write_status;
183 void
184 _IO_new_file_finish (fp, dummy)
185 _IO_FILE *fp;
186 int dummy;
188 if (_IO_file_is_open (fp))
190 _IO_do_flush (fp);
191 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
192 _IO_SYSCLOSE (fp);
194 _IO_default_finish (fp, 0);
197 #if defined __GNUC__ && __GNUC__ >= 2
198 __inline__
199 #endif
200 _IO_FILE *
201 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
202 _IO_FILE *fp;
203 const char *filename;
204 int posix_mode;
205 int prot;
206 int read_write;
207 int is32not64;
209 int fdesc;
210 #ifdef _G_OPEN64
211 fdesc = (is32not64
212 ? open (filename, posix_mode, prot)
213 : _G_OPEN64 (filename, posix_mode, prot));
214 #else
215 fdesc = open (filename, posix_mode, prot);
216 #endif
217 if (fdesc < 0)
218 return NULL;
219 fp->_fileno = fdesc;
220 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
221 if (read_write & _IO_IS_APPENDING)
222 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
223 == _IO_pos_BAD && errno != ESPIPE)
224 return NULL;
225 _IO_link_in ((struct _IO_FILE_plus *) fp);
226 return fp;
229 _IO_FILE *
230 _IO_new_file_fopen (fp, filename, mode, is32not64)
231 _IO_FILE *fp;
232 const char *filename;
233 const char *mode;
234 int is32not64;
236 int oflags = 0, omode;
237 int read_write;
238 int oprot = 0666;
239 int i;
240 _IO_FILE *result;
241 #if _LIBC
242 const char *cs;
243 #endif
245 if (_IO_file_is_open (fp))
246 return 0;
247 switch (*mode)
249 case 'r':
250 omode = O_RDONLY;
251 read_write = _IO_NO_WRITES;
252 break;
253 case 'w':
254 omode = O_WRONLY;
255 oflags = O_CREAT|O_TRUNC;
256 read_write = _IO_NO_READS;
257 break;
258 case 'a':
259 omode = O_WRONLY;
260 oflags = O_CREAT|O_APPEND;
261 read_write = _IO_NO_READS|_IO_IS_APPENDING;
262 break;
263 default:
264 __set_errno (EINVAL);
265 return NULL;
267 for (i = 1; i < 4; ++i)
269 switch (*++mode)
271 case '\0':
272 break;
273 case '+':
274 omode = O_RDWR;
275 read_write &= _IO_IS_APPENDING;
276 continue;
277 case 'x':
278 oflags |= O_EXCL;
279 continue;
280 case 'b':
281 default:
282 /* Ignore. */
283 continue;
285 break;
288 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
289 is32not64);
292 #if _LIBC
293 /* Test whether the mode string specifies the conversion. */
294 cs = strstr (mode, ",ccs=");
295 if (cs != NULL)
297 /* Yep. Load the appropriate conversions and set the orientation
298 to wide. */
299 struct gconv_fcts fcts;
300 struct _IO_codecvt *cc;
302 if (! _IO_CHECK_WIDE (fp) || __wcsmbs_named_conv (&fcts, cs + 5) != 0)
304 /* Something went wrong, we cannot load the conversion modules.
305 This means we cannot proceed since the user explicitly asked
306 for these. */
307 _IO_new_fclose (result);
308 return NULL;
311 cc = fp->_codecvt = &fp->_wide_data->_codecvt;
313 /* The functions are always the same. */
314 *cc = __libio_codecvt;
316 cc->__cd_in.__cd.__nsteps = 1; /* Only one step allowed. */
317 cc->__cd_in.__cd.__steps = fcts.towc;
319 cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
320 cc->__cd_in.__cd.__data[0].__internal_use = 1;
321 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
322 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
324 cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */
325 cc->__cd_out.__cd.__steps = fcts.tomb;
327 cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
328 cc->__cd_out.__cd.__data[0].__internal_use = 1;
329 cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
330 cc->__cd_out.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
332 /* Set the mode now. */
333 result->_mode = 1;
335 #endif /* GNU libc */
337 return result;
340 _IO_FILE *
341 _IO_new_file_attach (fp, fd)
342 _IO_FILE *fp;
343 int fd;
345 if (_IO_file_is_open (fp))
346 return NULL;
347 fp->_fileno = fd;
348 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
349 fp->_flags |= _IO_DELETE_DONT_CLOSE;
350 /* Get the current position of the file. */
351 /* We have to do that since that may be junk. */
352 fp->_offset = _IO_pos_BAD;
353 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
354 == _IO_pos_BAD && errno != ESPIPE)
355 return NULL;
356 return fp;
359 _IO_FILE *
360 _IO_new_file_setbuf (fp, p, len)
361 _IO_FILE *fp;
362 char *p;
363 _IO_ssize_t len;
365 if (_IO_default_setbuf (fp, p, len) == NULL)
366 return NULL;
368 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
369 = fp->_IO_buf_base;
370 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
372 return fp;
375 static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
377 /* Write TO_DO bytes from DATA to FP.
378 Then mark FP as having empty buffers. */
381 _IO_new_do_write (fp, data, to_do)
382 _IO_FILE *fp;
383 const char *data;
384 _IO_size_t to_do;
386 return (to_do == 0 || new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
389 static
391 new_do_write (fp, data, to_do)
392 _IO_FILE *fp;
393 const char *data;
394 _IO_size_t to_do;
396 _IO_size_t count;
397 if (fp->_flags & _IO_IS_APPENDING)
398 /* On a system without a proper O_APPEND implementation,
399 you would need to sys_seek(0, SEEK_END) here, but is
400 is not needed nor desirable for Unix- or Posix-like systems.
401 Instead, just indicate that offset (before and after) is
402 unpredictable. */
403 fp->_offset = _IO_pos_BAD;
404 else if (fp->_IO_read_end != fp->_IO_write_base)
406 _IO_off64_t new_pos
407 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
408 if (new_pos == _IO_pos_BAD)
409 return 0;
410 fp->_offset = new_pos;
412 count = _IO_SYSWRITE (fp, data, to_do);
413 if (fp->_cur_column && count)
414 fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
415 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
416 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
417 fp->_IO_write_end = (fp->_mode <= 0
418 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
419 ? fp->_IO_buf_base : fp->_IO_buf_end);
420 return count;
424 _IO_new_file_underflow (fp)
425 _IO_FILE *fp;
427 _IO_ssize_t count;
428 #if 0
429 /* SysV does not make this test; take it out for compatibility */
430 if (fp->_flags & _IO_EOF_SEEN)
431 return (EOF);
432 #endif
434 if (fp->_flags & _IO_NO_READS)
436 fp->_flags |= _IO_ERR_SEEN;
437 __set_errno (EBADF);
438 return EOF;
440 if (fp->_IO_read_ptr < fp->_IO_read_end)
441 return *(unsigned char *) fp->_IO_read_ptr;
443 if (fp->_IO_buf_base == NULL)
445 /* Maybe we already have a push back pointer. */
446 if (fp->_IO_save_base != NULL)
448 free (fp->_IO_save_base);
449 fp->_flags &= ~_IO_IN_BACKUP;
451 _IO_doallocbuf (fp);
454 /* Flush all line buffered files before reading. */
455 /* FIXME This can/should be moved to genops ?? */
456 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
457 _IO_flush_all_linebuffered ();
459 _IO_switch_to_get_mode (fp);
461 /* This is very tricky. We have to adjust those
462 pointers before we call _IO_SYSREAD () since
463 we may longjump () out while waiting for
464 input. Those pointers may be screwed up. H.J. */
465 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
466 fp->_IO_read_end = fp->_IO_buf_base;
467 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
468 = fp->_IO_buf_base;
470 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
471 fp->_IO_buf_end - fp->_IO_buf_base);
472 if (count <= 0)
474 if (count == 0)
475 fp->_flags |= _IO_EOF_SEEN;
476 else
477 fp->_flags |= _IO_ERR_SEEN, count = 0;
479 fp->_IO_read_end += count;
480 if (count == 0)
481 return EOF;
482 if (fp->_offset != _IO_pos_BAD)
483 _IO_pos_adjust (fp->_offset, count);
484 return *(unsigned char *) fp->_IO_read_ptr;
488 _IO_new_file_overflow (f, ch)
489 _IO_FILE *f;
490 int ch;
492 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
494 f->_flags |= _IO_ERR_SEEN;
495 __set_errno (EBADF);
496 return EOF;
498 /* If currently reading or no buffer allocated. */
499 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0)
501 /* Allocate a buffer if needed. */
502 if (f->_IO_write_base == 0)
504 _IO_doallocbuf (f);
505 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
507 /* Otherwise must be currently reading.
508 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
509 logically slide the buffer forwards one block (by setting the
510 read pointers to all point at the beginning of the block). This
511 makes room for subsequent output.
512 Otherwise, set the read pointers to _IO_read_end (leaving that
513 alone, so it can continue to correspond to the external position). */
514 if (f->_IO_read_ptr == f->_IO_buf_end)
515 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
516 f->_IO_write_ptr = f->_IO_read_ptr;
517 f->_IO_write_base = f->_IO_write_ptr;
518 f->_IO_write_end = f->_IO_buf_end;
519 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
521 f->_flags |= _IO_CURRENTLY_PUTTING;
522 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
523 f->_IO_write_end = f->_IO_write_ptr;
525 if (ch == EOF)
526 return _IO_new_do_write(f, f->_IO_write_base,
527 f->_IO_write_ptr - f->_IO_write_base);
528 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
529 if (_IO_do_flush (f) == EOF)
530 return EOF;
531 *f->_IO_write_ptr++ = ch;
532 if ((f->_flags & _IO_UNBUFFERED)
533 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
534 if (_IO_new_do_write(f, f->_IO_write_base,
535 f->_IO_write_ptr - f->_IO_write_base) == EOF)
536 return EOF;
537 return (unsigned char) ch;
541 _IO_new_file_sync (fp)
542 _IO_FILE *fp;
544 _IO_ssize_t delta;
545 int retval = 0;
547 /* char* ptr = cur_ptr(); */
548 if (fp->_IO_write_ptr > fp->_IO_write_base)
549 if (_IO_do_flush(fp)) return EOF;
550 delta = fp->_IO_read_ptr - fp->_IO_read_end;
551 if (delta != 0)
553 #ifdef TODO
554 if (_IO_in_backup (fp))
555 delta -= eGptr () - Gbase ();
556 #endif
557 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
558 if (new_pos != (_IO_off64_t) EOF)
559 fp->_IO_read_end = fp->_IO_read_ptr;
560 #ifdef ESPIPE
561 else if (errno == ESPIPE)
562 ; /* Ignore error from unseekable devices. */
563 #endif
564 else
565 retval = EOF;
567 if (retval != EOF)
568 fp->_offset = _IO_pos_BAD;
569 /* FIXME: Cleanup - can this be shared? */
570 /* setg(base(), ptr, ptr); */
571 return retval;
574 _IO_off64_t
575 _IO_new_file_seekoff (fp, offset, dir, mode)
576 _IO_FILE *fp;
577 _IO_off64_t offset;
578 int dir;
579 int mode;
581 _IO_off64_t result;
582 _IO_off64_t delta, new_offset;
583 long count;
584 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
585 offset of the underlying file must be exact. */
586 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
587 && fp->_IO_write_base == fp->_IO_write_ptr);
589 if (mode == 0)
590 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
592 /* Flush unwritten characters.
593 (This may do an unneeded write if we seek within the buffer.
594 But to be able to switch to reading, we would need to set
595 egptr to ptr. That can't be done in the current design,
596 which assumes file_ptr() is eGptr. Anyway, since we probably
597 end up flushing when we close(), it doesn't make much difference.)
598 FIXME: simulate mem-papped files. */
600 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
601 if (_IO_switch_to_get_mode (fp))
602 return EOF;
604 if (fp->_IO_buf_base == NULL)
606 /* It could be that we already have a pushback buffer. */
607 if (fp->_IO_read_base != NULL)
609 free (fp->_IO_read_base);
610 fp->_flags &= ~_IO_IN_BACKUP;
612 _IO_doallocbuf (fp);
613 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
614 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
617 switch (dir)
619 case _IO_seek_cur:
620 /* Adjust for read-ahead (bytes is buffer). */
621 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
622 if (fp->_offset == _IO_pos_BAD)
623 goto dumb;
624 /* Make offset absolute, assuming current pointer is file_ptr(). */
625 offset += fp->_offset;
627 dir = _IO_seek_set;
628 break;
629 case _IO_seek_set:
630 break;
631 case _IO_seek_end:
633 struct _G_stat64 st;
634 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
636 offset += st.st_size;
637 dir = _IO_seek_set;
639 else
640 goto dumb;
643 /* At this point, dir==_IO_seek_set. */
645 /* If we are only interested in the current position we've found it now. */
646 if (mode == 0)
647 return offset;
649 /* If destination is within current buffer, optimize: */
650 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
651 && !_IO_in_backup (fp))
653 /* Offset relative to start of main get area. */
654 _IO_off64_t rel_offset = (offset - fp->_offset
655 + (fp->_IO_read_end - fp->_IO_read_base));
656 if (rel_offset >= 0)
658 #if 0
659 if (_IO_in_backup (fp))
660 _IO_switch_to_main_get_area (fp);
661 #endif
662 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
664 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
665 fp->_IO_read_end);
666 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
668 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
669 goto resync;
672 #ifdef TODO
673 /* If we have streammarkers, seek forward by reading ahead. */
674 if (_IO_have_markers (fp))
676 int to_skip = rel_offset
677 - (fp->_IO_read_ptr - fp->_IO_read_base);
678 if (ignore (to_skip) != to_skip)
679 goto dumb;
680 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
681 goto resync;
683 #endif
685 #ifdef TODO
686 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
688 if (!_IO_in_backup (fp))
689 _IO_switch_to_backup_area (fp);
690 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
691 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
692 goto resync;
694 #endif
697 #ifdef TODO
698 _IO_unsave_markers (fp);
699 #endif
701 if (fp->_flags & _IO_NO_READS)
702 goto dumb;
704 /* Try to seek to a block boundary, to improve kernel page management. */
705 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
706 delta = offset - new_offset;
707 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
709 new_offset = offset;
710 delta = 0;
712 result = _IO_SYSSEEK (fp, new_offset, 0);
713 if (result < 0)
714 return EOF;
715 if (delta == 0)
716 count = 0;
717 else
719 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
720 (must_be_exact
721 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
722 if (count < delta)
724 /* We weren't allowed to read, but try to seek the remainder. */
725 offset = count == EOF ? delta : delta-count;
726 dir = _IO_seek_cur;
727 goto dumb;
730 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
731 fp->_IO_buf_base + count);
732 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
733 fp->_offset = result + count;
734 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
735 return offset;
736 dumb:
738 _IO_unsave_markers (fp);
739 result = _IO_SYSSEEK (fp, offset, dir);
740 if (result != EOF)
742 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
743 fp->_offset = result;
744 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
745 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
747 return result;
749 resync:
750 /* We need to do it since it is possible that the file offset in
751 the kernel may be changed behind our back. It may happen when
752 we fopen a file and then do a fork. One process may access the
753 the file and the kernel file offset will be changed. */
754 if (fp->_offset >= 0)
755 _IO_SYSSEEK (fp, fp->_offset, 0);
757 return offset;
760 _IO_ssize_t
761 _IO_file_read (fp, buf, size)
762 _IO_FILE *fp;
763 void *buf;
764 _IO_ssize_t size;
766 return read (fp->_fileno, buf, size);
769 _IO_off64_t
770 _IO_file_seek (fp, offset, dir)
771 _IO_FILE *fp;
772 _IO_off64_t offset;
773 int dir;
775 #ifdef _G_LSEEK64
776 return _G_LSEEK64 (fp->_fileno, offset, dir);
777 #else
778 return lseek (fp->_fileno, offset, dir);
779 #endif
783 _IO_file_stat (fp, st)
784 _IO_FILE *fp;
785 void *st;
787 #ifdef _G_FSTAT64
788 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
789 #else
790 return fstat (fp->_fileno, (struct stat *) st);
791 #endif
795 _IO_file_close (fp)
796 _IO_FILE *fp;
798 return close (fp->_fileno);
801 _IO_ssize_t
802 _IO_new_file_write (f, data, n)
803 _IO_FILE *f;
804 const void *data;
805 _IO_ssize_t n;
807 _IO_ssize_t to_do = n;
808 while (to_do > 0)
810 _IO_ssize_t count = write (f->_fileno, data, to_do);
811 if (count < 0)
813 f->_flags |= _IO_ERR_SEEN;
814 break;
816 to_do -= count;
817 data = (void *) ((char *) data + count);
819 n -= to_do;
820 if (f->_offset >= 0)
821 f->_offset += n;
822 return n;
825 _IO_size_t
826 _IO_new_file_xsputn (f, data, n)
827 _IO_FILE *f;
828 const void *data;
829 _IO_size_t n;
831 register const char *s = (const char *) data;
832 _IO_size_t to_do = n;
833 int must_flush = 0;
834 _IO_size_t count;
836 if (n <= 0)
837 return 0;
838 /* This is an optimized implementation.
839 If the amount to be written straddles a block boundary
840 (or the filebuf is unbuffered), use sys_write directly. */
842 /* First figure out how much space is available in the buffer. */
843 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
844 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
846 count = f->_IO_buf_end - f->_IO_write_ptr;
847 if (count >= n)
849 register const char *p;
850 for (p = s + n; p > s; )
852 if (*--p == '\n')
854 count = p - s + 1;
855 must_flush = 1;
856 break;
861 /* Then fill the buffer. */
862 if (count > 0)
864 if (count > to_do)
865 count = to_do;
866 if (count > 20)
868 #ifdef _LIBC
869 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
870 #else
871 memcpy (f->_IO_write_ptr, s, count);
872 f->_IO_write_ptr += count;
873 #endif
874 s += count;
876 else
878 register char *p = f->_IO_write_ptr;
879 register int i = (int) count;
880 while (--i >= 0)
881 *p++ = *s++;
882 f->_IO_write_ptr = p;
884 to_do -= count;
886 if (to_do + must_flush > 0)
888 _IO_size_t block_size, do_write;
889 /* Next flush the (full) buffer. */
890 if (_IO_OVERFLOW (f, EOF) == EOF)
891 return n - to_do;
893 /* Try to maintain alignment: write a whole number of blocks.
894 dont_write is what gets left over. */
895 block_size = f->_IO_buf_end - f->_IO_buf_base;
896 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
898 if (do_write)
900 count = new_do_write (f, s, do_write);
901 to_do -= count;
902 if (count < do_write)
903 return n - to_do;
906 /* Now write out the remainder. Normally, this will fit in the
907 buffer, but it's somewhat messier for line-buffered files,
908 so we let _IO_default_xsputn handle the general case. */
909 if (to_do)
910 to_do -= _IO_default_xsputn (f, s+do_write, to_do);
912 return n - to_do;
915 _IO_size_t
916 _IO_file_xsgetn (fp, data, n)
917 _IO_FILE *fp;
918 void *data;
919 _IO_size_t n;
921 register _IO_size_t want, have;
922 register _IO_ssize_t count;
923 register char *s = data;
925 want = n;
927 if (fp->_IO_buf_base == NULL)
929 /* Maybe we already have a push back pointer. */
930 if (fp->_IO_save_base != NULL)
932 free (fp->_IO_save_base);
933 fp->_flags &= ~_IO_IN_BACKUP;
935 _IO_doallocbuf (fp);
938 while (want > 0)
940 have = fp->_IO_read_end - fp->_IO_read_ptr;
941 if (want <= have)
943 memcpy (s, fp->_IO_read_ptr, want);
944 fp->_IO_read_ptr += want;
945 want = 0;
947 else
949 if (have > 0)
951 #ifdef _LIBC
952 s = __mempcpy (s, fp->_IO_read_ptr, have);
953 #else
954 memcpy (s, fp->_IO_read_ptr, have);
955 s += have;
956 #endif
957 want -= have;
958 fp->_IO_read_ptr += have;
961 /* Check for backup and repeat */
962 if (_IO_in_backup (fp))
964 _IO_switch_to_main_get_area (fp);
965 continue;
968 /* If we now want less than a buffer, underflow and repeat
969 the copy. Otherwise, _IO_SYSREAD directly to
970 the user buffer. */
971 if (fp->_IO_buf_base && want < fp->_IO_buf_end - fp->_IO_buf_base)
973 if (__underflow (fp) == EOF)
974 break;
976 continue;
979 /* These must be set before the sysread as we might longjmp out
980 waiting for input. */
981 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
982 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
984 /* Try to maintain alignment: read a whole number of blocks. */
985 count = want;
986 if (fp->_IO_buf_base)
988 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base;
989 if (block_size >= 128)
990 count -= want % block_size;
993 count = _IO_SYSREAD (fp, s, count);
994 if (count <= 0)
996 if (count == 0)
997 fp->_flags |= _IO_EOF_SEEN;
998 else
999 fp->_flags |= _IO_ERR_SEEN;
1001 break;
1004 s += count;
1005 want -= count;
1006 if (fp->_offset != _IO_pos_BAD)
1007 _IO_pos_adjust (fp->_offset, count);
1011 return n - want;
1014 struct _IO_jump_t _IO_file_jumps =
1016 JUMP_INIT_DUMMY,
1017 JUMP_INIT(finish, _IO_new_file_finish),
1018 JUMP_INIT(overflow, _IO_new_file_overflow),
1019 JUMP_INIT(underflow, _IO_new_file_underflow),
1020 JUMP_INIT(uflow, _IO_default_uflow),
1021 JUMP_INIT(pbackfail, _IO_default_pbackfail),
1022 JUMP_INIT(xsputn, _IO_new_file_xsputn),
1023 JUMP_INIT(xsgetn, _IO_file_xsgetn),
1024 JUMP_INIT(seekoff, _IO_new_file_seekoff),
1025 JUMP_INIT(seekpos, _IO_default_seekpos),
1026 JUMP_INIT(setbuf, _IO_new_file_setbuf),
1027 JUMP_INIT(sync, _IO_new_file_sync),
1028 JUMP_INIT(doallocate, _IO_file_doallocate),
1029 JUMP_INIT(read, _IO_file_read),
1030 JUMP_INIT(write, _IO_new_file_write),
1031 JUMP_INIT(seek, _IO_file_seek),
1032 JUMP_INIT(close, _IO_file_close),
1033 JUMP_INIT(stat, _IO_file_stat),
1034 JUMP_INIT(showmanyc, _IO_default_showmanyc),
1035 JUMP_INIT(imbue, _IO_default_imbue)
1038 #ifdef _LIBC
1039 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1);
1040 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1);
1041 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1);
1042 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1);
1043 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1);
1044 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1);
1045 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1);
1046 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1);
1047 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1);
1048 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
1049 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
1050 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
1051 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
1052 #endif