1 /* Copyright (C) 1993,1995,1997-2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception.
29 /* Generic or default I/O operations. */
36 static _IO_lock_t list_all_lock
= _IO_lock_initializer
;
39 /* Used to signal modifications to the list of FILE decriptors. */
40 static int _IO_list_all_stamp
;
43 static _IO_FILE
*run_fp
;
47 flush_cleanup (void *not_used
)
50 _IO_funlockfile (run_fp
);
52 _IO_lock_unlock (list_all_lock
);
59 _IO_un_link(struct _IO_FILE_plus
*fp
)
61 if (fp
->file
._flags
& _IO_LINKED
)
63 struct _IO_FILE_plus
**f
;
65 _IO_cleanup_region_start_noarg (flush_cleanup
);
66 _IO_lock_lock (list_all_lock
);
67 run_fp
= (_IO_FILE
*) fp
;
68 _IO_flockfile ((_IO_FILE
*) fp
);
70 for (f
= &INTUSE(_IO_list_all
); *f
;
71 f
= (struct _IO_FILE_plus
**) &(*f
)->file
._chain
)
75 *f
= (struct _IO_FILE_plus
*) fp
->file
._chain
;
80 fp
->file
._flags
&= ~_IO_LINKED
;
82 _IO_funlockfile ((_IO_FILE
*) fp
);
84 _IO_lock_unlock (list_all_lock
);
85 _IO_cleanup_region_end (0);
93 struct _IO_FILE_plus
*fp
;
95 if ((fp
->file
._flags
& _IO_LINKED
) == 0)
97 fp
->file
._flags
|= _IO_LINKED
;
99 _IO_cleanup_region_start_noarg (flush_cleanup
);
100 _IO_lock_lock (list_all_lock
);
101 run_fp
= (_IO_FILE
*) fp
;
102 _IO_flockfile ((_IO_FILE
*) fp
);
104 fp
->file
._chain
= (_IO_FILE
*) INTUSE(_IO_list_all
);
105 INTUSE(_IO_list_all
) = fp
;
106 ++_IO_list_all_stamp
;
108 _IO_funlockfile ((_IO_FILE
*) fp
);
110 _IO_lock_unlock (list_all_lock
);
111 _IO_cleanup_region_end (0);
117 /* Return minimum _pos markers
118 Assumes the current get area is the main get area. */
119 _IO_ssize_t _IO_least_marker
__P ((_IO_FILE
*fp
, char *end_p
));
122 _IO_least_marker (fp
, end_p
)
126 _IO_ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
127 struct _IO_marker
*mark
;
128 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
129 if (mark
->_pos
< least_so_far
)
130 least_so_far
= mark
->_pos
;
134 /* Switch current get area from backup buffer to (start of) main get area. */
137 _IO_switch_to_main_get_area (fp
)
141 fp
->_flags
&= ~_IO_IN_BACKUP
;
142 /* Swap _IO_read_end and _IO_save_end. */
143 tmp
= fp
->_IO_read_end
;
144 fp
->_IO_read_end
= fp
->_IO_save_end
;
145 fp
->_IO_save_end
= tmp
;
146 /* Swap _IO_read_base and _IO_save_base. */
147 tmp
= fp
->_IO_read_base
;
148 fp
->_IO_read_base
= fp
->_IO_save_base
;
149 fp
->_IO_save_base
= tmp
;
150 /* Set _IO_read_ptr. */
151 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
154 /* Switch current get area from main get area to (end of) backup area. */
157 _IO_switch_to_backup_area (fp
)
161 fp
->_flags
|= _IO_IN_BACKUP
;
162 /* Swap _IO_read_end and _IO_save_end. */
163 tmp
= fp
->_IO_read_end
;
164 fp
->_IO_read_end
= fp
->_IO_save_end
;
165 fp
->_IO_save_end
= tmp
;
166 /* Swap _IO_read_base and _IO_save_base. */
167 tmp
= fp
->_IO_read_base
;
168 fp
->_IO_read_base
= fp
->_IO_save_base
;
169 fp
->_IO_save_base
= tmp
;
170 /* Set _IO_read_ptr. */
171 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
175 _IO_switch_to_get_mode (fp
)
178 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
179 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
181 if (_IO_in_backup (fp
))
182 fp
->_IO_read_base
= fp
->_IO_backup_base
;
185 fp
->_IO_read_base
= fp
->_IO_buf_base
;
186 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
187 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
189 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
191 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
193 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
196 INTDEF(_IO_switch_to_get_mode
)
199 _IO_free_backup_area (fp
)
202 if (_IO_in_backup (fp
))
203 _IO_switch_to_main_get_area (fp
); /* Just in case. */
204 free (fp
->_IO_save_base
);
205 fp
->_IO_save_base
= NULL
;
206 fp
->_IO_save_end
= NULL
;
207 fp
->_IO_backup_base
= NULL
;
209 INTDEF(_IO_free_backup_area
)
213 _IO_switch_to_put_mode (fp
)
216 fp
->_IO_write_base
= fp
->_IO_read_ptr
;
217 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
218 /* Following is wrong if line- or un-buffered? */
219 fp
->_IO_write_end
= (fp
->_flags
& _IO_IN_BACKUP
220 ? fp
->_IO_read_end
: fp
->_IO_buf_end
);
222 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
223 fp
->_IO_read_base
= fp
->_IO_read_end
;
225 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
232 __overflow(_IO_FILE
*file
, int character
)
234 /* This is a single-byte stream. */
235 if (file
->_mode
== 0)
238 return _IO_OVERFLOW(file
, character
);
240 libc_hidden_def(__overflow
)
243 static int save_for_backup
__P ((_IO_FILE
*fp
, char *end_p
))
253 save_for_backup (fp
, end_p
)
257 /* Append [_IO_read_base..end_p] to backup area. */
258 _IO_ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
259 /* needed_size is how much space we need in the backup area. */
260 _IO_size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
261 /* FIXME: Dubious arithmetic if pointers are NULL */
262 _IO_size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
263 _IO_size_t avail
; /* Extra space available for future expansion. */
265 struct _IO_marker
*mark
;
266 if (needed_size
> current_Bsize
)
270 new_buffer
= (char *) malloc (avail
+ needed_size
);
271 if (new_buffer
== NULL
)
272 return EOF
; /* FIXME */
276 __mempcpy (__mempcpy (new_buffer
+ avail
,
277 fp
->_IO_save_end
+ least_mark
,
280 end_p
- fp
->_IO_read_base
);
282 memcpy (new_buffer
+ avail
,
283 fp
->_IO_save_end
+ least_mark
,
285 memcpy (new_buffer
+ avail
- least_mark
,
287 end_p
- fp
->_IO_read_base
);
291 memcpy (new_buffer
+ avail
,
292 fp
->_IO_read_base
+ least_mark
,
294 if (fp
->_IO_save_base
)
295 free (fp
->_IO_save_base
);
296 fp
->_IO_save_base
= new_buffer
;
297 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
301 avail
= current_Bsize
- needed_size
;
304 memmove (fp
->_IO_save_base
+ avail
,
305 fp
->_IO_save_end
+ least_mark
,
307 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
309 end_p
- fp
->_IO_read_base
);
311 else if (needed_size
> 0)
312 memcpy (fp
->_IO_save_base
+ avail
,
313 fp
->_IO_read_base
+ least_mark
,
316 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
317 /* Adjust all the streammarkers. */
318 delta
= end_p
- fp
->_IO_read_base
;
319 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
326 __underflow(_IO_FILE
*file
)
328 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
329 if (file
->_vtable_offset
== 0 && _IO_fwide(file
, -1) != -1)
333 if (file
->_mode
== 0)
336 if (_IO_in_put_mode(file
) && INTUSE(_IO_switch_to_get_mode
)(file
) == EOF
)
339 if (file
->_IO_read_ptr
< file
->_IO_read_end
)
340 return *(unsigned char *)file
->_IO_read_ptr
;
342 if (_IO_in_backup(file
)) {
343 _IO_switch_to_main_get_area(file
);
345 if (file
->_IO_read_ptr
< file
->_IO_read_end
)
346 return *(unsigned char *)file
->_IO_read_ptr
;
348 if (_IO_have_markers(file
)) {
349 if (save_for_backup(file
, file
->_IO_read_end
))
351 } else if (_IO_have_backup(file
))
352 INTUSE(_IO_free_backup_area
)(file
);
354 return _IO_UNDERFLOW(file
);
356 libc_hidden_def(__underflow
)
360 __uflow(_IO_FILE
*file
)
362 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
363 if (file
->_vtable_offset
== 0 && _IO_fwide(file
, -1) != -1)
367 if (file
->_mode
== 0)
368 _IO_fwide(file
, -11);
370 if (_IO_in_put_mode(file
) && INTUSE(_IO_switch_to_get_mode
)(file
) == EOF
)
373 if (file
->_IO_read_ptr
< file
->_IO_read_end
)
374 return *(unsigned char *)file
->_IO_read_ptr
++;
376 if (_IO_in_backup(file
)) {
377 _IO_switch_to_main_get_area(file
);
379 if (file
->_IO_read_ptr
< file
->_IO_read_end
)
380 return *(unsigned char *)file
->_IO_read_ptr
++;
383 if (_IO_have_markers(file
)) {
384 if (save_for_backup(file
, file
->_IO_read_end
))
386 } else if (_IO_have_backup(file
))
387 INTUSE(_IO_free_backup_area
)(file
);
389 return _IO_UFLOW(file
);
391 libc_hidden_def(__uflow
)
395 _IO_setb (f
, b
, eb
, a
)
401 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
402 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
406 f
->_flags
&= ~_IO_USER_BUF
;
408 f
->_flags
|= _IO_USER_BUF
;
416 if (fp
->_IO_buf_base
)
418 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
419 if (_IO_DOALLOCATE (fp
) != EOF
)
421 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
423 INTDEF(_IO_doallocbuf
)
426 _IO_default_underflow (fp
)
433 _IO_default_uflow (fp
)
436 int ch
= _IO_UNDERFLOW (fp
);
439 return *(unsigned char *) fp
->_IO_read_ptr
++;
441 INTDEF(_IO_default_uflow
)
444 _IO_default_xsputn (f
, data
, n
)
449 const char *s
= (char *) data
;
455 /* Space available. */
456 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
459 if ((_IO_size_t
) count
> more
)
464 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
466 memcpy (f
->_IO_write_ptr
, s
, count
);
467 f
->_IO_write_ptr
+= count
;
475 char *p
= f
->_IO_write_ptr
;
477 for (i
= count
; --i
>= 0; )
479 f
->_IO_write_ptr
= p
;
483 if (more
== 0 || _IO_OVERFLOW (f
, (unsigned char) *s
++) == EOF
)
489 INTDEF(_IO_default_xsputn
)
492 _IO_sgetn (fp
, data
, n
)
497 /* FIXME handle putback buffer here! */
498 return _IO_XSGETN (fp
, data
, n
);
503 _IO_default_xsgetn (fp
, data
, n
)
509 char *s
= (char*) data
;
512 /* Data available. */
513 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
516 if ((_IO_size_t
) count
> more
)
521 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
523 memcpy (s
, fp
->_IO_read_ptr
, count
);
526 fp
->_IO_read_ptr
+= count
;
532 char *p
= fp
->_IO_read_ptr
;
536 fp
->_IO_read_ptr
= p
;
540 if (more
== 0 || __underflow (fp
) == EOF
)
545 INTDEF(_IO_default_xsgetn
)
548 /* Seems not to be needed. --drepper */
558 _IO_default_setbuf (fp
, p
, len
)
563 if (_IO_SYNC (fp
) == EOF
)
565 if (p
== NULL
|| len
== 0)
567 fp
->_flags
|= _IO_UNBUFFERED
;
568 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
572 fp
->_flags
&= ~_IO_UNBUFFERED
;
573 INTUSE(_IO_setb
) (fp
, p
, p
+len
, 0);
575 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
576 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
581 _IO_default_seekpos (fp
, pos
, mode
)
586 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
590 _IO_default_doallocate (fp
)
595 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
596 INTUSE(_IO_setb
) (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
599 INTDEF(_IO_default_doallocate
)
606 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
611 _IO_no_init (fp
, flags
, orientation
, wd
, jmp
)
615 struct _IO_wide_data
*wd
;
616 struct _IO_jump_t
*jmp
;
618 fp
->_flags
= _IO_MAGIC
|flags
;
620 fp
->_IO_buf_base
= NULL
;
621 fp
->_IO_buf_end
= NULL
;
622 fp
->_IO_read_base
= NULL
;
623 fp
->_IO_read_ptr
= NULL
;
624 fp
->_IO_read_end
= NULL
;
625 fp
->_IO_write_base
= NULL
;
626 fp
->_IO_write_ptr
= NULL
;
627 fp
->_IO_write_end
= NULL
;
628 fp
->_chain
= NULL
; /* Not necessary. */
630 fp
->_IO_save_base
= NULL
;
631 fp
->_IO_backup_base
= NULL
;
632 fp
->_IO_save_end
= NULL
;
636 fp
->_vtable_offset
= 0;
639 if (fp
->_lock
!= NULL
)
640 _IO_lock_init (*fp
->_lock
);
642 fp
->_mode
= orientation
;
643 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
644 if (orientation
>= 0)
647 fp
->_wide_data
->_IO_buf_base
= NULL
;
648 fp
->_wide_data
->_IO_buf_end
= NULL
;
649 fp
->_wide_data
->_IO_read_base
= NULL
;
650 fp
->_wide_data
->_IO_read_ptr
= NULL
;
651 fp
->_wide_data
->_IO_read_end
= NULL
;
652 fp
->_wide_data
->_IO_write_base
= NULL
;
653 fp
->_wide_data
->_IO_write_ptr
= NULL
;
654 fp
->_wide_data
->_IO_write_end
= NULL
;
655 fp
->_wide_data
->_IO_save_base
= NULL
;
656 fp
->_wide_data
->_IO_backup_base
= NULL
;
657 fp
->_wide_data
->_IO_save_end
= NULL
;
659 fp
->_wide_data
->_wide_vtable
= jmp
;
665 _IO_default_sync (fp
)
671 /* The way the C++ classes are mapped into the C functions in the
672 current implementation, this function can get called twice! */
675 _IO_default_finish (fp
, dummy
)
679 struct _IO_marker
*mark
;
680 if (fp
->_IO_buf_base
&& fp
->_IO_buf_base
!= fp
->_shortbuf
681 && !(fp
->_flags
& _IO_USER_BUF
))
683 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
684 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
687 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
690 if (fp
->_IO_save_base
)
692 free (fp
->_IO_save_base
);
693 fp
->_IO_save_base
= NULL
;
697 if (fp
->_lock
!= NULL
)
698 _IO_lock_fini (*fp
->_lock
);
701 INTUSE(_IO_un_link
) ((struct _IO_FILE_plus
*) fp
);
703 INTDEF(_IO_default_finish
)
706 _IO_default_seekoff (fp
, offset
, dir
, mode
)
716 _IO_sputbackc (fp
, c
)
722 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
723 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
726 result
= (unsigned char) c
;
729 result
= _IO_PBACKFAIL (fp
, c
);
732 fp
->_flags
&= ~_IO_EOF_SEEN
;
736 INTDEF(_IO_sputbackc
)
744 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
747 result
= (unsigned char) *fp
->_IO_read_ptr
;
750 result
= _IO_PBACKFAIL (fp
, EOF
);
753 fp
->_flags
&= ~_IO_EOF_SEEN
;
758 #if 0 /* Work in progress */
759 /* Seems not to be needed. */
762 _IO_set_column (fp
, c
)
769 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
773 _IO_set_column (fp
, i
)
777 fp
->_cur_column
= i
+ 1;
785 _IO_adjust_column (start
, line
, count
)
790 const char *ptr
= line
+ count
;
793 return line
+ count
- ptr
- 1;
794 return start
+ count
;
796 INTDEF(_IO_adjust_column
)
799 /* Seems not to be needed. --drepper */
805 return _IO_adjust_column (fp
->_cur_column
- 1,
807 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
814 _IO_flush_all_lockp (int do_lock
)
821 _IO_cleanup_region_start_noarg (flush_cleanup
);
823 _IO_lock_lock (list_all_lock
);
826 last_stamp
= _IO_list_all_stamp
;
827 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
834 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
835 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
836 || (fp
->_vtable_offset
== 0
837 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
838 > fp
->_wide_data
->_IO_write_base
))
841 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
845 _IO_funlockfile (fp
);
848 if (last_stamp
!= _IO_list_all_stamp
)
850 /* Something was added to the list. Start all over again. */
851 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
852 last_stamp
= _IO_list_all_stamp
;
860 _IO_lock_unlock (list_all_lock
);
861 _IO_cleanup_region_end (0);
871 /* We want locking. */
872 return _IO_flush_all_lockp (1);
874 INTDEF(_IO_flush_all
)
877 _IO_flush_all_linebuffered ()
883 _IO_cleanup_region_start_noarg (flush_cleanup
);
884 _IO_lock_lock (list_all_lock
);
887 last_stamp
= _IO_list_all_stamp
;
888 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
894 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
895 _IO_OVERFLOW (fp
, EOF
);
897 _IO_funlockfile (fp
);
900 if (last_stamp
!= _IO_list_all_stamp
)
902 /* Something was added to the list. Start all over again. */
903 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
904 last_stamp
= _IO_list_all_stamp
;
911 _IO_lock_unlock (list_all_lock
);
912 _IO_cleanup_region_end (0);
915 INTDEF(_IO_flush_all_linebuffered
)
917 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
920 static void _IO_unbuffer_write
__P ((void));
923 _IO_unbuffer_write ()
926 for (fp
= (_IO_FILE
*) INTUSE(_IO_list_all
); fp
; fp
= fp
->_chain
)
928 if (! (fp
->_flags
& _IO_UNBUFFERED
)
929 && (! (fp
->_flags
& _IO_NO_WRITES
)
930 || (fp
->_flags
& _IO_IS_APPENDING
))
931 /* Iff stream is un-orientated, it wasn't used. */
933 _IO_SETBUF (fp
, NULL
, 0);
935 /* Make sure that never again the wide char functions can be
944 /* We do *not* want locking. Some threads might use streams but
945 that is there problem, we flush them underneath them. */
946 int result
= _IO_flush_all_lockp (0);
948 /* We currently don't have a reliable mechanism for making sure that
949 C++ static destructors are executed in the correct order.
950 So it is possible that other static destructors might want to
951 write to cout - and they're supposed to be able to do so.
953 The following will make the standard streambufs be unbuffered,
954 which forces any output from late destructors to be written out. */
955 _IO_unbuffer_write ();
962 _IO_init_marker (marker
, fp
)
963 struct _IO_marker
*marker
;
967 if (_IO_in_put_mode (fp
))
968 INTUSE(_IO_switch_to_get_mode
) (fp
);
969 if (_IO_in_backup (fp
))
970 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
972 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
974 /* Should perhaps sort the chain? */
975 marker
->_next
= fp
->_markers
;
976 fp
->_markers
= marker
;
980 _IO_remove_marker (marker
)
981 struct _IO_marker
*marker
;
983 /* Unlink from sb's chain. */
984 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
985 for (; ; ptr
= &(*ptr
)->_next
)
989 else if (*ptr
== marker
)
991 *ptr
= marker
->_next
;
996 if _sbuf has a backup area that is no longer needed
, should we
delete
997 it now
, or wait until the next underflow
?
1001 #define BAD_DELTA EOF
1004 _IO_marker_difference (mark1
, mark2
)
1005 struct _IO_marker
*mark1
;
1006 struct _IO_marker
*mark2
;
1008 return mark1
->_pos
- mark2
->_pos
;
1011 /* Return difference between MARK and current position of MARK's stream. */
1013 _IO_marker_delta (mark
)
1014 struct _IO_marker
*mark
;
1017 if (mark
->_sbuf
== NULL
)
1019 if (_IO_in_backup (mark
->_sbuf
))
1020 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
1022 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
1023 return mark
->_pos
- cur_pos
;
1027 _IO_seekmark (fp
, mark
, delta
)
1029 struct _IO_marker
*mark
;
1032 if (mark
->_sbuf
!= fp
)
1034 if (mark
->_pos
>= 0)
1036 if (_IO_in_backup (fp
))
1037 _IO_switch_to_main_get_area (fp
);
1038 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
1042 if (!_IO_in_backup (fp
))
1043 _IO_switch_to_backup_area (fp
);
1044 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1050 _IO_unsave_markers (fp
)
1053 struct _IO_marker
*mark
= fp
->_markers
;
1057 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1060 offset
+= eGptr () - Gbase ();
1061 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1062 mark
->set_streampos (mark
->_pos
+ offset
);
1066 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1067 mark
->set_streampos (EOF
);
1073 if (_IO_have_backup (fp
))
1074 INTUSE(_IO_free_backup_area
) (fp
);
1076 INTDEF(_IO_unsave_markers
)
1079 /* Seems not to be needed. --drepper */
1081 _IO_nobackup_pbackfail (fp
, c
)
1085 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1087 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1088 *fp
->_IO_read_ptr
= c
;
1089 return (unsigned char) c
;
1094 _IO_default_pbackfail (fp
, c
)
1098 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1099 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1103 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1104 if (!_IO_in_backup (fp
))
1106 /* We need to keep the invariant that the main get area
1107 logically follows the backup area. */
1108 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1110 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1113 else if (!_IO_have_backup (fp
))
1115 /* No backup buffer: allocate one. */
1116 /* Use nshort buffer, if unused? (probably not) FIXME */
1117 int backup_size
= 128;
1118 char *bbuf
= (char *) malloc (backup_size
);
1121 fp
->_IO_save_base
= bbuf
;
1122 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1123 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1125 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1126 _IO_switch_to_backup_area (fp
);
1128 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1130 /* Increase size of existing backup buffer. */
1131 _IO_size_t new_size
;
1132 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1134 new_size
= 2 * old_size
;
1135 new_buf
= (char *) malloc (new_size
);
1136 if (new_buf
== NULL
)
1138 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1140 free (fp
->_IO_read_base
);
1141 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1142 new_buf
+ new_size
);
1143 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1146 *--fp
->_IO_read_ptr
= c
;
1148 return (unsigned char) c
;
1150 INTDEF(_IO_default_pbackfail
)
1153 _IO_default_seek (fp
, offset
, dir
)
1162 _IO_default_stat (fp
, st
)
1170 _IO_default_read (fp
, data
, n
)
1179 _IO_default_write (fp
, data
, n
)
1188 _IO_default_showmanyc (fp
)
1195 _IO_default_imbue (fp
, locale
)
1204 return (_IO_ITER
) INTUSE(_IO_list_all
);
1206 libc_hidden_def (_IO_iter_begin
)
1213 libc_hidden_def (_IO_iter_end
)
1219 return iter
->_chain
;
1221 libc_hidden_def (_IO_iter_next
)
1229 libc_hidden_def (_IO_iter_file
)
1234 #ifdef _IO_MTSAFE_IO
1235 _IO_lock_lock (list_all_lock
);
1238 libc_hidden_def (_IO_list_lock
)
1243 #ifdef _IO_MTSAFE_IO
1244 _IO_lock_unlock (list_all_lock
);
1247 libc_hidden_def (_IO_list_unlock
)
1250 _IO_list_resetlock()
1252 #ifdef _IO_MTSAFE_IO
1253 _IO_lock_init (list_all_lock
);
1256 libc_hidden_def (_IO_list_resetlock
)
1261 #define IO_CLEANUP ;
1269 ~__io_defs() { _IO_cleanup (); }
1271 __io_defs io_defs__
;
1276 #ifdef text_set_element
1277 text_set_element(__libc_atexit
, _IO_cleanup
);