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
));
189 /* Append [_IO_read_base.._IO_read_end] to backup area. */
190 int least_mark
= _IO_least_marker (fp
);
191 /* needed_size is how much space we need in the backup area. */
192 int needed_size
= (fp
->_IO_read_end
- fp
->_IO_read_base
) - least_mark
;
193 int current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
194 int avail
; /* Extra space available for future expansion. */
196 struct _IO_marker
*mark
;
197 if (needed_size
> current_Bsize
)
201 new_buffer
= (char *) malloc (avail
+ needed_size
);
202 if (new_buffer
== NULL
)
203 return EOF
; /* FIXME */
206 memcpy (new_buffer
+ avail
,
207 fp
->_IO_save_end
+ least_mark
,
209 memcpy (new_buffer
+ avail
- least_mark
,
211 fp
->_IO_read_end
- fp
->_IO_read_base
);
214 memcpy (new_buffer
+ avail
,
215 fp
->_IO_read_base
+ least_mark
,
217 if (fp
->_IO_save_base
)
218 free (fp
->_IO_save_base
);
219 fp
->_IO_save_base
= new_buffer
;
220 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
224 avail
= current_Bsize
- needed_size
;
227 memmove (fp
->_IO_save_base
+ avail
,
228 fp
->_IO_save_end
+ least_mark
,
230 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
232 fp
->_IO_read_end
- fp
->_IO_read_base
);
234 else if (needed_size
> 0)
235 memcpy (fp
->_IO_save_base
+ avail
,
236 fp
->_IO_read_base
+ least_mark
,
239 /* FIXME: Dubious arithmetic if pointers are NULL */
240 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
241 /* Adjust all the streammarkers. */
242 delta
= fp
->_IO_read_end
- fp
->_IO_read_base
;
243 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
252 if (_IO_in_put_mode (fp
))
253 if (_IO_switch_to_get_mode (fp
) == EOF
)
255 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
256 return *(unsigned char *) fp
->_IO_read_ptr
;
257 if (_IO_in_backup (fp
))
259 _IO_switch_to_main_get_area (fp
);
260 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
261 return *(unsigned char *) fp
->_IO_read_ptr
;
263 if (_IO_have_markers (fp
))
265 if (save_for_backup (fp
))
268 else if (_IO_have_backup (fp
))
269 _IO_free_backup_area (fp
);
270 return _IO_UNDERFLOW (fp
);
277 if (_IO_in_put_mode (fp
))
278 if (_IO_switch_to_get_mode (fp
) == EOF
)
280 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
281 return *(unsigned char *) fp
->_IO_read_ptr
++;
282 if (_IO_in_backup (fp
))
284 _IO_switch_to_main_get_area (fp
);
285 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
286 return *(unsigned char *) fp
->_IO_read_ptr
++;
288 if (_IO_have_markers (fp
))
290 if (save_for_backup (fp
))
293 else if (_IO_have_backup (fp
))
294 _IO_free_backup_area (fp
);
295 return _IO_UFLOW (fp
);
299 _IO_setb (f
, b
, eb
, a
)
305 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
306 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
310 f
->_flags
&= ~_IO_USER_BUF
;
312 f
->_flags
|= _IO_USER_BUF
;
319 if (fp
->_IO_buf_base
)
321 if (!(fp
->_flags
& _IO_UNBUFFERED
))
322 if (_IO_DOALLOCATE (fp
) != EOF
)
324 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
328 _IO_default_underflow (fp
)
335 _IO_default_uflow (fp
)
338 int ch
= _IO_UNDERFLOW (fp
);
341 return *(unsigned char *) fp
->_IO_read_ptr
++;
345 _IO_default_xsputn (f
, data
, n
)
350 const char *s
= (char *) data
;
356 /* Space available. */
357 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
360 if ((_IO_size_t
) count
> more
)
364 memcpy (f
->_IO_write_ptr
, s
, count
);
366 f
->_IO_write_ptr
+= count
;
372 char *p
= f
->_IO_write_ptr
;
374 for (i
= count
; --i
>= 0; )
376 f
->_IO_write_ptr
= p
;
380 if (more
== 0 || __overflow (f
, (unsigned char) *s
++) == EOF
)
388 _IO_sgetn (fp
, data
, n
)
393 /* FIXME handle putback buffer here! */
394 return _IO_XSGETN (fp
, data
, n
);
398 _IO_default_xsgetn (fp
, data
, n
)
404 char *s
= (char*) data
;
407 /* Data available. */
408 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
411 if ((_IO_size_t
) count
> more
)
415 memcpy (s
, fp
->_IO_read_ptr
, count
);
417 fp
->_IO_read_ptr
+= count
;
423 char *p
= fp
->_IO_read_ptr
;
427 fp
->_IO_read_ptr
= p
;
431 if (more
== 0 || __underflow (fp
) == EOF
)
438 /* Seems not to be needed. --drepper */
448 _IO_default_setbuf (fp
, p
, len
)
453 if (_IO_SYNC (fp
) == EOF
)
455 if (p
== NULL
|| len
== 0)
457 fp
->_flags
|= _IO_UNBUFFERED
;
458 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
462 fp
->_flags
&= ~_IO_UNBUFFERED
;
463 _IO_setb (fp
, p
, p
+len
, 0);
465 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
466 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
471 _IO_default_seekpos (fp
, pos
, mode
)
476 return _IO_SEEKOFF (fp
, _IO_pos_as_off (pos
), 0, mode
);
480 _IO_default_doallocate (fp
)
485 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
486 _IO_setb (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
495 fp
->_flags
= _IO_MAGIC
|flags
;
496 fp
->_IO_buf_base
= NULL
;
497 fp
->_IO_buf_end
= NULL
;
498 fp
->_IO_read_base
= NULL
;
499 fp
->_IO_read_ptr
= NULL
;
500 fp
->_IO_read_end
= NULL
;
501 fp
->_IO_write_base
= NULL
;
502 fp
->_IO_write_ptr
= NULL
;
503 fp
->_IO_write_end
= NULL
;
504 fp
->_chain
= NULL
; /* Not necessary. */
506 fp
->_IO_save_base
= NULL
;
507 fp
->_IO_backup_base
= NULL
;
508 fp
->_IO_save_end
= NULL
;
512 _IO_lock_init (*fp
->_lock
);
517 _IO_default_sync (fp
)
523 /* The way the C++ classes are mapped into the C functions in the
524 current implementation, this function can get called twice! */
527 _IO_default_finish (fp
, dummy
)
531 struct _IO_marker
*mark
;
532 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
534 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
535 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
538 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
541 if (fp
->_IO_save_base
)
543 free (fp
->_IO_save_base
);
544 fp
->_IO_save_base
= NULL
;
548 _IO_lock_fini (*fp
->_lock
);
555 _IO_default_seekoff (fp
, offset
, dir
, mode
)
565 _IO_sputbackc (fp
, c
)
571 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
572 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
575 result
= (unsigned char) c
;
578 result
= _IO_PBACKFAIL (fp
, c
);
581 fp
->_flags
&= ~_IO_EOF_SEEN
;
592 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
595 result
= (unsigned char) *fp
->_IO_read_ptr
;
598 result
= _IO_PBACKFAIL (fp
, EOF
);
601 fp
->_flags
&= ~_IO_EOF_SEEN
;
606 #if 0 /* Work in progress */
607 /* Seems not to be needed. */
610 _IO_set_column (fp
, c
)
617 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
621 _IO_set_column (fp
, i
)
625 fp
->_cur_column
= i
+ 1;
633 _IO_adjust_column (start
, line
, count
)
638 const char *ptr
= line
+ count
;
641 return line
+ count
- ptr
- 1;
642 return start
+ count
;
646 /* Seems not to be needed. --drepper */
652 return _IO_adjust_column (fp
->_cur_column
- 1,
654 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
664 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
665 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
666 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
672 _IO_flush_all_linebuffered ()
675 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
676 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
677 _IO_OVERFLOW (fp
, EOF
);
680 static void _IO_unbuffer_all
__P ((void));
686 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
687 if (! (fp
->_flags
& _IO_UNBUFFERED
))
688 _IO_SETBUF (fp
, NULL
, 0);
696 /* We currently don't have a reliable mechanism for making sure that
697 C++ static destructors are executed in the correct order.
698 So it is possible that other static destructors might want to
699 write to cout - and they're supposed to be able to do so.
701 The following will make the standard streambufs be unbuffered,
702 which forces any output from late destructors to be written out. */
707 _IO_init_marker (marker
, fp
)
708 struct _IO_marker
*marker
;
712 if (_IO_in_put_mode (fp
))
713 _IO_switch_to_get_mode (fp
);
714 if (_IO_in_backup (fp
))
715 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
717 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
719 /* Should perhaps sort the chain? */
720 marker
->_next
= fp
->_markers
;
721 fp
->_markers
= marker
;
725 _IO_remove_marker (marker
)
726 struct _IO_marker
*marker
;
728 /* Unlink from sb's chain. */
729 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
730 for (; ; ptr
= &(*ptr
)->_next
)
734 else if (*ptr
== marker
)
736 *ptr
= marker
->_next
;
741 if _sbuf has a backup area that is no longer needed
, should we
delete
742 it now
, or wait until the next underflow
?
746 #define BAD_DELTA EOF
749 _IO_marker_difference (mark1
, mark2
)
750 struct _IO_marker
*mark1
;
751 struct _IO_marker
*mark2
;
753 return mark1
->_pos
- mark2
->_pos
;
756 /* Return difference between MARK and current position of MARK's stream. */
758 _IO_marker_delta (mark
)
759 struct _IO_marker
*mark
;
762 if (mark
->_sbuf
== NULL
)
764 if (_IO_in_backup (mark
->_sbuf
))
765 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
767 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
768 return mark
->_pos
- cur_pos
;
772 _IO_seekmark (fp
, mark
, delta
)
774 struct _IO_marker
*mark
;
777 if (mark
->_sbuf
!= fp
)
781 if (_IO_in_backup (fp
))
782 _IO_switch_to_main_get_area (fp
);
783 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
787 if (!_IO_in_backup (fp
))
788 _IO_switch_to_backup_area (fp
);
789 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
795 _IO_unsave_markers (fp
)
798 struct _IO_marker
*mark
= fp
->_markers
;
802 streampos offset
= seekoff (0, ios::cur
, ios::in
);
805 offset
+= eGptr () - Gbase ();
806 for ( ; mark
!= NULL
; mark
= mark
->_next
)
807 mark
->set_streampos (mark
->_pos
+ offset
);
811 for ( ; mark
!= NULL
; mark
= mark
->_next
)
812 mark
->set_streampos (EOF
);
818 if (_IO_have_backup (fp
))
819 _IO_free_backup_area (fp
);
823 /* Seems not to be needed. --drepper */
825 _IO_nobackup_pbackfail (fp
, c
)
829 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
831 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
832 *fp
->_IO_read_ptr
= c
;
833 return (unsigned char) c
;
838 _IO_default_pbackfail (fp
, c
)
842 if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
844 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
845 if (_IO_have_backup (fp
) && !_IO_in_backup (fp
))
846 _IO_switch_to_backup_area (fp
);
848 if (!_IO_have_backup (fp
))
850 /* No backup buffer: allocate one. */
851 /* Use nshort buffer, if unused? (probably not) FIXME */
852 int backup_size
= 128;
853 char *bbuf
= (char *) malloc (backup_size
);
856 fp
->_IO_save_base
= bbuf
;
857 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
858 fp
->_IO_backup_base
= fp
->_IO_save_end
;
859 _IO_switch_to_backup_area (fp
);
861 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
863 /* Increase size of existing backup buffer. */
865 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
867 new_size
= 2 * old_size
;
868 new_buf
= (char *) malloc (new_size
);
871 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
873 free (fp
->_IO_read_base
);
874 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
876 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
880 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
881 *fp
->_IO_read_ptr
= c
;
882 return (unsigned char) *fp
->_IO_read_ptr
;
886 _IO_default_seek (fp
, offset
, dir
)
895 _IO_default_stat (fp
, st
)
903 _IO_default_read (fp
, data
, n
)
912 _IO_default_write (fp
, data
, n
)
931 ~__io_defs() { _IO_cleanup (); }
939 weak_alias (_IO_cleanup
, _cleanup
)
940 #elif defined(_G_STDIO_USES_LIBIO) && defined(_G_HAVE_WEAK_SYMBOL)
941 void _cleanup () __attribute__ ((weak
, alias ("_IO_cleanup")));
944 #ifdef text_set_element
945 text_set_element(__libc_atexit
, _cleanup
);