1 /* Copyright (C) 1993,1995,1997-2002, 2003, 2004 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. */
28 /* Generic or default I/O operations. */
37 static _IO_lock_t list_all_lock
= _IO_lock_initializer
;
40 /* Used to signal modifications to the list of FILE decriptors. */
41 static int _IO_list_all_stamp
;
44 static _IO_FILE
*run_fp
;
47 flush_cleanup (void *not_used
)
50 _IO_funlockfile (run_fp
);
52 _IO_lock_unlock (list_all_lock
);
58 struct _IO_FILE_plus
*fp
;
60 if (fp
->file
._flags
& _IO_LINKED
)
62 struct _IO_FILE_plus
**f
;
64 _IO_cleanup_region_start_noarg (flush_cleanup
);
65 _IO_lock_lock (list_all_lock
);
66 run_fp
= (_IO_FILE
*) fp
;
67 _IO_flockfile ((_IO_FILE
*) fp
);
69 for (f
= &INTUSE(_IO_list_all
); *f
;
70 f
= (struct _IO_FILE_plus
**) &(*f
)->file
._chain
)
74 *f
= (struct _IO_FILE_plus
*) fp
->file
._chain
;
79 fp
->file
._flags
&= ~_IO_LINKED
;
81 _IO_funlockfile ((_IO_FILE
*) fp
);
83 _IO_lock_unlock (list_all_lock
);
84 _IO_cleanup_region_end (0);
92 struct _IO_FILE_plus
*fp
;
94 if ((fp
->file
._flags
& _IO_LINKED
) == 0)
96 fp
->file
._flags
|= _IO_LINKED
;
98 _IO_cleanup_region_start_noarg (flush_cleanup
);
99 _IO_lock_lock (list_all_lock
);
100 run_fp
= (_IO_FILE
*) fp
;
101 _IO_flockfile ((_IO_FILE
*) fp
);
103 fp
->file
._chain
= (_IO_FILE
*) INTUSE(_IO_list_all
);
104 INTUSE(_IO_list_all
) = fp
;
105 ++_IO_list_all_stamp
;
107 _IO_funlockfile ((_IO_FILE
*) fp
);
109 _IO_lock_unlock (list_all_lock
);
110 _IO_cleanup_region_end (0);
116 /* Return minimum _pos markers
117 Assumes the current get area is the main get area. */
118 _IO_ssize_t _IO_least_marker
__P ((_IO_FILE
*fp
, char *end_p
));
121 _IO_least_marker (fp
, end_p
)
125 _IO_ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
126 struct _IO_marker
*mark
;
127 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
128 if (mark
->_pos
< least_so_far
)
129 least_so_far
= mark
->_pos
;
133 /* Switch current get area from backup buffer to (start of) main get area. */
136 _IO_switch_to_main_get_area (fp
)
140 fp
->_flags
&= ~_IO_IN_BACKUP
;
141 /* Swap _IO_read_end and _IO_save_end. */
142 tmp
= fp
->_IO_read_end
;
143 fp
->_IO_read_end
= fp
->_IO_save_end
;
144 fp
->_IO_save_end
= tmp
;
145 /* Swap _IO_read_base and _IO_save_base. */
146 tmp
= fp
->_IO_read_base
;
147 fp
->_IO_read_base
= fp
->_IO_save_base
;
148 fp
->_IO_save_base
= tmp
;
149 /* Set _IO_read_ptr. */
150 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
153 /* Switch current get area from main get area to (end of) backup area. */
156 _IO_switch_to_backup_area (fp
)
160 fp
->_flags
|= _IO_IN_BACKUP
;
161 /* Swap _IO_read_end and _IO_save_end. */
162 tmp
= fp
->_IO_read_end
;
163 fp
->_IO_read_end
= fp
->_IO_save_end
;
164 fp
->_IO_save_end
= tmp
;
165 /* Swap _IO_read_base and _IO_save_base. */
166 tmp
= fp
->_IO_read_base
;
167 fp
->_IO_read_base
= fp
->_IO_save_base
;
168 fp
->_IO_save_base
= tmp
;
169 /* Set _IO_read_ptr. */
170 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
174 _IO_switch_to_get_mode (fp
)
177 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
178 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
180 if (_IO_in_backup (fp
))
181 fp
->_IO_read_base
= fp
->_IO_backup_base
;
184 fp
->_IO_read_base
= fp
->_IO_buf_base
;
185 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
186 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
188 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
190 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
192 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
195 INTDEF(_IO_switch_to_get_mode
)
198 _IO_free_backup_area (fp
)
201 if (_IO_in_backup (fp
))
202 _IO_switch_to_main_get_area (fp
); /* Just in case. */
203 free (fp
->_IO_save_base
);
204 fp
->_IO_save_base
= NULL
;
205 fp
->_IO_save_end
= NULL
;
206 fp
->_IO_backup_base
= NULL
;
208 INTDEF(_IO_free_backup_area
)
212 _IO_switch_to_put_mode (fp
)
215 fp
->_IO_write_base
= fp
->_IO_read_ptr
;
216 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
217 /* Following is wrong if line- or un-buffered? */
218 fp
->_IO_write_end
= (fp
->_flags
& _IO_IN_BACKUP
219 ? fp
->_IO_read_end
: fp
->_IO_buf_end
);
221 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
222 fp
->_IO_read_base
= fp
->_IO_read_end
;
224 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
234 /* This is a single-byte stream. */
237 return _IO_OVERFLOW (f
, ch
);
239 libc_hidden_def (__overflow
)
241 static int save_for_backup
__P ((_IO_FILE
*fp
, char *end_p
))
251 save_for_backup (fp
, end_p
)
255 /* Append [_IO_read_base..end_p] to backup area. */
256 _IO_ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
257 /* needed_size is how much space we need in the backup area. */
258 _IO_size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
259 /* FIXME: Dubious arithmetic if pointers are NULL */
260 _IO_size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
261 _IO_size_t avail
; /* Extra space available for future expansion. */
263 struct _IO_marker
*mark
;
264 if (needed_size
> current_Bsize
)
268 new_buffer
= (char *) malloc (avail
+ needed_size
);
269 if (new_buffer
== NULL
)
270 return EOF
; /* FIXME */
274 __mempcpy (__mempcpy (new_buffer
+ avail
,
275 fp
->_IO_save_end
+ least_mark
,
278 end_p
- fp
->_IO_read_base
);
280 memcpy (new_buffer
+ avail
,
281 fp
->_IO_save_end
+ least_mark
,
283 memcpy (new_buffer
+ avail
- least_mark
,
285 end_p
- fp
->_IO_read_base
);
289 memcpy (new_buffer
+ avail
,
290 fp
->_IO_read_base
+ least_mark
,
292 if (fp
->_IO_save_base
)
293 free (fp
->_IO_save_base
);
294 fp
->_IO_save_base
= new_buffer
;
295 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
299 avail
= current_Bsize
- needed_size
;
302 memmove (fp
->_IO_save_base
+ avail
,
303 fp
->_IO_save_end
+ least_mark
,
305 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
307 end_p
- fp
->_IO_read_base
);
309 else if (needed_size
> 0)
310 memcpy (fp
->_IO_save_base
+ avail
,
311 fp
->_IO_read_base
+ least_mark
,
314 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
315 /* Adjust all the streammarkers. */
316 delta
= end_p
- fp
->_IO_read_base
;
317 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
326 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
327 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
333 if (_IO_in_put_mode (fp
))
334 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
336 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
337 return *(unsigned char *) fp
->_IO_read_ptr
;
338 if (_IO_in_backup (fp
))
340 _IO_switch_to_main_get_area (fp
);
341 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
342 return *(unsigned char *) fp
->_IO_read_ptr
;
344 if (_IO_have_markers (fp
))
346 if (save_for_backup (fp
, fp
->_IO_read_end
))
349 else if (_IO_have_backup (fp
))
350 INTUSE(_IO_free_backup_area
) (fp
);
351 return _IO_UNDERFLOW (fp
);
353 libc_hidden_def (__underflow
)
359 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
360 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
366 if (_IO_in_put_mode (fp
))
367 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
369 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
370 return *(unsigned char *) fp
->_IO_read_ptr
++;
371 if (_IO_in_backup (fp
))
373 _IO_switch_to_main_get_area (fp
);
374 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
375 return *(unsigned char *) fp
->_IO_read_ptr
++;
377 if (_IO_have_markers (fp
))
379 if (save_for_backup (fp
, fp
->_IO_read_end
))
382 else if (_IO_have_backup (fp
))
383 INTUSE(_IO_free_backup_area
) (fp
);
384 return _IO_UFLOW (fp
);
386 libc_hidden_def (__uflow
)
389 _IO_setb (f
, b
, eb
, a
)
395 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
396 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
400 f
->_flags
&= ~_IO_USER_BUF
;
402 f
->_flags
|= _IO_USER_BUF
;
410 if (fp
->_IO_buf_base
)
412 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
413 if (_IO_DOALLOCATE (fp
) != EOF
)
415 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
417 INTDEF(_IO_doallocbuf
)
420 _IO_default_underflow (fp
)
427 _IO_default_uflow (fp
)
430 int ch
= _IO_UNDERFLOW (fp
);
433 return *(unsigned char *) fp
->_IO_read_ptr
++;
435 INTDEF(_IO_default_uflow
)
438 _IO_default_xsputn (f
, data
, n
)
443 const char *s
= (char *) data
;
449 /* Space available. */
450 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
453 if ((_IO_size_t
) count
> more
)
458 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
460 memcpy (f
->_IO_write_ptr
, s
, count
);
461 f
->_IO_write_ptr
+= count
;
469 char *p
= f
->_IO_write_ptr
;
471 for (i
= count
; --i
>= 0; )
473 f
->_IO_write_ptr
= p
;
477 if (more
== 0 || _IO_OVERFLOW (f
, (unsigned char) *s
++) == EOF
)
483 INTDEF(_IO_default_xsputn
)
486 _IO_sgetn (fp
, data
, n
)
491 /* FIXME handle putback buffer here! */
492 return _IO_XSGETN (fp
, data
, n
);
497 _IO_default_xsgetn (fp
, data
, n
)
503 char *s
= (char*) data
;
506 /* Data available. */
507 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
510 if ((_IO_size_t
) count
> more
)
515 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
517 memcpy (s
, fp
->_IO_read_ptr
, count
);
520 fp
->_IO_read_ptr
+= count
;
526 char *p
= fp
->_IO_read_ptr
;
530 fp
->_IO_read_ptr
= p
;
534 if (more
== 0 || __underflow (fp
) == EOF
)
539 INTDEF(_IO_default_xsgetn
)
542 /* Seems not to be needed. --drepper */
552 _IO_default_setbuf (fp
, p
, len
)
557 if (_IO_SYNC (fp
) == EOF
)
559 if (p
== NULL
|| len
== 0)
561 fp
->_flags
|= _IO_UNBUFFERED
;
562 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
566 fp
->_flags
&= ~_IO_UNBUFFERED
;
567 INTUSE(_IO_setb
) (fp
, p
, p
+len
, 0);
569 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
570 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
575 _IO_default_seekpos (fp
, pos
, mode
)
580 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
584 _IO_default_doallocate (fp
)
589 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
590 INTUSE(_IO_setb
) (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
593 INTDEF(_IO_default_doallocate
)
600 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
605 _IO_old_init (fp
, flags
)
609 fp
->_flags
= _IO_MAGIC
|flags
;
611 fp
->_IO_buf_base
= NULL
;
612 fp
->_IO_buf_end
= NULL
;
613 fp
->_IO_read_base
= NULL
;
614 fp
->_IO_read_ptr
= NULL
;
615 fp
->_IO_read_end
= NULL
;
616 fp
->_IO_write_base
= NULL
;
617 fp
->_IO_write_ptr
= NULL
;
618 fp
->_IO_write_end
= NULL
;
619 fp
->_chain
= NULL
; /* Not necessary. */
621 fp
->_IO_save_base
= NULL
;
622 fp
->_IO_backup_base
= NULL
;
623 fp
->_IO_save_end
= NULL
;
627 fp
->_vtable_offset
= 0;
630 if (fp
->_lock
!= NULL
)
631 _IO_lock_init (*fp
->_lock
);
636 _IO_no_init (fp
, flags
, orientation
, wd
, jmp
)
640 struct _IO_wide_data
*wd
;
641 const struct _IO_jump_t
*jmp
;
643 _IO_old_init (fp
, flags
);
644 fp
->_mode
= orientation
;
645 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
646 if (orientation
>= 0)
649 fp
->_wide_data
->_IO_buf_base
= NULL
;
650 fp
->_wide_data
->_IO_buf_end
= NULL
;
651 fp
->_wide_data
->_IO_read_base
= NULL
;
652 fp
->_wide_data
->_IO_read_ptr
= NULL
;
653 fp
->_wide_data
->_IO_read_end
= NULL
;
654 fp
->_wide_data
->_IO_write_base
= NULL
;
655 fp
->_wide_data
->_IO_write_ptr
= NULL
;
656 fp
->_wide_data
->_IO_write_end
= NULL
;
657 fp
->_wide_data
->_IO_save_base
= NULL
;
658 fp
->_wide_data
->_IO_backup_base
= NULL
;
659 fp
->_wide_data
->_IO_save_end
= NULL
;
661 fp
->_wide_data
->_wide_vtable
= jmp
;
667 _IO_default_sync (fp
)
673 /* The way the C++ classes are mapped into the C functions in the
674 current implementation, this function can get called twice! */
677 _IO_default_finish (fp
, dummy
)
681 struct _IO_marker
*mark
;
682 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
684 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
685 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
688 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
691 if (fp
->_IO_save_base
)
693 free (fp
->_IO_save_base
);
694 fp
->_IO_save_base
= NULL
;
698 if (fp
->_lock
!= NULL
)
699 _IO_lock_fini (*fp
->_lock
);
702 INTUSE(_IO_un_link
) ((struct _IO_FILE_plus
*) fp
);
704 INTDEF(_IO_default_finish
)
707 _IO_default_seekoff (fp
, offset
, dir
, mode
)
717 _IO_sputbackc (fp
, c
)
723 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
724 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
727 result
= (unsigned char) c
;
730 result
= _IO_PBACKFAIL (fp
, c
);
733 fp
->_flags
&= ~_IO_EOF_SEEN
;
737 INTDEF(_IO_sputbackc
)
745 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
748 result
= (unsigned char) *fp
->_IO_read_ptr
;
751 result
= _IO_PBACKFAIL (fp
, EOF
);
754 fp
->_flags
&= ~_IO_EOF_SEEN
;
759 #if 0 /* Work in progress */
760 /* Seems not to be needed. */
763 _IO_set_column (fp
, c
)
770 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
774 _IO_set_column (fp
, i
)
778 fp
->_cur_column
= i
+ 1;
786 _IO_adjust_column (start
, line
, count
)
791 const char *ptr
= line
+ count
;
794 return line
+ count
- ptr
- 1;
795 return start
+ count
;
797 INTDEF(_IO_adjust_column
)
800 /* Seems not to be needed. --drepper */
806 return _IO_adjust_column (fp
->_cur_column
- 1,
808 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
815 _IO_flush_all_lockp (int do_lock
)
822 _IO_cleanup_region_start_noarg (flush_cleanup
);
824 _IO_lock_lock (list_all_lock
);
827 last_stamp
= _IO_list_all_stamp
;
828 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
835 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
836 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
837 || (_IO_vtable_offset (fp
) == 0
838 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
839 > fp
->_wide_data
->_IO_write_base
))
842 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
846 _IO_funlockfile (fp
);
849 if (last_stamp
!= _IO_list_all_stamp
)
851 /* Something was added to the list. Start all over again. */
852 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
853 last_stamp
= _IO_list_all_stamp
;
861 _IO_lock_unlock (list_all_lock
);
862 _IO_cleanup_region_end (0);
872 /* We want locking. */
873 return _IO_flush_all_lockp (1);
875 INTDEF(_IO_flush_all
)
878 _IO_flush_all_linebuffered ()
884 _IO_cleanup_region_start_noarg (flush_cleanup
);
885 _IO_lock_lock (list_all_lock
);
888 last_stamp
= _IO_list_all_stamp
;
889 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
895 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
896 _IO_OVERFLOW (fp
, EOF
);
898 _IO_funlockfile (fp
);
901 if (last_stamp
!= _IO_list_all_stamp
)
903 /* Something was added to the list. Start all over again. */
904 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
905 last_stamp
= _IO_list_all_stamp
;
912 _IO_lock_unlock (list_all_lock
);
913 _IO_cleanup_region_end (0);
916 INTDEF(_IO_flush_all_linebuffered
)
918 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
921 static void _IO_unbuffer_write
__P ((void));
924 _IO_unbuffer_write ()
927 for (fp
= (_IO_FILE
*) INTUSE(_IO_list_all
); fp
; fp
= fp
->_chain
)
929 if (! (fp
->_flags
& _IO_UNBUFFERED
)
930 && (! (fp
->_flags
& _IO_NO_WRITES
)
931 || (fp
->_flags
& _IO_IS_APPENDING
))
932 /* Iff stream is un-orientated, it wasn't used. */
934 _IO_SETBUF (fp
, NULL
, 0);
936 /* Make sure that never again the wide char functions can be
945 /* We do *not* want locking. Some threads might use streams but
946 that is there problem, we flush them underneath them. */
947 int result
= _IO_flush_all_lockp (0);
949 /* We currently don't have a reliable mechanism for making sure that
950 C++ static destructors are executed in the correct order.
951 So it is possible that other static destructors might want to
952 write to cout - and they're supposed to be able to do so.
954 The following will make the standard streambufs be unbuffered,
955 which forces any output from late destructors to be written out. */
956 _IO_unbuffer_write ();
963 _IO_init_marker (marker
, fp
)
964 struct _IO_marker
*marker
;
968 if (_IO_in_put_mode (fp
))
969 INTUSE(_IO_switch_to_get_mode
) (fp
);
970 if (_IO_in_backup (fp
))
971 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
973 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
975 /* Should perhaps sort the chain? */
976 marker
->_next
= fp
->_markers
;
977 fp
->_markers
= marker
;
981 _IO_remove_marker (marker
)
982 struct _IO_marker
*marker
;
984 /* Unlink from sb's chain. */
985 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
986 for (; ; ptr
= &(*ptr
)->_next
)
990 else if (*ptr
== marker
)
992 *ptr
= marker
->_next
;
997 if _sbuf has a backup area that is no longer needed
, should we
delete
998 it now
, or wait until the next underflow
?
1002 #define BAD_DELTA EOF
1005 _IO_marker_difference (mark1
, mark2
)
1006 struct _IO_marker
*mark1
;
1007 struct _IO_marker
*mark2
;
1009 return mark1
->_pos
- mark2
->_pos
;
1012 /* Return difference between MARK and current position of MARK's stream. */
1014 _IO_marker_delta (mark
)
1015 struct _IO_marker
*mark
;
1018 if (mark
->_sbuf
== NULL
)
1020 if (_IO_in_backup (mark
->_sbuf
))
1021 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
1023 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
1024 return mark
->_pos
- cur_pos
;
1028 _IO_seekmark (fp
, mark
, delta
)
1030 struct _IO_marker
*mark
;
1033 if (mark
->_sbuf
!= fp
)
1035 if (mark
->_pos
>= 0)
1037 if (_IO_in_backup (fp
))
1038 _IO_switch_to_main_get_area (fp
);
1039 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
1043 if (!_IO_in_backup (fp
))
1044 _IO_switch_to_backup_area (fp
);
1045 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1051 _IO_unsave_markers (fp
)
1054 struct _IO_marker
*mark
= fp
->_markers
;
1058 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1061 offset
+= eGptr () - Gbase ();
1062 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1063 mark
->set_streampos (mark
->_pos
+ offset
);
1067 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1068 mark
->set_streampos (EOF
);
1074 if (_IO_have_backup (fp
))
1075 INTUSE(_IO_free_backup_area
) (fp
);
1077 INTDEF(_IO_unsave_markers
)
1080 /* Seems not to be needed. --drepper */
1082 _IO_nobackup_pbackfail (fp
, c
)
1086 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1088 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1089 *fp
->_IO_read_ptr
= c
;
1090 return (unsigned char) c
;
1095 _IO_default_pbackfail (fp
, c
)
1099 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1100 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1104 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1105 if (!_IO_in_backup (fp
))
1107 /* We need to keep the invariant that the main get area
1108 logically follows the backup area. */
1109 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1111 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1114 else if (!_IO_have_backup (fp
))
1116 /* No backup buffer: allocate one. */
1117 /* Use nshort buffer, if unused? (probably not) FIXME */
1118 int backup_size
= 128;
1119 char *bbuf
= (char *) malloc (backup_size
);
1122 fp
->_IO_save_base
= bbuf
;
1123 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1124 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1126 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1127 _IO_switch_to_backup_area (fp
);
1129 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1131 /* Increase size of existing backup buffer. */
1132 _IO_size_t new_size
;
1133 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1135 new_size
= 2 * old_size
;
1136 new_buf
= (char *) malloc (new_size
);
1137 if (new_buf
== NULL
)
1139 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1141 free (fp
->_IO_read_base
);
1142 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1143 new_buf
+ new_size
);
1144 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1147 *--fp
->_IO_read_ptr
= c
;
1149 return (unsigned char) c
;
1151 INTDEF(_IO_default_pbackfail
)
1154 _IO_default_seek (fp
, offset
, dir
)
1163 _IO_default_stat (fp
, st
)
1171 _IO_default_read (fp
, data
, n
)
1180 _IO_default_write (fp
, data
, n
)
1189 _IO_default_showmanyc (fp
)
1196 _IO_default_imbue (fp
, locale
)
1205 return (_IO_ITER
) INTUSE(_IO_list_all
);
1207 libc_hidden_def (_IO_iter_begin
)
1214 libc_hidden_def (_IO_iter_end
)
1220 return iter
->_chain
;
1222 libc_hidden_def (_IO_iter_next
)
1230 libc_hidden_def (_IO_iter_file
)
1235 #ifdef _IO_MTSAFE_IO
1236 _IO_lock_lock (list_all_lock
);
1239 libc_hidden_def (_IO_list_lock
)
1244 #ifdef _IO_MTSAFE_IO
1245 _IO_lock_unlock (list_all_lock
);
1248 libc_hidden_def (_IO_list_unlock
)
1251 _IO_list_resetlock()
1253 #ifdef _IO_MTSAFE_IO
1254 _IO_lock_init (list_all_lock
);
1257 libc_hidden_def (_IO_list_resetlock
)
1262 #define IO_CLEANUP ;
1270 ~__io_defs() { _IO_cleanup (); }
1272 __io_defs io_defs__
;
1277 #ifdef text_set_element
1278 text_set_element(__libc_atexit
, _IO_cleanup
);