1 /* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this library; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does
21 not cause the resulting executable to be covered by the GNU General
22 Public License. This exception does not however invalidate any
23 other reasons why the executable file might be covered by the GNU
24 General Public License. */
26 /* Generic or default I/O operations. */
38 if (fp->_flags & _IO_LINKED)
41 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
49 fp->_flags &= ~_IO_LINKED;
57 if ((fp->_flags & _IO_LINKED) == 0)
59 fp->_flags |= _IO_LINKED;
60 fp->_chain = _IO_list_all;
65 /* Return minimum _pos markers
66 Assumes the current get area is the main get area. */
67 static _IO_size_t _IO_least_marker __P ((_IO_FILE *fp));
73 _IO_ssize_t least_so_far = fp->_IO_read_end - fp->_IO_read_base;
74 struct _IO_marker *mark;
75 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
76 if (mark->_pos < least_so_far)
77 least_so_far = mark->_pos;
81 /* Switch current get area from backup buffer to (start of) main get area. */
84 _IO_switch_to_main_get_area (fp)
88 fp->_flags &= ~_IO_IN_BACKUP;
89 /* Swap _IO_read_end and _IO_save_end. */
90 tmp = fp->_IO_read_end;
91 fp->_IO_read_end = fp->_IO_save_end;
92 fp->_IO_save_end= tmp;
93 /* Swap _IO_read_base and _IO_save_base. */
94 tmp = fp->_IO_read_base;
95 fp->_IO_read_base = fp->_IO_save_base;
96 fp->_IO_save_base = tmp;
98 fp->_IO_read_ptr = fp->_IO_read_base;
101 /* Switch current get area from main get area to (end of) backup area. */
104 _IO_switch_to_backup_area (fp)
108 fp->_flags |= _IO_IN_BACKUP;
109 /* Swap _IO_read_end and _IO_save_end. */
110 tmp = fp->_IO_read_end;
111 fp->_IO_read_end = fp->_IO_save_end;
112 fp->_IO_save_end = tmp;
113 /* Swap _gbase and _IO_save_base. */
114 tmp = fp->_IO_read_base;
115 fp->_IO_read_base = fp->_IO_save_base;
116 fp->_IO_save_base = tmp;
118 fp->_IO_read_ptr = fp->_IO_read_end;
122 _IO_switch_to_get_mode (fp)
125 if (fp->_IO_write_ptr > fp->_IO_write_base)
126 if (_IO_OVERFLOW (fp, EOF) == EOF)
128 if (_IO_in_backup (fp))
129 fp->_IO_read_base = fp->_IO_backup_base;
132 fp->_IO_read_base = fp->_IO_buf_base;
133 if (fp->_IO_write_ptr > fp->_IO_read_end)
134 fp->_IO_read_end = fp->_IO_write_ptr;
136 fp->_IO_read_ptr = fp->_IO_write_ptr;
138 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
140 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
145 _IO_free_backup_area (fp)
148 if (_IO_in_backup (fp))
149 _IO_switch_to_main_get_area (fp); /* Just in case. */
150 free (fp->_IO_save_base);
151 fp->_IO_save_base = NULL;
152 fp->_IO_save_end = NULL;
153 fp->_IO_backup_base = NULL;
158 _IO_switch_to_put_mode (fp)
161 fp->_IO_write_base = fp->_IO_read_ptr;
162 fp->_IO_write_ptr = fp->_IO_read_ptr;
163 /* Following is wrong if line- or un-buffered? */
164 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
165 ? fp->_IO_read_end : fp->_IO_buf_end);
167 fp->_IO_read_ptr = fp->_IO_read_end;
168 fp->_IO_read_base = fp->_IO_read_end;
170 fp->_flags |= _IO_CURRENTLY_PUTTING;
180 return _IO_OVERFLOW (f, ch);
183 static int save_for_backup __P ((_IO_FILE *fp))
196 /* Append [_IO_read_base.._IO_read_end] to backup area. */
197 int least_mark = _IO_least_marker (fp);
198 /* needed_size is how much space we need in the backup area. */
199 int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
200 int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
201 int avail; /* Extra space available for future expansion. */
203 struct _IO_marker *mark;
204 if (needed_size > current_Bsize)
208 new_buffer = (char *) malloc (avail + needed_size);
209 if (new_buffer == NULL)
210 return EOF; /* FIXME */
214 __mempcpy (__mempcpy (new_buffer + avail,
215 fp->_IO_save_end + least_mark,
218 fp->_IO_read_end - fp->_IO_read_base);
220 memcpy (new_buffer + avail,
221 fp->_IO_save_end + least_mark,
223 memcpy (new_buffer + avail - least_mark,
225 fp->_IO_read_end - fp->_IO_read_base);
229 memcpy (new_buffer + avail,
230 fp->_IO_read_base + least_mark,
232 if (fp->_IO_save_base)
233 free (fp->_IO_save_base);
234 fp->_IO_save_base = new_buffer;
235 fp->_IO_save_end = new_buffer + avail + needed_size;
239 avail = current_Bsize - needed_size;
242 memmove (fp->_IO_save_base + avail,
243 fp->_IO_save_end + least_mark,
245 memcpy (fp->_IO_save_base + avail - least_mark,
247 fp->_IO_read_end - fp->_IO_read_base);
249 else if (needed_size > 0)
250 memcpy (fp->_IO_save_base + avail,
251 fp->_IO_read_base + least_mark,
254 /* FIXME: Dubious arithmetic if pointers are NULL */
255 fp->_IO_backup_base = fp->_IO_save_base + avail;
256 /* Adjust all the streammarkers. */
257 delta = fp->_IO_read_end - fp->_IO_read_base;
258 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
267 if (_IO_in_put_mode (fp))
268 if (_IO_switch_to_get_mode (fp) == EOF)
270 if (fp->_IO_read_ptr < fp->_IO_read_end)
271 return *(unsigned char *) fp->_IO_read_ptr;
272 if (_IO_in_backup (fp))
274 _IO_switch_to_main_get_area (fp);
275 if (fp->_IO_read_ptr < fp->_IO_read_end)
276 return *(unsigned char *) fp->_IO_read_ptr;
278 if (_IO_have_markers (fp))
280 if (save_for_backup (fp))
283 else if (_IO_have_backup (fp))
284 _IO_free_backup_area (fp);
285 return _IO_UNDERFLOW (fp);
292 if (_IO_in_put_mode (fp))
293 if (_IO_switch_to_get_mode (fp) == EOF)
295 if (fp->_IO_read_ptr < fp->_IO_read_end)
296 return *(unsigned char *) fp->_IO_read_ptr++;
297 if (_IO_in_backup (fp))
299 _IO_switch_to_main_get_area (fp);
300 if (fp->_IO_read_ptr < fp->_IO_read_end)
301 return *(unsigned char *) fp->_IO_read_ptr++;
303 if (_IO_have_markers (fp))
305 if (save_for_backup (fp))
308 else if (_IO_have_backup (fp))
309 _IO_free_backup_area (fp);
310 return _IO_UFLOW (fp);
314 _IO_setb (f, b, eb, a)
320 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
321 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
325 f->_flags &= ~_IO_USER_BUF;
327 f->_flags |= _IO_USER_BUF;
334 if (fp->_IO_buf_base)
336 if (!(fp->_flags & _IO_UNBUFFERED))
337 if (_IO_DOALLOCATE (fp) != EOF)
339 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
343 _IO_default_underflow (fp)
350 _IO_default_uflow (fp)
353 int ch = _IO_UNDERFLOW (fp);
356 return *(unsigned char *) fp->_IO_read_ptr++;
360 _IO_default_xsputn (f, data, n)
365 const char *s = (char *) data;
371 /* Space available. */
372 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
375 if ((_IO_size_t) count > more)
380 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
382 memcpy (f->_IO_write_ptr, s, count);
383 f->_IO_write_ptr += count;
391 char *p = f->_IO_write_ptr;
393 for (i = count; --i >= 0; )
395 f->_IO_write_ptr = p;
399 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
407 _IO_sgetn (fp, data, n)
412 /* FIXME handle putback buffer here! */
413 return _IO_XSGETN (fp, data, n);
417 _IO_default_xsgetn (fp, data, n)
423 char *s = (char*) data;
426 /* Data available. */
427 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
430 if ((_IO_size_t) count > more)
435 s = __mempcpy (s, fp->_IO_read_ptr, count);
437 memcpy (s, fp->_IO_read_ptr, count);
440 fp->_IO_read_ptr += count;
446 char *p = fp->_IO_read_ptr;
450 fp->_IO_read_ptr = p;
454 if (more == 0 || __underflow (fp) == EOF)
461 /* Seems not to be needed. --drepper */
471 _IO_default_setbuf (fp, p, len)
476 if (_IO_SYNC (fp) == EOF)
478 if (p == NULL || len == 0)
480 fp->_flags |= _IO_UNBUFFERED;
481 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
485 fp->_flags &= ~_IO_UNBUFFERED;
486 _IO_setb (fp, p, p+len, 0);
488 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
489 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
494 _IO_default_seekpos (fp, pos, mode)
499 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
503 _IO_default_doallocate (fp)
508 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
509 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
518 fp->_flags = _IO_MAGIC|flags;
519 fp->_IO_buf_base = NULL;
520 fp->_IO_buf_end = NULL;
521 fp->_IO_read_base = NULL;
522 fp->_IO_read_ptr = NULL;
523 fp->_IO_read_end = NULL;
524 fp->_IO_write_base = NULL;
525 fp->_IO_write_ptr = NULL;
526 fp->_IO_write_end = NULL;
527 fp->_chain = NULL; /* Not necessary. */
529 fp->_IO_save_base = NULL;
530 fp->_IO_backup_base = NULL;
531 fp->_IO_save_end = NULL;
535 fp->_vtable_offset = 0;
538 _IO_lock_init (*fp->_lock);
543 _IO_default_sync (fp)
549 /* The way the C++ classes are mapped into the C functions in the
550 current implementation, this function can get called twice! */
553 _IO_default_finish (fp, dummy)
557 struct _IO_marker *mark;
558 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
560 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
561 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
564 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
567 if (fp->_IO_save_base)
569 free (fp->_IO_save_base);
570 fp->_IO_save_base = NULL;
574 _IO_lock_fini (*fp->_lock);
581 _IO_default_seekoff (fp, offset, dir, mode)
591 _IO_sputbackc (fp, c)
597 if (fp->_IO_read_ptr > fp->_IO_read_base
598 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
601 result = (unsigned char) c;
604 result = _IO_PBACKFAIL (fp, c);
607 fp->_flags &= ~_IO_EOF_SEEN;
618 if (fp->_IO_read_ptr > fp->_IO_read_base)
621 result = (unsigned char) *fp->_IO_read_ptr;
624 result = _IO_PBACKFAIL (fp, EOF);
627 fp->_flags &= ~_IO_EOF_SEEN;
632 #if 0 /* Work in progress */
633 /* Seems not to be needed. */
636 _IO_set_column (fp, c)
643 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
647 _IO_set_column (fp, i)
651 fp->_cur_column = i + 1;
659 _IO_adjust_column (start, line, count)
664 const char *ptr = line + count;
667 return line + count - ptr - 1;
668 return start + count;
672 /* Seems not to be needed. --drepper */
678 return _IO_adjust_column (fp->_cur_column - 1,
680 fp->_IO_write_ptr - fp->_IO_write_base);
690 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
691 if (fp->_IO_write_ptr > fp->_IO_write_base
692 && _IO_OVERFLOW (fp, EOF) == EOF)
698 _IO_flush_all_linebuffered ()
701 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
702 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
703 _IO_OVERFLOW (fp, EOF);
706 static void _IO_unbuffer_all __P ((void));
712 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
713 if (! (fp->_flags & _IO_UNBUFFERED))
714 _IO_SETBUF (fp, NULL, 0);
720 int result = _IO_flush_all ();
722 /* We currently don't have a reliable mechanism for making sure that
723 C++ static destructors are executed in the correct order.
724 So it is possible that other static destructors might want to
725 write to cout - and they're supposed to be able to do so.
727 The following will make the standard streambufs be unbuffered,
728 which forces any output from late destructors to be written out. */
736 _IO_init_marker (marker, fp)
737 struct _IO_marker *marker;
741 if (_IO_in_put_mode (fp))
742 _IO_switch_to_get_mode (fp);
743 if (_IO_in_backup (fp))
744 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
746 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
748 /* Should perhaps sort the chain? */
749 marker->_next = fp->_markers;
750 fp->_markers = marker;
754 _IO_remove_marker (marker)
755 struct _IO_marker *marker;
757 /* Unlink from sb's chain. */
758 struct _IO_marker **ptr = &marker->_sbuf->_markers;
759 for (; ; ptr = &(*ptr)->_next)
763 else if (*ptr == marker)
765 *ptr = marker->_next;
770 if _sbuf has a backup area that is no longer needed, should we delete
771 it now, or wait until the next underflow?
775 #define BAD_DELTA EOF
778 _IO_marker_difference (mark1, mark2)
779 struct _IO_marker *mark1;
780 struct _IO_marker *mark2;
782 return mark1->_pos - mark2->_pos;
785 /* Return difference between MARK and current position of MARK's stream. */
787 _IO_marker_delta (mark)
788 struct _IO_marker *mark;
791 if (mark->_sbuf == NULL)
793 if (_IO_in_backup (mark->_sbuf))
794 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
796 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
797 return mark->_pos - cur_pos;
801 _IO_seekmark (fp, mark, delta)
803 struct _IO_marker *mark;
806 if (mark->_sbuf != fp)
810 if (_IO_in_backup (fp))
811 _IO_switch_to_main_get_area (fp);
812 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
816 if (!_IO_in_backup (fp))
817 _IO_switch_to_backup_area (fp);
818 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
824 _IO_unsave_markers (fp)
827 struct _IO_marker *mark = fp->_markers;
831 streampos offset = seekoff (0, ios::cur, ios::in);
834 offset += eGptr () - Gbase ();
835 for ( ; mark != NULL; mark = mark->_next)
836 mark->set_streampos (mark->_pos + offset);
840 for ( ; mark != NULL; mark = mark->_next)
841 mark->set_streampos (EOF);
847 if (_IO_have_backup (fp))
848 _IO_free_backup_area (fp);
852 /* Seems not to be needed. --drepper */
854 _IO_nobackup_pbackfail (fp, c)
858 if (fp->_IO_read_ptr > fp->_IO_read_base)
860 if (c != EOF && *fp->_IO_read_ptr != c)
861 *fp->_IO_read_ptr = c;
862 return (unsigned char) c;
867 _IO_default_pbackfail (fp, c)
871 if (fp->_IO_read_ptr <= fp->_IO_read_base)
873 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
874 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
875 _IO_switch_to_backup_area (fp);
877 if (!_IO_have_backup (fp))
879 /* No backup buffer: allocate one. */
880 /* Use nshort buffer, if unused? (probably not) FIXME */
881 int backup_size = 128;
882 char *bbuf = (char *) malloc (backup_size);
885 fp->_IO_save_base = bbuf;
886 fp->_IO_save_end = fp->_IO_save_base + backup_size;
887 fp->_IO_backup_base = fp->_IO_save_end;
888 _IO_switch_to_backup_area (fp);
890 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
892 /* Increase size of existing backup buffer. */
894 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
896 new_size = 2 * old_size;
897 new_buf = (char *) malloc (new_size);
900 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
902 free (fp->_IO_read_base);
903 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
905 fp->_IO_backup_base = fp->_IO_read_ptr;
909 if (c != EOF && *fp->_IO_read_ptr != c)
910 *fp->_IO_read_ptr = c;
911 return (unsigned char) *fp->_IO_read_ptr;
915 _IO_default_seek (fp, offset, dir)
924 _IO_default_stat (fp, st)
932 _IO_default_read (fp, data, n)
941 _IO_default_write (fp, data, n)
950 _IO_default_showmanyc (fp)
957 _IO_default_imbue (fp, locale)
974 ~__io_defs() { _IO_cleanup (); }
982 weak_alias (_IO_cleanup, _cleanup)
985 #ifdef text_set_element
986 text_set_element(__libc_atexit, _cleanup);