1 /* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
3 Written by Per Bothner <bothner@cygnus.com>.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2, or (at
8 your option) any later version.
10 This library is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to
17 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
20 As a special exception, if you link this library with files
21 compiled with a GNU compiler to produce an executable, this does
22 not cause the resulting executable to be covered by the GNU General
23 Public License. This exception does not however invalidate any
24 other reasons why the executable file might be covered by the GNU
25 General Public License. */
29 # define _POSIX_SOURCE
33 #include <sys/types.h>
41 # define __set_errno(Val) errno = (Val)
46 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
47 # define close(FD) __close (FD)
48 # define fstat(FD, Statbuf) __fstat (FD, Statbuf)
49 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
50 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
51 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
54 /* An fstream can be in at most one of put mode, get mode, or putback mode.
55 Putback mode is a variant of get mode.
57 In a filebuf, there is only one current position, instead of two
58 separate get and put pointers. In get mode, the current position
59 is that of gptr(); in put mode that of pptr().
61 The position in the buffer that corresponds to the position
62 in external file system is normally _IO_read_end, except in putback
63 mode, when it is _IO_save_end.
64 If the field _fb._offset is >= 0, it gives the offset in
65 the file as a whole corresponding to eGptr(). (?)
68 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
69 and _IO_read_base are equal to each other. These are usually equal
70 to _IO_buf_base, though not necessarily if we have switched from
71 get mode to put mode. (The reason is to maintain the invariant
72 that _IO_read_end corresponds to the external file position.)
73 _IO_write_base is non-NULL and usually equal to _IO_base_base.
74 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
75 The un-flushed character are those between _IO_write_base and _IO_write_ptr.
78 If a filebuf is in get or putback mode, eback() != egptr().
79 In get mode, the unread characters are between gptr() and egptr().
80 The OS file position corresponds to that of egptr().
83 Putback mode is used to remember "excess" characters that have
84 been sputbackc'd in a separate putback buffer.
85 In putback mode, the get buffer points to the special putback buffer.
86 The unread characters are the characters between gptr() and egptr()
87 in the putback buffer, as well as the area between save_gptr()
88 and save_egptr(), which point into the original reserve buffer.
89 (The pointers save_gptr() and save_egptr() are the values
90 of gptr() and egptr() at the time putback mode was entered.)
91 The OS position corresponds to that of save_egptr().
94 During line buffered output, _IO_write_base==base() && epptr()==base().
95 However, ptr() may be anywhere between base() and ebuf().
96 This forces a call to filebuf::overflow(int C) on every put.
97 If there is more space in the buffer, and C is not a '\n',
98 then C is inserted, and pptr() incremented.
101 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
104 #define CLOSED_FILEBUF_FLAGS \
105 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
112 /* POSIX.1 allows another file handle to be used to change the position
113 of our file descriptor. Hence we actually don't know the actual
114 position before we do the first fseek (and until a following fflush). */
115 fp->_offset = _IO_pos_BAD;
116 fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
123 _IO_file_close_it (fp)
126 int write_status, close_status;
127 if (!_IO_file_is_open (fp))
130 write_status = _IO_do_flush (fp);
132 _IO_unsave_markers(fp);
134 close_status = _IO_SYSCLOSE (fp);
137 _IO_setb (fp, NULL, NULL, 0);
138 _IO_setg (fp, NULL, NULL, NULL);
139 _IO_setp (fp, NULL, NULL);
142 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
144 fp->_offset = _IO_pos_BAD;
146 return close_status ? close_status : write_status;
150 _IO_file_finish (fp, dummy)
154 if (_IO_file_is_open (fp))
157 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
160 _IO_default_finish (fp, 0);
164 _IO_file_fopen (fp, filename, mode)
166 const char *filename;
169 int oflags = 0, omode;
170 int read_write, fdesc;
172 if (_IO_file_is_open (fp))
178 read_write = _IO_NO_WRITES;
182 oflags = O_CREAT|O_TRUNC;
183 read_write = _IO_NO_READS;
187 oflags = O_CREAT|O_APPEND;
188 read_write = _IO_NO_READS|_IO_IS_APPENDING;
191 __set_errno (EINVAL);
194 if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
197 read_write &= _IO_IS_APPENDING;
199 fdesc = open (filename, omode|oflags, oprot);
203 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
204 if (read_write & _IO_IS_APPENDING)
205 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
206 == _IO_pos_BAD && errno != ESPIPE)
214 _IO_file_fopen64 (fp, filename, mode)
216 const char *filename;
219 int oflags = 0, omode;
220 int read_write, fdesc;
222 if (_IO_file_is_open (fp))
228 read_write = _IO_NO_WRITES;
232 oflags = O_CREAT|O_TRUNC;
233 read_write = _IO_NO_READS;
237 oflags = O_CREAT|O_APPEND;
238 read_write = _IO_NO_READS|_IO_IS_APPENDING;
241 __set_errno (EINVAL);
244 if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
247 read_write &= _IO_IS_APPENDING;
249 fdesc = _G_OPEN64 (filename, omode|oflags, oprot);
253 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
254 if (read_write & _IO_IS_APPENDING)
255 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
256 == _IO_pos_BAD && errno != ESPIPE)
264 _IO_file_attach (fp, fd)
268 if (_IO_file_is_open (fp))
271 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
272 fp->_flags |= _IO_DELETE_DONT_CLOSE;
273 /* Get the current position of the file. */
274 /* We have to do that since that may be junk. */
275 fp->_offset = _IO_pos_BAD;
276 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
277 == _IO_pos_BAD && errno != ESPIPE)
283 _IO_file_setbuf (fp, p, len)
288 if (_IO_default_setbuf (fp, p, len) == NULL)
291 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
293 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
298 /* Write TO_DO bytes from DATA to FP.
299 Then mark FP as having empty buffers. */
302 _IO_do_write (fp, data, to_do)
310 if (fp->_flags & _IO_IS_APPENDING)
311 /* On a system without a proper O_APPEND implementation,
312 you would need to sys_seek(0, SEEK_END) here, but is
313 is not needed nor desirable for Unix- or Posix-like systems.
314 Instead, just indicate that offset (before and after) is
316 fp->_offset = _IO_pos_BAD;
317 else if (fp->_IO_read_end != fp->_IO_write_base)
320 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
321 if (new_pos == _IO_pos_BAD)
323 fp->_offset = new_pos;
325 count = _IO_SYSWRITE (fp, data, to_do);
327 fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, to_do) + 1;
328 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
329 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
330 fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
331 ? fp->_IO_buf_base : fp->_IO_buf_end);
332 return count != to_do ? EOF : 0;
336 _IO_file_underflow (fp)
341 /* SysV does not make this test; take it out for compatibility */
342 if (fp->_flags & _IO_EOF_SEEN)
346 if (fp->_flags & _IO_NO_READS)
351 if (fp->_IO_read_ptr < fp->_IO_read_end)
352 return *(unsigned char *) fp->_IO_read_ptr;
354 if (fp->_IO_buf_base == NULL)
357 /* Flush all line buffered files before reading. */
358 /* FIXME This can/should be moved to genops ?? */
359 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
360 _IO_flush_all_linebuffered ();
362 _IO_switch_to_get_mode (fp);
364 /* This is very tricky. We have to adjust those
365 pointers before we call _IO_SYSREAD () since
366 we may longjump () out while waiting for
367 input. Those pointers may be screwed up. H.J. */
368 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
369 fp->_IO_read_end = fp->_IO_buf_base;
370 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
373 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
374 fp->_IO_buf_end - fp->_IO_buf_base);
378 fp->_flags |= _IO_EOF_SEEN;
380 fp->_flags |= _IO_ERR_SEEN, count = 0;
382 fp->_IO_read_end += count;
385 if (fp->_offset != _IO_pos_BAD)
386 _IO_pos_adjust (fp->_offset, count);
387 return *(unsigned char *) fp->_IO_read_ptr;
391 _IO_file_overflow (f, ch)
395 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
397 f->_flags |= _IO_ERR_SEEN;
401 /* If currently reading or no buffer allocated. */
402 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
404 /* Allocate a buffer if needed. */
405 if (f->_IO_write_base == 0)
408 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
410 /* Otherwise must be currently reading.
411 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
412 logically slide the buffer forwards one block (by setting the
413 read pointers to all point at the beginning of the block). This
414 makes room for subsequent output.
415 Otherwise, set the read pointers to _IO_read_end (leaving that
416 alone, so it can continue to correspond to the external position). */
417 if (f->_IO_read_ptr == f->_IO_buf_end)
418 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
419 f->_IO_write_ptr = f->_IO_read_ptr;
420 f->_IO_write_base = f->_IO_write_ptr;
421 f->_IO_write_end = f->_IO_buf_end;
422 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
424 if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
425 f->_IO_write_end = f->_IO_write_ptr;
426 f->_flags |= _IO_CURRENTLY_PUTTING;
429 return _IO_do_flush (f);
430 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
431 if (_IO_do_flush (f) == EOF)
433 *f->_IO_write_ptr++ = ch;
434 if ((f->_flags & _IO_UNBUFFERED)
435 || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
436 if (_IO_do_flush (f) == EOF)
438 return (unsigned char) ch;
448 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
450 /* char* ptr = cur_ptr(); */
451 if (fp->_IO_write_ptr > fp->_IO_write_base)
452 if (_IO_do_flush(fp)) return EOF;
453 delta = fp->_IO_read_ptr - fp->_IO_read_end;
457 if (_IO_in_backup (fp))
458 delta -= eGptr () - Gbase ();
460 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
461 if (new_pos != (_IO_off64_t) EOF)
462 fp->_IO_read_end = fp->_IO_read_ptr;
464 else if (errno == ESPIPE)
465 ; /* Ignore error from unseekable devices. */
471 fp->_offset = _IO_pos_BAD;
472 /* FIXME: Cleanup - can this be shared? */
473 /* setg(base(), ptr, ptr); */
474 _IO_cleanup_region_end (1);
479 _IO_file_seekoff (fp, offset, dir, mode)
486 _IO_off64_t delta, new_offset;
488 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
489 offset of the underlying file must be exact. */
490 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
491 && fp->_IO_write_base == fp->_IO_write_ptr);
494 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
496 /* Flush unwritten characters.
497 (This may do an unneeded write if we seek within the buffer.
498 But to be able to switch to reading, we would need to set
499 egptr to ptr. That can't be done in the current design,
500 which assumes file_ptr() is eGptr. Anyway, since we probably
501 end up flushing when we close(), it doesn't make much difference.)
502 FIXME: simulate mem-papped files. */
504 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
505 if (_IO_switch_to_get_mode (fp))
508 if (fp->_IO_buf_base == NULL)
511 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
512 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
518 /* Adjust for read-ahead (bytes is buffer). */
519 offset -= fp->_IO_read_end - fp->_IO_read_ptr;
520 if (fp->_offset == _IO_pos_BAD)
522 /* Make offset absolute, assuming current pointer is file_ptr(). */
523 offset += _IO_pos_as_off (fp->_offset);
532 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
534 offset += st.st_size;
541 /* At this point, dir==_IO_seek_set. */
543 /* If destination is within current buffer, optimize: */
544 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
545 && !_IO_in_backup (fp))
547 /* Offset relative to start of main get area. */
548 _IO_fpos64_t rel_offset = (offset - fp->_offset
549 + (fp->_IO_read_end - fp->_IO_read_base));
553 if (_IO_in_backup (fp))
554 _IO_switch_to_main_get_area (fp);
556 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
558 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
560 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
564 /* If we have streammarkers, seek forward by reading ahead. */
565 if (_IO_have_markers (fp))
567 int to_skip = rel_offset
568 - (fp->_IO_read_ptr - fp->_IO_read_base);
569 if (ignore (to_skip) != to_skip)
576 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
578 if (!_IO_in_backup (fp))
579 _IO_switch_to_backup_area (fp);
580 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
587 _IO_unsave_markers (fp);
590 if (fp->_flags & _IO_NO_READS)
593 /* Try to seek to a block boundary, to improve kernel page management. */
594 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
595 delta = offset - new_offset;
596 if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
601 result = _IO_SYSSEEK (fp, new_offset, 0);
608 count = _IO_SYSREAD (fp, fp->_IO_buf_base,
610 ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
613 /* We weren't allowed to read, but try to seek the remainder. */
614 offset = count == EOF ? delta : delta-count;
619 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
620 fp->_IO_buf_base + count);
621 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
622 fp->_offset = result + count;
623 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
627 _IO_unsave_markers (fp);
628 result = _IO_SYSSEEK (fp, offset, dir);
630 _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
631 fp->_offset = result;
632 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
633 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
638 _IO_file_read (fp, buf, size)
643 return read (fp->_fileno, buf, size);
647 _IO_file_seek (fp, offset, dir)
653 return _G_LSEEK64 (fp->_fileno, offset, dir);
655 return lseek (fp->_fileno, offset, dir);
660 _IO_file_stat (fp, st)
665 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st);
667 return fstat (fp->_fileno, (struct _G_stat64 *) st);
675 return close (fp->_fileno);
679 _IO_file_write (f, data, n)
684 _IO_ssize_t to_do = n;
687 _IO_ssize_t count = write (f->_fileno, data, to_do);
690 f->_flags |= _IO_ERR_SEEN;
694 data = (void *) ((char *) data + count);
703 _IO_file_xsputn (f, data, n)
708 register const char *s = (char *) data;
709 _IO_size_t to_do = n;
715 /* This is an optimized implementation.
716 If the amount to be written straddles a block boundary
717 (or the filebuf is unbuffered), use sys_write directly. */
719 /* First figure out how much space is available in the buffer. */
720 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
721 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
723 count = f->_IO_buf_end - f->_IO_write_ptr;
726 register const char *p;
727 for (p = s + n; p > s; )
738 /* Then fill the buffer. */
745 memcpy (f->_IO_write_ptr, s, count);
750 register char *p = f->_IO_write_ptr;
751 register int i = (int) count;
755 f->_IO_write_ptr += count;
758 if (to_do + must_flush > 0)
760 _IO_size_t block_size, dont_write;
761 /* Next flush the (full) buffer. */
762 if (__overflow (f, EOF) == EOF)
765 /* Try to maintain alignment: write a whole number of blocks.
766 dont_write is what gets left over. */
767 block_size = f->_IO_buf_end - f->_IO_buf_base;
768 dont_write = block_size >= 128 ? to_do % block_size : 0;
770 count = to_do - dont_write;
771 if (_IO_do_write (f, s, count) == EOF)
775 /* Now write out the remainder. Normally, this will fit in the
776 buffer, but it's somewhat messier for line-buffered files,
777 so we let _IO_default_xsputn handle the general case. */
779 to_do -= _IO_default_xsputn (f, s+count, dont_write);
785 /* Work in progress */
787 _IO_file_xsgetn (fp, data, n)
792 register _IO_size_t more = n;
793 register char *s = data;
796 /* Data available. */
797 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
804 memcpy (s, fp->_IO_read_ptr, count);
806 fp->_IO_read_ptr += count;
812 register char *p = fp->_IO_read_ptr;
813 register int i = (int) count;
816 fp->_IO_read_ptr = p;
821 if (! _IO_in put_mode (fp)
822 && ! _IO_have_markers (fp) && ! IO_have_backup (fp))
824 /* This is an optimization of _IO_file_underflow */
825 if (fp->_flags & _IO_NO_READS)
827 /* If we're reading a lot of data, don't bother allocating
828 a buffer. But if we're only reading a bit, perhaps we should ??*/
829 if (count <= 512 && fp->_IO_buf_base == NULL)
831 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
832 _IO_flush_all_linebuffered ();
834 _IO_switch_to_get_mode (fp); ???;
835 count = _IO_SYSREAD (fp, s, more);
839 fp->_flags |= _IO_EOF_SEEN;
841 fp->_flags |= _IO_ERR_SEEN, count = 0;
848 if (more == 0 || __underflow (fp) == EOF)
855 struct _IO_jump_t _IO_file_jumps =
858 JUMP_INIT(finish, _IO_file_finish),
859 JUMP_INIT(overflow, _IO_file_overflow),
860 JUMP_INIT(underflow, _IO_file_underflow),
861 JUMP_INIT(uflow, _IO_default_uflow),
862 JUMP_INIT(pbackfail, _IO_default_pbackfail),
863 JUMP_INIT(xsputn, _IO_file_xsputn),
864 JUMP_INIT(xsgetn, _IO_default_xsgetn),
865 JUMP_INIT(seekoff, _IO_file_seekoff),
866 JUMP_INIT(seekpos, _IO_default_seekpos),
867 JUMP_INIT(setbuf, _IO_file_setbuf),
868 JUMP_INIT(sync, _IO_file_sync),
869 JUMP_INIT(doallocate, _IO_file_doallocate),
870 JUMP_INIT(read, _IO_file_read),
871 JUMP_INIT(write, _IO_file_write),
872 JUMP_INIT(seek, _IO_file_seek),
873 JUMP_INIT(close, _IO_file_close),
874 JUMP_INIT(stat, _IO_file_stat),
875 JUMP_INIT(showmanyc, _IO_default_showmanyc),
876 JUMP_INIT(imbue, _IO_default_imbue)