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. */
34 static _IO_lock_t list_all_lock
= _IO_lock_initializer
;
40 if (fp
->_flags
& _IO_LINKED
)
43 _IO_lock_lock (list_all_lock
);
44 for (f
= &_IO_list_all
; *f
!= NULL
; f
= &(*f
)->_chain
)
52 _IO_lock_unlock (list_all_lock
);
53 fp
->_flags
&= ~_IO_LINKED
;
61 if ((fp
->_flags
& _IO_LINKED
) == 0)
63 fp
->_flags
|= _IO_LINKED
;
64 _IO_lock_lock (list_all_lock
);
65 fp
->_chain
= _IO_list_all
;
67 _IO_lock_unlock (list_all_lock
);
71 /* Return minimum _pos markers
72 Assumes the current get area is the main get area. */
73 static _IO_ssize_t _IO_least_marker
__P ((_IO_FILE
*fp
, char *end_p
));
76 _IO_least_marker (fp
, end_p
)
80 _IO_ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
81 struct _IO_marker
*mark
;
82 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
83 if (mark
->_pos
< least_so_far
)
84 least_so_far
= mark
->_pos
;
88 /* Switch current get area from backup buffer to (start of) main get area. */
91 _IO_switch_to_main_get_area (fp
)
95 fp
->_flags
&= ~_IO_IN_BACKUP
;
96 /* Swap _IO_read_end and _IO_save_end. */
97 tmp
= fp
->_IO_read_end
;
98 fp
->_IO_read_end
= fp
->_IO_save_end
;
99 fp
->_IO_save_end
= tmp
;
100 /* Swap _IO_read_base and _IO_save_base. */
101 tmp
= fp
->_IO_read_base
;
102 fp
->_IO_read_base
= fp
->_IO_save_base
;
103 fp
->_IO_save_base
= tmp
;
104 /* Set _IO_read_ptr. */
105 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
108 /* Switch current get area from main get area to (end of) backup area. */
111 _IO_switch_to_backup_area (fp
)
115 fp
->_flags
|= _IO_IN_BACKUP
;
116 /* Swap _IO_read_end and _IO_save_end. */
117 tmp
= fp
->_IO_read_end
;
118 fp
->_IO_read_end
= fp
->_IO_save_end
;
119 fp
->_IO_save_end
= tmp
;
120 /* Swap _IO_read_base and _IO_save_base. */
121 tmp
= fp
->_IO_read_base
;
122 fp
->_IO_read_base
= fp
->_IO_save_base
;
123 fp
->_IO_save_base
= tmp
;
124 /* Set _IO_read_ptr. */
125 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
129 _IO_switch_to_get_mode (fp
)
132 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
133 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
135 if (_IO_in_backup (fp
))
136 fp
->_IO_read_base
= fp
->_IO_backup_base
;
139 fp
->_IO_read_base
= fp
->_IO_buf_base
;
140 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
141 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
143 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
145 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
147 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
152 _IO_free_backup_area (fp
)
155 if (_IO_in_backup (fp
))
156 _IO_switch_to_main_get_area (fp
); /* Just in case. */
157 free (fp
->_IO_save_base
);
158 fp
->_IO_save_base
= NULL
;
159 fp
->_IO_save_end
= NULL
;
160 fp
->_IO_backup_base
= NULL
;
165 _IO_switch_to_put_mode (fp
)
168 fp
->_IO_write_base
= fp
->_IO_read_ptr
;
169 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
170 /* Following is wrong if line- or un-buffered? */
171 fp
->_IO_write_end
= (fp
->_flags
& _IO_IN_BACKUP
172 ? fp
->_IO_read_end
: fp
->_IO_buf_end
);
174 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
175 fp
->_IO_read_base
= fp
->_IO_read_end
;
177 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
187 return _IO_OVERFLOW (f
, ch
);
190 static int save_for_backup
__P ((_IO_FILE
*fp
, char *end_p
))
200 save_for_backup (fp
, end_p
)
204 /* Append [_IO_read_base..end_p] to backup area. */
205 _IO_ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
206 /* needed_size is how much space we need in the backup area. */
207 _IO_size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
208 /* FIXME: Dubious arithmetic if pointers are NULL */
209 _IO_size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
210 _IO_size_t avail
; /* Extra space available for future expansion. */
212 struct _IO_marker
*mark
;
213 if (needed_size
> current_Bsize
)
217 new_buffer
= (char *) malloc (avail
+ needed_size
);
218 if (new_buffer
== NULL
)
219 return EOF
; /* FIXME */
223 __mempcpy (__mempcpy (new_buffer
+ avail
,
224 fp
->_IO_save_end
+ least_mark
,
227 end_p
- fp
->_IO_read_base
);
229 memcpy (new_buffer
+ avail
,
230 fp
->_IO_save_end
+ least_mark
,
232 memcpy (new_buffer
+ avail
- least_mark
,
234 end_p
- fp
->_IO_read_base
);
238 memcpy (new_buffer
+ avail
,
239 fp
->_IO_read_base
+ least_mark
,
241 if (fp
->_IO_save_base
)
242 free (fp
->_IO_save_base
);
243 fp
->_IO_save_base
= new_buffer
;
244 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
248 avail
= current_Bsize
- needed_size
;
251 memmove (fp
->_IO_save_base
+ avail
,
252 fp
->_IO_save_end
+ least_mark
,
254 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
256 end_p
- fp
->_IO_read_base
);
258 else if (needed_size
> 0)
259 memcpy (fp
->_IO_save_base
+ avail
,
260 fp
->_IO_read_base
+ least_mark
,
263 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
264 /* Adjust all the streammarkers. */
265 delta
= end_p
- fp
->_IO_read_base
;
266 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
275 if (_IO_in_put_mode (fp
))
276 if (_IO_switch_to_get_mode (fp
) == EOF
)
278 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
279 return *(unsigned char *) fp
->_IO_read_ptr
;
280 if (_IO_in_backup (fp
))
282 _IO_switch_to_main_get_area (fp
);
283 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
284 return *(unsigned char *) fp
->_IO_read_ptr
;
286 if (_IO_have_markers (fp
))
288 if (save_for_backup (fp
, fp
->_IO_read_end
))
291 else if (_IO_have_backup (fp
))
292 _IO_free_backup_area (fp
);
293 return _IO_UNDERFLOW (fp
);
300 if (_IO_in_put_mode (fp
))
301 if (_IO_switch_to_get_mode (fp
) == EOF
)
303 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
304 return *(unsigned char *) fp
->_IO_read_ptr
++;
305 if (_IO_in_backup (fp
))
307 _IO_switch_to_main_get_area (fp
);
308 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
309 return *(unsigned char *) fp
->_IO_read_ptr
++;
311 if (_IO_have_markers (fp
))
313 if (save_for_backup (fp
, fp
->_IO_read_end
))
316 else if (_IO_have_backup (fp
))
317 _IO_free_backup_area (fp
);
318 return _IO_UFLOW (fp
);
322 _IO_setb (f
, b
, eb
, a
)
328 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
329 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
333 f
->_flags
&= ~_IO_USER_BUF
;
335 f
->_flags
|= _IO_USER_BUF
;
342 if (fp
->_IO_buf_base
)
344 if (!(fp
->_flags
& _IO_UNBUFFERED
))
345 if (_IO_DOALLOCATE (fp
) != EOF
)
347 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
351 _IO_default_underflow (fp
)
358 _IO_default_uflow (fp
)
361 int ch
= _IO_UNDERFLOW (fp
);
364 return *(unsigned char *) fp
->_IO_read_ptr
++;
368 _IO_default_xsputn (f
, data
, n
)
373 const char *s
= (char *) data
;
379 /* Space available. */
380 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
383 if ((_IO_size_t
) count
> more
)
388 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
390 memcpy (f
->_IO_write_ptr
, s
, count
);
391 f
->_IO_write_ptr
+= count
;
399 char *p
= f
->_IO_write_ptr
;
401 for (i
= count
; --i
>= 0; )
403 f
->_IO_write_ptr
= p
;
407 if (more
== 0 || __overflow (f
, (unsigned char) *s
++) == EOF
)
415 _IO_sgetn (fp
, data
, n
)
420 /* FIXME handle putback buffer here! */
421 return _IO_XSGETN (fp
, data
, n
);
425 _IO_default_xsgetn (fp
, data
, n
)
431 char *s
= (char*) data
;
434 /* Data available. */
435 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
438 if ((_IO_size_t
) count
> more
)
443 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
445 memcpy (s
, fp
->_IO_read_ptr
, count
);
448 fp
->_IO_read_ptr
+= count
;
454 char *p
= fp
->_IO_read_ptr
;
458 fp
->_IO_read_ptr
= p
;
462 if (more
== 0 || __underflow (fp
) == EOF
)
469 /* Seems not to be needed. --drepper */
479 _IO_default_setbuf (fp
, p
, len
)
484 if (_IO_SYNC (fp
) == EOF
)
486 if (p
== NULL
|| len
== 0)
488 fp
->_flags
|= _IO_UNBUFFERED
;
489 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
493 fp
->_flags
&= ~_IO_UNBUFFERED
;
494 _IO_setb (fp
, p
, p
+len
, 0);
496 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
497 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
502 _IO_default_seekpos (fp
, pos
, mode
)
507 return _IO_SEEKOFF (fp
, _IO_pos_as_off (pos
), 0, mode
);
511 _IO_default_doallocate (fp
)
516 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
517 _IO_setb (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
526 fp
->_flags
= _IO_MAGIC
|flags
;
527 fp
->_IO_buf_base
= NULL
;
528 fp
->_IO_buf_end
= NULL
;
529 fp
->_IO_read_base
= NULL
;
530 fp
->_IO_read_ptr
= NULL
;
531 fp
->_IO_read_end
= NULL
;
532 fp
->_IO_write_base
= NULL
;
533 fp
->_IO_write_ptr
= NULL
;
534 fp
->_IO_write_end
= NULL
;
535 fp
->_chain
= NULL
; /* Not necessary. */
537 fp
->_IO_save_base
= NULL
;
538 fp
->_IO_backup_base
= NULL
;
539 fp
->_IO_save_end
= NULL
;
543 fp
->_vtable_offset
= 0;
546 _IO_lock_init (*fp
->_lock
);
551 _IO_default_sync (fp
)
557 /* The way the C++ classes are mapped into the C functions in the
558 current implementation, this function can get called twice! */
561 _IO_default_finish (fp
, dummy
)
565 struct _IO_marker
*mark
;
566 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
568 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
569 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
572 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
575 if (fp
->_IO_save_base
)
577 free (fp
->_IO_save_base
);
578 fp
->_IO_save_base
= NULL
;
582 _IO_lock_fini (*fp
->_lock
);
589 _IO_default_seekoff (fp
, offset
, dir
, mode
)
599 _IO_sputbackc (fp
, c
)
605 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
606 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
609 result
= (unsigned char) c
;
612 result
= _IO_PBACKFAIL (fp
, c
);
615 fp
->_flags
&= ~_IO_EOF_SEEN
;
626 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
629 result
= (unsigned char) *fp
->_IO_read_ptr
;
632 result
= _IO_PBACKFAIL (fp
, EOF
);
635 fp
->_flags
&= ~_IO_EOF_SEEN
;
640 #if 0 /* Work in progress */
641 /* Seems not to be needed. */
644 _IO_set_column (fp
, c
)
651 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
655 _IO_set_column (fp
, i
)
659 fp
->_cur_column
= i
+ 1;
667 _IO_adjust_column (start
, line
, count
)
672 const char *ptr
= line
+ count
;
675 return line
+ count
- ptr
- 1;
676 return start
+ count
;
680 /* Seems not to be needed. --drepper */
686 return _IO_adjust_column (fp
->_cur_column
- 1,
688 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
698 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
699 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
700 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
706 _IO_flush_all_linebuffered ()
709 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
710 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
711 _IO_OVERFLOW (fp
, EOF
);
714 static void _IO_unbuffer_write
__P ((void));
717 _IO_unbuffer_write ()
720 for (fp
= _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
721 if (! (fp
->_flags
& _IO_UNBUFFERED
)
722 && (! (fp
->_flags
& _IO_NO_WRITES
)
723 || (fp
->_flags
& _IO_IS_APPENDING
)))
724 _IO_SETBUF (fp
, NULL
, 0);
730 int result
= _IO_flush_all ();
732 /* We currently don't have a reliable mechanism for making sure that
733 C++ static destructors are executed in the correct order.
734 So it is possible that other static destructors might want to
735 write to cout - and they're supposed to be able to do so.
737 The following will make the standard streambufs be unbuffered,
738 which forces any output from late destructors to be written out. */
739 _IO_unbuffer_write ();
746 _IO_init_marker (marker
, fp
)
747 struct _IO_marker
*marker
;
751 if (_IO_in_put_mode (fp
))
752 _IO_switch_to_get_mode (fp
);
753 if (_IO_in_backup (fp
))
754 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
756 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
758 /* Should perhaps sort the chain? */
759 marker
->_next
= fp
->_markers
;
760 fp
->_markers
= marker
;
764 _IO_remove_marker (marker
)
765 struct _IO_marker
*marker
;
767 /* Unlink from sb's chain. */
768 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
769 for (; ; ptr
= &(*ptr
)->_next
)
773 else if (*ptr
== marker
)
775 *ptr
= marker
->_next
;
780 if _sbuf has a backup area that is no longer needed
, should we
delete
781 it now
, or wait until the next underflow
?
785 #define BAD_DELTA EOF
788 _IO_marker_difference (mark1
, mark2
)
789 struct _IO_marker
*mark1
;
790 struct _IO_marker
*mark2
;
792 return mark1
->_pos
- mark2
->_pos
;
795 /* Return difference between MARK and current position of MARK's stream. */
797 _IO_marker_delta (mark
)
798 struct _IO_marker
*mark
;
801 if (mark
->_sbuf
== NULL
)
803 if (_IO_in_backup (mark
->_sbuf
))
804 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
806 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
807 return mark
->_pos
- cur_pos
;
811 _IO_seekmark (fp
, mark
, delta
)
813 struct _IO_marker
*mark
;
816 if (mark
->_sbuf
!= fp
)
820 if (_IO_in_backup (fp
))
821 _IO_switch_to_main_get_area (fp
);
822 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
826 if (!_IO_in_backup (fp
))
827 _IO_switch_to_backup_area (fp
);
828 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
834 _IO_unsave_markers (fp
)
837 struct _IO_marker
*mark
= fp
->_markers
;
841 streampos offset
= seekoff (0, ios::cur
, ios::in
);
844 offset
+= eGptr () - Gbase ();
845 for ( ; mark
!= NULL
; mark
= mark
->_next
)
846 mark
->set_streampos (mark
->_pos
+ offset
);
850 for ( ; mark
!= NULL
; mark
= mark
->_next
)
851 mark
->set_streampos (EOF
);
857 if (_IO_have_backup (fp
))
858 _IO_free_backup_area (fp
);
862 /* Seems not to be needed. --drepper */
864 _IO_nobackup_pbackfail (fp
, c
)
868 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
870 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
871 *fp
->_IO_read_ptr
= c
;
872 return (unsigned char) c
;
877 _IO_default_pbackfail (fp
, c
)
881 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
882 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
886 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
887 if (!_IO_in_backup (fp
))
889 /* We need to keep the invariant that the main get area
890 logically follows the backup area. */
891 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
893 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
896 else if (!_IO_have_backup (fp
))
898 /* No backup buffer: allocate one. */
899 /* Use nshort buffer, if unused? (probably not) FIXME */
900 int backup_size
= 128;
901 char *bbuf
= (char *) malloc (backup_size
);
904 fp
->_IO_save_base
= bbuf
;
905 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
906 fp
->_IO_backup_base
= fp
->_IO_save_end
;
908 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
909 _IO_switch_to_backup_area (fp
);
911 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
913 /* Increase size of existing backup buffer. */
915 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
917 new_size
= 2 * old_size
;
918 new_buf
= (char *) malloc (new_size
);
921 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
923 free (fp
->_IO_read_base
);
924 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
926 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
929 *--fp
->_IO_read_ptr
= c
;
931 return (unsigned char) c
;
935 _IO_default_seek (fp
, offset
, dir
)
944 _IO_default_stat (fp
, st
)
952 _IO_default_read (fp
, data
, n
)
961 _IO_default_write (fp
, data
, n
)
970 _IO_default_showmanyc (fp
)
977 _IO_default_imbue (fp
, locale
)
994 ~__io_defs() { _IO_cleanup (); }
1002 weak_alias (_IO_cleanup
, _cleanup
)
1005 #ifdef text_set_element
1006 text_set_element(__libc_atexit
, _cleanup
);