1 /* Copyright (C) 1993,1995,1997-2001,2002 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
);
240 static int save_for_backup
__P ((_IO_FILE
*fp
, char *end_p
))
250 save_for_backup (fp
, end_p
)
254 /* Append [_IO_read_base..end_p] to backup area. */
255 _IO_ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
256 /* needed_size is how much space we need in the backup area. */
257 _IO_size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
258 /* FIXME: Dubious arithmetic if pointers are NULL */
259 _IO_size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
260 _IO_size_t avail
; /* Extra space available for future expansion. */
262 struct _IO_marker
*mark
;
263 if (needed_size
> current_Bsize
)
267 new_buffer
= (char *) malloc (avail
+ needed_size
);
268 if (new_buffer
== NULL
)
269 return EOF
; /* FIXME */
273 __mempcpy (__mempcpy (new_buffer
+ avail
,
274 fp
->_IO_save_end
+ least_mark
,
277 end_p
- fp
->_IO_read_base
);
279 memcpy (new_buffer
+ avail
,
280 fp
->_IO_save_end
+ least_mark
,
282 memcpy (new_buffer
+ avail
- least_mark
,
284 end_p
- fp
->_IO_read_base
);
288 memcpy (new_buffer
+ avail
,
289 fp
->_IO_read_base
+ least_mark
,
291 if (fp
->_IO_save_base
)
292 free (fp
->_IO_save_base
);
293 fp
->_IO_save_base
= new_buffer
;
294 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
298 avail
= current_Bsize
- needed_size
;
301 memmove (fp
->_IO_save_base
+ avail
,
302 fp
->_IO_save_end
+ least_mark
,
304 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
306 end_p
- fp
->_IO_read_base
);
308 else if (needed_size
> 0)
309 memcpy (fp
->_IO_save_base
+ avail
,
310 fp
->_IO_read_base
+ least_mark
,
313 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
314 /* Adjust all the streammarkers. */
315 delta
= end_p
- fp
->_IO_read_base
;
316 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
325 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
326 if (fp
->_vtable_offset
== 0 && _IO_fwide (fp
, -1) != -1)
332 if (_IO_in_put_mode (fp
))
333 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
335 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
336 return *(unsigned char *) fp
->_IO_read_ptr
;
337 if (_IO_in_backup (fp
))
339 _IO_switch_to_main_get_area (fp
);
340 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
341 return *(unsigned char *) fp
->_IO_read_ptr
;
343 if (_IO_have_markers (fp
))
345 if (save_for_backup (fp
, fp
->_IO_read_end
))
348 else if (_IO_have_backup (fp
))
349 INTUSE(_IO_free_backup_area
) (fp
);
350 return _IO_UNDERFLOW (fp
);
357 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
358 if (fp
->_vtable_offset
== 0 && _IO_fwide (fp
, -1) != -1)
364 if (_IO_in_put_mode (fp
))
365 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
367 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
368 return *(unsigned char *) fp
->_IO_read_ptr
++;
369 if (_IO_in_backup (fp
))
371 _IO_switch_to_main_get_area (fp
);
372 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
373 return *(unsigned char *) fp
->_IO_read_ptr
++;
375 if (_IO_have_markers (fp
))
377 if (save_for_backup (fp
, fp
->_IO_read_end
))
380 else if (_IO_have_backup (fp
))
381 INTUSE(_IO_free_backup_area
) (fp
);
382 return _IO_UFLOW (fp
);
386 _IO_setb (f
, b
, eb
, a
)
392 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
393 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
397 f
->_flags
&= ~_IO_USER_BUF
;
399 f
->_flags
|= _IO_USER_BUF
;
407 if (fp
->_IO_buf_base
)
409 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
410 if (_IO_DOALLOCATE (fp
) != EOF
)
412 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
414 INTDEF(_IO_doallocbuf
)
417 _IO_default_underflow (fp
)
424 _IO_default_uflow (fp
)
427 int ch
= _IO_UNDERFLOW (fp
);
430 return *(unsigned char *) fp
->_IO_read_ptr
++;
432 INTDEF(_IO_default_uflow
)
435 _IO_default_xsputn (f
, data
, n
)
440 const char *s
= (char *) data
;
446 /* Space available. */
447 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
450 if ((_IO_size_t
) count
> more
)
455 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
457 memcpy (f
->_IO_write_ptr
, s
, count
);
458 f
->_IO_write_ptr
+= count
;
466 char *p
= f
->_IO_write_ptr
;
468 for (i
= count
; --i
>= 0; )
470 f
->_IO_write_ptr
= p
;
474 if (more
== 0 || _IO_OVERFLOW (f
, (unsigned char) *s
++) == EOF
)
480 INTDEF(_IO_default_xsputn
)
483 _IO_sgetn (fp
, data
, n
)
488 /* FIXME handle putback buffer here! */
489 return _IO_XSGETN (fp
, data
, n
);
494 _IO_default_xsgetn (fp
, data
, n
)
500 char *s
= (char*) data
;
503 /* Data available. */
504 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
507 if ((_IO_size_t
) count
> more
)
512 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
514 memcpy (s
, fp
->_IO_read_ptr
, count
);
517 fp
->_IO_read_ptr
+= count
;
523 char *p
= fp
->_IO_read_ptr
;
527 fp
->_IO_read_ptr
= p
;
531 if (more
== 0 || __underflow (fp
) == EOF
)
536 INTDEF(_IO_default_xsgetn
)
539 /* Seems not to be needed. --drepper */
549 _IO_default_setbuf (fp
, p
, len
)
554 if (_IO_SYNC (fp
) == EOF
)
556 if (p
== NULL
|| len
== 0)
558 fp
->_flags
|= _IO_UNBUFFERED
;
559 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
563 fp
->_flags
&= ~_IO_UNBUFFERED
;
564 INTUSE(_IO_setb
) (fp
, p
, p
+len
, 0);
566 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
567 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
572 _IO_default_seekpos (fp
, pos
, mode
)
577 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
581 _IO_default_doallocate (fp
)
586 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
587 INTUSE(_IO_setb
) (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
590 INTDEF(_IO_default_doallocate
)
597 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
602 _IO_no_init (fp
, flags
, orientation
, wd
, jmp
)
606 struct _IO_wide_data
*wd
;
607 struct _IO_jump_t
*jmp
;
609 fp
->_flags
= _IO_MAGIC
|flags
;
610 fp
->_IO_buf_base
= NULL
;
611 fp
->_IO_buf_end
= NULL
;
612 fp
->_IO_read_base
= NULL
;
613 fp
->_IO_read_ptr
= NULL
;
614 fp
->_IO_read_end
= NULL
;
615 fp
->_IO_write_base
= NULL
;
616 fp
->_IO_write_ptr
= NULL
;
617 fp
->_IO_write_end
= NULL
;
618 fp
->_chain
= NULL
; /* Not necessary. */
620 fp
->_IO_save_base
= NULL
;
621 fp
->_IO_backup_base
= NULL
;
622 fp
->_IO_save_end
= NULL
;
626 fp
->_vtable_offset
= 0;
629 if (fp
->_lock
!= NULL
)
630 _IO_lock_init (*fp
->_lock
);
632 fp
->_mode
= orientation
;
633 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
634 if (orientation
>= 0)
637 fp
->_wide_data
->_IO_buf_base
= NULL
;
638 fp
->_wide_data
->_IO_buf_end
= NULL
;
639 fp
->_wide_data
->_IO_read_base
= NULL
;
640 fp
->_wide_data
->_IO_read_ptr
= NULL
;
641 fp
->_wide_data
->_IO_read_end
= NULL
;
642 fp
->_wide_data
->_IO_write_base
= NULL
;
643 fp
->_wide_data
->_IO_write_ptr
= NULL
;
644 fp
->_wide_data
->_IO_write_end
= NULL
;
645 fp
->_wide_data
->_IO_save_base
= NULL
;
646 fp
->_wide_data
->_IO_backup_base
= NULL
;
647 fp
->_wide_data
->_IO_save_end
= NULL
;
649 fp
->_wide_data
->_wide_vtable
= jmp
;
655 _IO_default_sync (fp
)
661 /* The way the C++ classes are mapped into the C functions in the
662 current implementation, this function can get called twice! */
665 _IO_default_finish (fp
, dummy
)
669 struct _IO_marker
*mark
;
670 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
672 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
673 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
676 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
679 if (fp
->_IO_save_base
)
681 free (fp
->_IO_save_base
);
682 fp
->_IO_save_base
= NULL
;
686 if (fp
->_lock
!= NULL
)
687 _IO_lock_fini (*fp
->_lock
);
690 INTUSE(_IO_un_link
) ((struct _IO_FILE_plus
*) fp
);
692 INTDEF(_IO_default_finish
)
695 _IO_default_seekoff (fp
, offset
, dir
, mode
)
705 _IO_sputbackc (fp
, c
)
711 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
712 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
715 result
= (unsigned char) c
;
718 result
= _IO_PBACKFAIL (fp
, c
);
721 fp
->_flags
&= ~_IO_EOF_SEEN
;
725 INTDEF(_IO_sputbackc
)
733 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
736 result
= (unsigned char) *fp
->_IO_read_ptr
;
739 result
= _IO_PBACKFAIL (fp
, EOF
);
742 fp
->_flags
&= ~_IO_EOF_SEEN
;
747 #if 0 /* Work in progress */
748 /* Seems not to be needed. */
751 _IO_set_column (fp
, c
)
758 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
762 _IO_set_column (fp
, i
)
766 fp
->_cur_column
= i
+ 1;
774 _IO_adjust_column (start
, line
, count
)
779 const char *ptr
= line
+ count
;
782 return line
+ count
- ptr
- 1;
783 return start
+ count
;
785 INTDEF(_IO_adjust_column
)
788 /* Seems not to be needed. --drepper */
794 return _IO_adjust_column (fp
->_cur_column
- 1,
796 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
803 _IO_flush_all_lockp (int do_lock
)
810 _IO_cleanup_region_start_noarg (flush_cleanup
);
812 _IO_lock_lock (list_all_lock
);
815 last_stamp
= _IO_list_all_stamp
;
816 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
823 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
824 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
825 || (fp
->_vtable_offset
== 0
826 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
827 > fp
->_wide_data
->_IO_write_base
))
830 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
834 _IO_funlockfile (fp
);
837 if (last_stamp
!= _IO_list_all_stamp
)
839 /* Something was added to the list. Start all over again. */
840 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
841 last_stamp
= _IO_list_all_stamp
;
849 _IO_lock_unlock (list_all_lock
);
850 _IO_cleanup_region_end (0);
860 /* We want locking. */
861 return _IO_flush_all_lockp (1);
863 INTDEF(_IO_flush_all
)
866 _IO_flush_all_linebuffered ()
872 _IO_cleanup_region_start_noarg (flush_cleanup
);
873 _IO_lock_lock (list_all_lock
);
876 last_stamp
= _IO_list_all_stamp
;
877 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
883 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
884 _IO_OVERFLOW (fp
, EOF
);
886 _IO_funlockfile (fp
);
889 if (last_stamp
!= _IO_list_all_stamp
)
891 /* Something was added to the list. Start all over again. */
892 fp
= (_IO_FILE
*) INTUSE(_IO_list_all
);
893 last_stamp
= _IO_list_all_stamp
;
900 _IO_lock_unlock (list_all_lock
);
901 _IO_cleanup_region_end (0);
904 INTDEF(_IO_flush_all_linebuffered
)
906 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
909 static void _IO_unbuffer_write
__P ((void));
912 _IO_unbuffer_write ()
915 for (fp
= (_IO_FILE
*) INTUSE(_IO_list_all
); fp
; fp
= fp
->_chain
)
917 if (! (fp
->_flags
& _IO_UNBUFFERED
)
918 && (! (fp
->_flags
& _IO_NO_WRITES
)
919 || (fp
->_flags
& _IO_IS_APPENDING
))
920 /* Iff stream is un-orientated, it wasn't used. */
922 _IO_SETBUF (fp
, NULL
, 0);
924 /* Make sure that never again the wide char functions can be
933 int result
= INTUSE(_IO_flush_all
) ();
935 /* We currently don't have a reliable mechanism for making sure that
936 C++ static destructors are executed in the correct order.
937 So it is possible that other static destructors might want to
938 write to cout - and they're supposed to be able to do so.
940 The following will make the standard streambufs be unbuffered,
941 which forces any output from late destructors to be written out. */
942 _IO_unbuffer_write ();
949 _IO_init_marker (marker
, fp
)
950 struct _IO_marker
*marker
;
954 if (_IO_in_put_mode (fp
))
955 INTUSE(_IO_switch_to_get_mode
) (fp
);
956 if (_IO_in_backup (fp
))
957 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
959 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
961 /* Should perhaps sort the chain? */
962 marker
->_next
= fp
->_markers
;
963 fp
->_markers
= marker
;
967 _IO_remove_marker (marker
)
968 struct _IO_marker
*marker
;
970 /* Unlink from sb's chain. */
971 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
972 for (; ; ptr
= &(*ptr
)->_next
)
976 else if (*ptr
== marker
)
978 *ptr
= marker
->_next
;
983 if _sbuf has a backup area that is no longer needed
, should we
delete
984 it now
, or wait until the next underflow
?
988 #define BAD_DELTA EOF
991 _IO_marker_difference (mark1
, mark2
)
992 struct _IO_marker
*mark1
;
993 struct _IO_marker
*mark2
;
995 return mark1
->_pos
- mark2
->_pos
;
998 /* Return difference between MARK and current position of MARK's stream. */
1000 _IO_marker_delta (mark
)
1001 struct _IO_marker
*mark
;
1004 if (mark
->_sbuf
== NULL
)
1006 if (_IO_in_backup (mark
->_sbuf
))
1007 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
1009 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
1010 return mark
->_pos
- cur_pos
;
1014 _IO_seekmark (fp
, mark
, delta
)
1016 struct _IO_marker
*mark
;
1019 if (mark
->_sbuf
!= fp
)
1021 if (mark
->_pos
>= 0)
1023 if (_IO_in_backup (fp
))
1024 _IO_switch_to_main_get_area (fp
);
1025 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
1029 if (!_IO_in_backup (fp
))
1030 _IO_switch_to_backup_area (fp
);
1031 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1037 _IO_unsave_markers (fp
)
1040 struct _IO_marker
*mark
= fp
->_markers
;
1044 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1047 offset
+= eGptr () - Gbase ();
1048 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1049 mark
->set_streampos (mark
->_pos
+ offset
);
1053 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1054 mark
->set_streampos (EOF
);
1060 if (_IO_have_backup (fp
))
1061 INTUSE(_IO_free_backup_area
) (fp
);
1063 INTDEF(_IO_unsave_markers
)
1066 /* Seems not to be needed. --drepper */
1068 _IO_nobackup_pbackfail (fp
, c
)
1072 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1074 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1075 *fp
->_IO_read_ptr
= c
;
1076 return (unsigned char) c
;
1081 _IO_default_pbackfail (fp
, c
)
1085 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1086 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1090 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1091 if (!_IO_in_backup (fp
))
1093 /* We need to keep the invariant that the main get area
1094 logically follows the backup area. */
1095 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1097 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1100 else if (!_IO_have_backup (fp
))
1102 /* No backup buffer: allocate one. */
1103 /* Use nshort buffer, if unused? (probably not) FIXME */
1104 int backup_size
= 128;
1105 char *bbuf
= (char *) malloc (backup_size
);
1108 fp
->_IO_save_base
= bbuf
;
1109 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1110 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1112 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1113 _IO_switch_to_backup_area (fp
);
1115 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1117 /* Increase size of existing backup buffer. */
1118 _IO_size_t new_size
;
1119 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1121 new_size
= 2 * old_size
;
1122 new_buf
= (char *) malloc (new_size
);
1123 if (new_buf
== NULL
)
1125 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1127 free (fp
->_IO_read_base
);
1128 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1129 new_buf
+ new_size
);
1130 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1133 *--fp
->_IO_read_ptr
= c
;
1135 return (unsigned char) c
;
1137 INTDEF(_IO_default_pbackfail
)
1140 _IO_default_seek (fp
, offset
, dir
)
1149 _IO_default_stat (fp
, st
)
1157 _IO_default_read (fp
, data
, n
)
1166 _IO_default_write (fp
, data
, n
)
1175 _IO_default_showmanyc (fp
)
1182 _IO_default_imbue (fp
, locale
)
1191 return (_IO_ITER
) INTUSE(_IO_list_all
);
1204 return iter
->_chain
;
1217 #ifdef _IO_MTSAFE_IO
1218 _IO_lock_lock (list_all_lock
);
1225 #ifdef _IO_MTSAFE_IO
1226 _IO_lock_unlock (list_all_lock
);
1231 _IO_list_resetlock()
1233 #ifdef _IO_MTSAFE_IO
1234 _IO_lock_init (list_all_lock
);
1241 #define IO_CLEANUP ;
1249 ~__io_defs() { _IO_cleanup (); }
1251 __io_defs io_defs__
;
1257 weak_alias (_IO_cleanup
, _cleanup
)
1260 #ifdef text_set_element
1261 text_set_element(__libc_atexit
, _cleanup
);