1 /* Copyright (C) 1993, 1995, 1997 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 */
213 memcpy (new_buffer + avail,
214 fp->_IO_save_end + least_mark,
216 memcpy (new_buffer + avail - least_mark,
218 fp->_IO_read_end - fp->_IO_read_base);
221 memcpy (new_buffer + avail,
222 fp->_IO_read_base + least_mark,
224 if (fp->_IO_save_base)
225 free (fp->_IO_save_base);
226 fp->_IO_save_base = new_buffer;
227 fp->_IO_save_end = new_buffer + avail + needed_size;
231 avail = current_Bsize - needed_size;
234 memmove (fp->_IO_save_base + avail,
235 fp->_IO_save_end + least_mark,
237 memcpy (fp->_IO_save_base + avail - least_mark,
239 fp->_IO_read_end - fp->_IO_read_base);
241 else if (needed_size > 0)
242 memcpy (fp->_IO_save_base + avail,
243 fp->_IO_read_base + least_mark,
246 /* FIXME: Dubious arithmetic if pointers are NULL */
247 fp->_IO_backup_base = fp->_IO_save_base + avail;
248 /* Adjust all the streammarkers. */
249 delta = fp->_IO_read_end - fp->_IO_read_base;
250 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
259 if (_IO_in_put_mode (fp))
260 if (_IO_switch_to_get_mode (fp) == EOF)
262 if (fp->_IO_read_ptr < fp->_IO_read_end)
263 return *(unsigned char *) fp->_IO_read_ptr;
264 if (_IO_in_backup (fp))
266 _IO_switch_to_main_get_area (fp);
267 if (fp->_IO_read_ptr < fp->_IO_read_end)
268 return *fp->_IO_read_ptr;
270 if (_IO_have_markers (fp))
272 if (save_for_backup (fp))
275 else if (_IO_have_backup (fp))
276 _IO_free_backup_area (fp);
277 return _IO_UNDERFLOW (fp);
284 if (_IO_in_put_mode (fp))
285 if (_IO_switch_to_get_mode (fp) == EOF)
287 if (fp->_IO_read_ptr < fp->_IO_read_end)
288 return *(unsigned char *) fp->_IO_read_ptr++;
289 if (_IO_in_backup (fp))
291 _IO_switch_to_main_get_area (fp);
292 if (fp->_IO_read_ptr < fp->_IO_read_end)
293 return *fp->_IO_read_ptr++;
295 if (_IO_have_markers (fp))
297 if (save_for_backup (fp))
300 else if (_IO_have_backup (fp))
301 _IO_free_backup_area (fp);
302 return _IO_UFLOW (fp);
306 _IO_setb (f, b, eb, a)
312 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
313 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
317 f->_flags &= ~_IO_USER_BUF;
319 f->_flags |= _IO_USER_BUF;
326 if (fp->_IO_buf_base)
328 if (!(fp->_flags & _IO_UNBUFFERED))
329 if (_IO_DOALLOCATE (fp) != EOF)
331 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
335 _IO_default_underflow (fp)
342 _IO_default_uflow (fp)
345 int ch = _IO_UNDERFLOW (fp);
348 return *(unsigned char *) fp->_IO_read_ptr++;
352 _IO_default_xsputn (f, data, n)
357 const char *s = (char *) data;
363 /* Space available. */
364 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
367 if ((_IO_size_t) count > more)
371 memcpy (f->_IO_write_ptr, s, count);
373 f->_IO_write_ptr += count;
379 char *p = f->_IO_write_ptr;
381 for (i = count; --i >= 0; )
383 f->_IO_write_ptr = p;
387 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
395 _IO_sgetn (fp, data, n)
400 /* FIXME handle putback buffer here! */
401 return _IO_XSGETN (fp, data, n);
405 _IO_default_xsgetn (fp, data, n)
411 char *s = (char*) data;
414 /* Data available. */
415 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
418 if ((_IO_size_t) count > more)
422 memcpy (s, fp->_IO_read_ptr, count);
424 fp->_IO_read_ptr += count;
430 char *p = fp->_IO_read_ptr;
434 fp->_IO_read_ptr = p;
438 if (more == 0 || __underflow (fp) == EOF)
445 /* Seems not to be needed. --drepper */
455 _IO_default_setbuf (fp, p, len)
460 if (_IO_SYNC (fp) == EOF)
462 if (p == NULL || len == 0)
464 fp->_flags |= _IO_UNBUFFERED;
465 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
469 fp->_flags &= ~_IO_UNBUFFERED;
470 _IO_setb (fp, p, p+len, 0);
472 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
473 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
478 _IO_default_seekpos (fp, pos, mode)
483 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
487 _IO_default_doallocate (fp)
492 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
493 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
502 fp->_flags = _IO_MAGIC|flags;
503 fp->_IO_buf_base = NULL;
504 fp->_IO_buf_end = NULL;
505 fp->_IO_read_base = NULL;
506 fp->_IO_read_ptr = NULL;
507 fp->_IO_read_end = NULL;
508 fp->_IO_write_base = NULL;
509 fp->_IO_write_ptr = NULL;
510 fp->_IO_write_end = NULL;
511 fp->_chain = NULL; /* Not necessary. */
513 fp->_IO_save_base = NULL;
514 fp->_IO_backup_base = NULL;
515 fp->_IO_save_end = NULL;
519 _IO_lock_init (*fp->_lock);
524 _IO_default_sync (fp)
530 /* The way the C++ classes are mapped into the C functions in the
531 current implementation, this function can get called twice! */
534 _IO_default_finish (fp, dummy)
538 struct _IO_marker *mark;
539 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
541 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
542 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
545 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
548 if (fp->_IO_save_base)
550 free (fp->_IO_save_base);
551 fp->_IO_save_base = NULL;
555 _IO_lock_fini (*fp->_lock);
562 _IO_default_seekoff (fp, offset, dir, mode)
572 _IO_sputbackc (fp, c)
578 if (fp->_IO_read_ptr > fp->_IO_read_base
579 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
582 result = (unsigned char) c;
585 result = _IO_PBACKFAIL (fp, c);
588 fp->_flags &= ~_IO_EOF_SEEN;
599 if (fp->_IO_read_ptr > fp->_IO_read_base)
602 result = (unsigned char) *fp->_IO_read_ptr;
605 result = _IO_PBACKFAIL (fp, EOF);
608 fp->_flags &= ~_IO_EOF_SEEN;
613 #if 0 /* Work in progress */
614 /* Seems not to be needed. */
617 _IO_set_column (fp, c)
624 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
628 _IO_set_column (fp, i)
632 fp->_cur_column = i + 1;
640 _IO_adjust_column (start, line, count)
645 const char *ptr = line + count;
648 return line + count - ptr - 1;
649 return start + count;
653 /* Seems not to be needed. --drepper */
659 return _IO_adjust_column (fp->_cur_column - 1,
661 fp->_IO_write_ptr - fp->_IO_write_base);
671 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
672 if (fp->_IO_write_ptr > fp->_IO_write_base
673 && _IO_OVERFLOW (fp, EOF) == EOF)
679 _IO_flush_all_linebuffered ()
682 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
683 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
684 _IO_OVERFLOW (fp, EOF);
687 static void _IO_unbuffer_all __P ((void));
693 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
694 if (! (fp->_flags & _IO_UNBUFFERED))
695 _IO_SETBUF (fp, NULL, 0);
703 /* We currently don't have a reliable mechanism for making sure that
704 C++ static destructors are executed in the correct order.
705 So it is possible that other static destructors might want to
706 write to cout - and they're supposed to be able to do so.
708 The following will make the standard streambufs be unbuffered,
709 which forces any output from late destructors to be written out. */
715 _IO_init_marker (marker, fp)
716 struct _IO_marker *marker;
720 if (_IO_in_put_mode (fp))
721 _IO_switch_to_get_mode (fp);
722 if (_IO_in_backup (fp))
723 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
725 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
727 /* Should perhaps sort the chain? */
728 marker->_next = fp->_markers;
729 fp->_markers = marker;
733 _IO_remove_marker (marker)
734 struct _IO_marker *marker;
736 /* Unlink from sb's chain. */
737 struct _IO_marker **ptr = &marker->_sbuf->_markers;
738 for (; ; ptr = &(*ptr)->_next)
742 else if (*ptr == marker)
744 *ptr = marker->_next;
749 if _sbuf has a backup area that is no longer needed, should we delete
750 it now, or wait until the next underflow?
754 #define BAD_DELTA EOF
757 _IO_marker_difference (mark1, mark2)
758 struct _IO_marker *mark1;
759 struct _IO_marker *mark2;
761 return mark1->_pos - mark2->_pos;
764 /* Return difference between MARK and current position of MARK's stream. */
766 _IO_marker_delta (mark)
767 struct _IO_marker *mark;
770 if (mark->_sbuf == NULL)
772 if (_IO_in_backup (mark->_sbuf))
773 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
775 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
776 return mark->_pos - cur_pos;
780 _IO_seekmark (fp, mark, delta)
782 struct _IO_marker *mark;
785 if (mark->_sbuf != fp)
789 if (_IO_in_backup (fp))
790 _IO_switch_to_main_get_area (fp);
791 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
795 if (!_IO_in_backup (fp))
796 _IO_switch_to_backup_area (fp);
797 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
803 _IO_unsave_markers (fp)
806 struct _IO_marker *mark = fp->_markers;
810 streampos offset = seekoff (0, ios::cur, ios::in);
813 offset += eGptr () - Gbase ();
814 for ( ; mark != NULL; mark = mark->_next)
815 mark->set_streampos (mark->_pos + offset);
819 for ( ; mark != NULL; mark = mark->_next)
820 mark->set_streampos (EOF);
826 if (_IO_have_backup (fp))
827 _IO_free_backup_area (fp);
831 /* Seems not to be needed. --drepper */
833 _IO_nobackup_pbackfail (fp, c)
837 if (fp->_IO_read_ptr > fp->_IO_read_base)
839 if (c != EOF && *fp->_IO_read_ptr != c)
840 *fp->_IO_read_ptr = c;
841 return (unsigned char) c;
846 _IO_default_pbackfail (fp, c)
850 if (fp->_IO_read_ptr <= fp->_IO_read_base)
852 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
853 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
854 _IO_switch_to_backup_area (fp);
856 if (!_IO_have_backup (fp))
858 /* No backup buffer: allocate one. */
859 /* Use nshort buffer, if unused? (probably not) FIXME */
860 int backup_size = 128;
861 char *bbuf = (char *) malloc (backup_size);
864 fp->_IO_save_base = bbuf;
865 fp->_IO_save_end = fp->_IO_save_base + backup_size;
866 fp->_IO_backup_base = fp->_IO_save_end;
867 _IO_switch_to_backup_area (fp);
869 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
871 /* Increase size of existing backup buffer. */
873 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
875 new_size = 2 * old_size;
876 new_buf = (char *) malloc (new_size);
879 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
881 free (fp->_IO_read_base);
882 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
884 fp->_IO_backup_base = fp->_IO_read_ptr;
888 if (c != EOF && *fp->_IO_read_ptr != c)
889 *fp->_IO_read_ptr = c;
890 return (unsigned char) *fp->_IO_read_ptr;
894 _IO_default_seek (fp, offset, dir)
903 _IO_default_stat (fp, st)
911 _IO_default_read (fp, data, n)
920 _IO_default_write (fp, data, n)
929 _IO_default_showmanyc (fp)
936 _IO_default_imbue (fp, locale)
953 ~__io_defs() { _IO_cleanup (); }
961 weak_alias (_IO_cleanup, _cleanup)
964 #ifdef text_set_element
965 text_set_element(__libc_atexit, _cleanup);