1 /* Copyright (C) 1993,1995,1997-1999,2000,2001 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
= &_IO_list_all
; *f
; f
= (struct _IO_FILE_plus
**) &(*f
)->file
._chain
)
73 *f
= (struct _IO_FILE_plus
*) fp
->file
._chain
;
78 fp
->file
._flags
&= ~_IO_LINKED
;
80 _IO_funlockfile ((_IO_FILE
*) fp
);
82 _IO_lock_unlock (list_all_lock
);
83 _IO_cleanup_region_end (0);
90 struct _IO_FILE_plus
*fp
;
92 if ((fp
->file
._flags
& _IO_LINKED
) == 0)
94 fp
->file
._flags
|= _IO_LINKED
;
96 _IO_cleanup_region_start_noarg (flush_cleanup
);
97 _IO_lock_lock (list_all_lock
);
98 run_fp
= (_IO_FILE
*) fp
;
99 _IO_flockfile ((_IO_FILE
*) fp
);
101 fp
->file
._chain
= (_IO_FILE
*) _IO_list_all
;
103 ++_IO_list_all_stamp
;
105 _IO_funlockfile ((_IO_FILE
*) fp
);
107 _IO_lock_unlock (list_all_lock
);
108 _IO_cleanup_region_end (0);
113 /* Return minimum _pos markers
114 Assumes the current get area is the main get area. */
115 _IO_ssize_t _IO_least_marker
__P ((_IO_FILE
*fp
, char *end_p
));
118 _IO_least_marker (fp
, end_p
)
122 _IO_ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
123 struct _IO_marker
*mark
;
124 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
125 if (mark
->_pos
< least_so_far
)
126 least_so_far
= mark
->_pos
;
130 /* Switch current get area from backup buffer to (start of) main get area. */
133 _IO_switch_to_main_get_area (fp
)
137 fp
->_flags
&= ~_IO_IN_BACKUP
;
138 /* Swap _IO_read_end and _IO_save_end. */
139 tmp
= fp
->_IO_read_end
;
140 fp
->_IO_read_end
= fp
->_IO_save_end
;
141 fp
->_IO_save_end
= tmp
;
142 /* Swap _IO_read_base and _IO_save_base. */
143 tmp
= fp
->_IO_read_base
;
144 fp
->_IO_read_base
= fp
->_IO_save_base
;
145 fp
->_IO_save_base
= tmp
;
146 /* Set _IO_read_ptr. */
147 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
150 /* Switch current get area from main get area to (end of) backup area. */
153 _IO_switch_to_backup_area (fp
)
157 fp
->_flags
|= _IO_IN_BACKUP
;
158 /* Swap _IO_read_end and _IO_save_end. */
159 tmp
= fp
->_IO_read_end
;
160 fp
->_IO_read_end
= fp
->_IO_save_end
;
161 fp
->_IO_save_end
= tmp
;
162 /* Swap _IO_read_base and _IO_save_base. */
163 tmp
= fp
->_IO_read_base
;
164 fp
->_IO_read_base
= fp
->_IO_save_base
;
165 fp
->_IO_save_base
= tmp
;
166 /* Set _IO_read_ptr. */
167 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
171 _IO_switch_to_get_mode (fp
)
174 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
175 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
177 if (_IO_in_backup (fp
))
178 fp
->_IO_read_base
= fp
->_IO_backup_base
;
181 fp
->_IO_read_base
= fp
->_IO_buf_base
;
182 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
183 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
185 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
187 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
189 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
194 _IO_free_backup_area (fp
)
197 if (_IO_in_backup (fp
))
198 _IO_switch_to_main_get_area (fp
); /* Just in case. */
199 free (fp
->_IO_save_base
);
200 fp
->_IO_save_base
= NULL
;
201 fp
->_IO_save_end
= NULL
;
202 fp
->_IO_backup_base
= NULL
;
207 _IO_switch_to_put_mode (fp
)
210 fp
->_IO_write_base
= fp
->_IO_read_ptr
;
211 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
212 /* Following is wrong if line- or un-buffered? */
213 fp
->_IO_write_end
= (fp
->_flags
& _IO_IN_BACKUP
214 ? fp
->_IO_read_end
: fp
->_IO_buf_end
);
216 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
217 fp
->_IO_read_base
= fp
->_IO_read_end
;
219 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
229 /* This is a single-byte stream. */
232 return _IO_OVERFLOW (f
, ch
);
235 static int save_for_backup
__P ((_IO_FILE
*fp
, char *end_p
))
245 save_for_backup (fp
, end_p
)
249 /* Append [_IO_read_base..end_p] to backup area. */
250 _IO_ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
251 /* needed_size is how much space we need in the backup area. */
252 _IO_size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
253 /* FIXME: Dubious arithmetic if pointers are NULL */
254 _IO_size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
255 _IO_size_t avail
; /* Extra space available for future expansion. */
257 struct _IO_marker
*mark
;
258 if (needed_size
> current_Bsize
)
262 new_buffer
= (char *) malloc (avail
+ needed_size
);
263 if (new_buffer
== NULL
)
264 return EOF
; /* FIXME */
268 __mempcpy (__mempcpy (new_buffer
+ avail
,
269 fp
->_IO_save_end
+ least_mark
,
272 end_p
- fp
->_IO_read_base
);
274 memcpy (new_buffer
+ avail
,
275 fp
->_IO_save_end
+ least_mark
,
277 memcpy (new_buffer
+ avail
- least_mark
,
279 end_p
- fp
->_IO_read_base
);
283 memcpy (new_buffer
+ avail
,
284 fp
->_IO_read_base
+ least_mark
,
286 if (fp
->_IO_save_base
)
287 free (fp
->_IO_save_base
);
288 fp
->_IO_save_base
= new_buffer
;
289 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
293 avail
= current_Bsize
- needed_size
;
296 memmove (fp
->_IO_save_base
+ avail
,
297 fp
->_IO_save_end
+ least_mark
,
299 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
301 end_p
- fp
->_IO_read_base
);
303 else if (needed_size
> 0)
304 memcpy (fp
->_IO_save_base
+ avail
,
305 fp
->_IO_read_base
+ least_mark
,
308 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
309 /* Adjust all the streammarkers. */
310 delta
= end_p
- fp
->_IO_read_base
;
311 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
320 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
321 if (fp
->_vtable_offset
== 0 && _IO_fwide (fp
, -1) != -1)
327 if (_IO_in_put_mode (fp
))
328 if (_IO_switch_to_get_mode (fp
) == EOF
)
330 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
331 return *(unsigned char *) fp
->_IO_read_ptr
;
332 if (_IO_in_backup (fp
))
334 _IO_switch_to_main_get_area (fp
);
335 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
336 return *(unsigned char *) fp
->_IO_read_ptr
;
338 if (_IO_have_markers (fp
))
340 if (save_for_backup (fp
, fp
->_IO_read_end
))
343 else if (_IO_have_backup (fp
))
344 _IO_free_backup_area (fp
);
345 return _IO_UNDERFLOW (fp
);
352 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
353 if (fp
->_vtable_offset
== 0 && _IO_fwide (fp
, -1) != -1)
359 if (_IO_in_put_mode (fp
))
360 if (_IO_switch_to_get_mode (fp
) == EOF
)
362 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
363 return *(unsigned char *) fp
->_IO_read_ptr
++;
364 if (_IO_in_backup (fp
))
366 _IO_switch_to_main_get_area (fp
);
367 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
368 return *(unsigned char *) fp
->_IO_read_ptr
++;
370 if (_IO_have_markers (fp
))
372 if (save_for_backup (fp
, fp
->_IO_read_end
))
375 else if (_IO_have_backup (fp
))
376 _IO_free_backup_area (fp
);
377 return _IO_UFLOW (fp
);
381 _IO_setb (f
, b
, eb
, a
)
387 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
388 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
392 f
->_flags
&= ~_IO_USER_BUF
;
394 f
->_flags
|= _IO_USER_BUF
;
401 if (fp
->_IO_buf_base
)
403 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
404 if (_IO_DOALLOCATE (fp
) != EOF
)
406 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
410 _IO_default_underflow (fp
)
417 _IO_default_uflow (fp
)
420 int ch
= _IO_UNDERFLOW (fp
);
423 return *(unsigned char *) fp
->_IO_read_ptr
++;
427 _IO_default_xsputn (f
, data
, n
)
432 const char *s
= (char *) data
;
438 /* Space available. */
439 _IO_ssize_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
442 if ((_IO_size_t
) count
> more
)
447 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
449 memcpy (f
->_IO_write_ptr
, s
, count
);
450 f
->_IO_write_ptr
+= count
;
458 char *p
= f
->_IO_write_ptr
;
460 for (i
= count
; --i
>= 0; )
462 f
->_IO_write_ptr
= p
;
466 if (more
== 0 || _IO_OVERFLOW (f
, (unsigned char) *s
++) == EOF
)
474 _IO_sgetn (fp
, data
, n
)
479 /* FIXME handle putback buffer here! */
480 return _IO_XSGETN (fp
, data
, n
);
484 _IO_default_xsgetn (fp
, data
, n
)
490 char *s
= (char*) data
;
493 /* Data available. */
494 _IO_ssize_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
497 if ((_IO_size_t
) count
> more
)
502 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
504 memcpy (s
, fp
->_IO_read_ptr
, count
);
507 fp
->_IO_read_ptr
+= count
;
513 char *p
= fp
->_IO_read_ptr
;
517 fp
->_IO_read_ptr
= p
;
521 if (more
== 0 || __underflow (fp
) == EOF
)
528 /* Seems not to be needed. --drepper */
538 _IO_default_setbuf (fp
, p
, len
)
543 if (_IO_SYNC (fp
) == EOF
)
545 if (p
== NULL
|| len
== 0)
547 fp
->_flags
|= _IO_UNBUFFERED
;
548 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
552 fp
->_flags
&= ~_IO_UNBUFFERED
;
553 _IO_setb (fp
, p
, p
+len
, 0);
555 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
556 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
561 _IO_default_seekpos (fp
, pos
, mode
)
566 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
570 _IO_default_doallocate (fp
)
575 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
576 _IO_setb (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
585 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
589 _IO_no_init (fp
, flags
, orientation
, wd
, jmp
)
593 struct _IO_wide_data
*wd
;
594 struct _IO_jump_t
*jmp
;
596 fp
->_flags
= _IO_MAGIC
|flags
;
597 fp
->_IO_buf_base
= NULL
;
598 fp
->_IO_buf_end
= NULL
;
599 fp
->_IO_read_base
= NULL
;
600 fp
->_IO_read_ptr
= NULL
;
601 fp
->_IO_read_end
= NULL
;
602 fp
->_IO_write_base
= NULL
;
603 fp
->_IO_write_ptr
= NULL
;
604 fp
->_IO_write_end
= NULL
;
605 fp
->_chain
= NULL
; /* Not necessary. */
607 fp
->_IO_save_base
= NULL
;
608 fp
->_IO_backup_base
= NULL
;
609 fp
->_IO_save_end
= NULL
;
613 fp
->_vtable_offset
= 0;
616 if (fp
->_lock
!= NULL
)
617 _IO_lock_init (*fp
->_lock
);
619 fp
->_mode
= orientation
;
620 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
621 if (orientation
>= 0)
624 fp
->_wide_data
->_IO_buf_base
= NULL
;
625 fp
->_wide_data
->_IO_buf_end
= NULL
;
626 fp
->_wide_data
->_IO_read_base
= NULL
;
627 fp
->_wide_data
->_IO_read_ptr
= NULL
;
628 fp
->_wide_data
->_IO_read_end
= NULL
;
629 fp
->_wide_data
->_IO_write_base
= NULL
;
630 fp
->_wide_data
->_IO_write_ptr
= NULL
;
631 fp
->_wide_data
->_IO_write_end
= NULL
;
632 fp
->_wide_data
->_IO_save_base
= NULL
;
633 fp
->_wide_data
->_IO_backup_base
= NULL
;
634 fp
->_wide_data
->_IO_save_end
= NULL
;
636 fp
->_wide_data
->_wide_vtable
= jmp
;
642 _IO_default_sync (fp
)
648 /* The way the C++ classes are mapped into the C functions in the
649 current implementation, this function can get called twice! */
652 _IO_default_finish (fp
, dummy
)
656 struct _IO_marker
*mark
;
657 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
659 FREE_BUF (fp
->_IO_buf_base
, _IO_blen (fp
));
660 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
663 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
666 if (fp
->_IO_save_base
)
668 free (fp
->_IO_save_base
);
669 fp
->_IO_save_base
= NULL
;
673 if (fp
->_lock
!= NULL
)
674 _IO_lock_fini (*fp
->_lock
);
677 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
681 _IO_default_seekoff (fp
, offset
, dir
, mode
)
691 _IO_sputbackc (fp
, c
)
697 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
698 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
701 result
= (unsigned char) c
;
704 result
= _IO_PBACKFAIL (fp
, c
);
707 fp
->_flags
&= ~_IO_EOF_SEEN
;
718 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
721 result
= (unsigned char) *fp
->_IO_read_ptr
;
724 result
= _IO_PBACKFAIL (fp
, EOF
);
727 fp
->_flags
&= ~_IO_EOF_SEEN
;
732 #if 0 /* Work in progress */
733 /* Seems not to be needed. */
736 _IO_set_column (fp
, c
)
743 fp
->_column
= c
- (fp
->_IO_write_ptr
- fp
->_IO_write_base
);
747 _IO_set_column (fp
, i
)
751 fp
->_cur_column
= i
+ 1;
759 _IO_adjust_column (start
, line
, count
)
764 const char *ptr
= line
+ count
;
767 return line
+ count
- ptr
- 1;
768 return start
+ count
;
772 /* Seems not to be needed. --drepper */
778 return _IO_adjust_column (fp
->_cur_column
- 1,
780 fp
->_IO_write_ptr
- fp
->_IO_write_base
);
794 _IO_cleanup_region_start_noarg (flush_cleanup
);
795 _IO_lock_lock (list_all_lock
);
798 last_stamp
= _IO_list_all_stamp
;
799 fp
= (_IO_FILE
*) _IO_list_all
;
805 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
806 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
807 || (fp
->_vtable_offset
== 0
808 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
809 > fp
->_wide_data
->_IO_write_base
))
812 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
815 _IO_funlockfile (fp
);
818 if (last_stamp
!= _IO_list_all_stamp
)
820 /* Something was added to the list. Start all over again. */
821 fp
= (_IO_FILE
*) _IO_list_all
;
822 last_stamp
= _IO_list_all_stamp
;
829 _IO_lock_unlock (list_all_lock
);
830 _IO_cleanup_region_end (0);
837 _IO_flush_all_linebuffered ()
843 _IO_cleanup_region_start_noarg (flush_cleanup
);
844 _IO_lock_lock (list_all_lock
);
847 last_stamp
= _IO_list_all_stamp
;
848 fp
= (_IO_FILE
*) _IO_list_all
;
854 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
855 _IO_OVERFLOW (fp
, EOF
);
857 _IO_funlockfile (fp
);
860 if (last_stamp
!= _IO_list_all_stamp
)
862 /* Something was added to the list. Start all over again. */
863 fp
= (_IO_FILE
*) _IO_list_all
;
864 last_stamp
= _IO_list_all_stamp
;
871 _IO_lock_unlock (list_all_lock
);
872 _IO_cleanup_region_end (0);
876 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
879 static void _IO_unbuffer_write
__P ((void));
882 _IO_unbuffer_write ()
885 for (fp
= (_IO_FILE
*) _IO_list_all
; fp
; fp
= fp
->_chain
)
887 if (! (fp
->_flags
& _IO_UNBUFFERED
)
888 && (! (fp
->_flags
& _IO_NO_WRITES
)
889 || (fp
->_flags
& _IO_IS_APPENDING
))
890 /* Iff stream is un-orientated, it wasn't used. */
892 _IO_SETBUF (fp
, NULL
, 0);
894 /* Make sure that never again the wide char functions can be
903 int result
= _IO_flush_all ();
905 /* We currently don't have a reliable mechanism for making sure that
906 C++ static destructors are executed in the correct order.
907 So it is possible that other static destructors might want to
908 write to cout - and they're supposed to be able to do so.
910 The following will make the standard streambufs be unbuffered,
911 which forces any output from late destructors to be written out. */
912 _IO_unbuffer_write ();
919 _IO_init_marker (marker
, fp
)
920 struct _IO_marker
*marker
;
924 if (_IO_in_put_mode (fp
))
925 _IO_switch_to_get_mode (fp
);
926 if (_IO_in_backup (fp
))
927 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
929 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
931 /* Should perhaps sort the chain? */
932 marker
->_next
= fp
->_markers
;
933 fp
->_markers
= marker
;
937 _IO_remove_marker (marker
)
938 struct _IO_marker
*marker
;
940 /* Unlink from sb's chain. */
941 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
942 for (; ; ptr
= &(*ptr
)->_next
)
946 else if (*ptr
== marker
)
948 *ptr
= marker
->_next
;
953 if _sbuf has a backup area that is no longer needed
, should we
delete
954 it now
, or wait until the next underflow
?
958 #define BAD_DELTA EOF
961 _IO_marker_difference (mark1
, mark2
)
962 struct _IO_marker
*mark1
;
963 struct _IO_marker
*mark2
;
965 return mark1
->_pos
- mark2
->_pos
;
968 /* Return difference between MARK and current position of MARK's stream. */
970 _IO_marker_delta (mark
)
971 struct _IO_marker
*mark
;
974 if (mark
->_sbuf
== NULL
)
976 if (_IO_in_backup (mark
->_sbuf
))
977 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
979 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
980 return mark
->_pos
- cur_pos
;
984 _IO_seekmark (fp
, mark
, delta
)
986 struct _IO_marker
*mark
;
989 if (mark
->_sbuf
!= fp
)
993 if (_IO_in_backup (fp
))
994 _IO_switch_to_main_get_area (fp
);
995 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
999 if (!_IO_in_backup (fp
))
1000 _IO_switch_to_backup_area (fp
);
1001 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1007 _IO_unsave_markers (fp
)
1010 struct _IO_marker
*mark
= fp
->_markers
;
1014 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1017 offset
+= eGptr () - Gbase ();
1018 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1019 mark
->set_streampos (mark
->_pos
+ offset
);
1023 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1024 mark
->set_streampos (EOF
);
1030 if (_IO_have_backup (fp
))
1031 _IO_free_backup_area (fp
);
1035 /* Seems not to be needed. --drepper */
1037 _IO_nobackup_pbackfail (fp
, c
)
1041 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1043 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1044 *fp
->_IO_read_ptr
= c
;
1045 return (unsigned char) c
;
1050 _IO_default_pbackfail (fp
, c
)
1054 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1055 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1059 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1060 if (!_IO_in_backup (fp
))
1062 /* We need to keep the invariant that the main get area
1063 logically follows the backup area. */
1064 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1066 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1069 else if (!_IO_have_backup (fp
))
1071 /* No backup buffer: allocate one. */
1072 /* Use nshort buffer, if unused? (probably not) FIXME */
1073 int backup_size
= 128;
1074 char *bbuf
= (char *) malloc (backup_size
);
1077 fp
->_IO_save_base
= bbuf
;
1078 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1079 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1081 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1082 _IO_switch_to_backup_area (fp
);
1084 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1086 /* Increase size of existing backup buffer. */
1087 _IO_size_t new_size
;
1088 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1090 new_size
= 2 * old_size
;
1091 new_buf
= (char *) malloc (new_size
);
1092 if (new_buf
== NULL
)
1094 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1096 free (fp
->_IO_read_base
);
1097 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1098 new_buf
+ new_size
);
1099 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1102 *--fp
->_IO_read_ptr
= c
;
1104 return (unsigned char) c
;
1108 _IO_default_seek (fp
, offset
, dir
)
1117 _IO_default_stat (fp
, st
)
1125 _IO_default_read (fp
, data
, n
)
1134 _IO_default_write (fp
, data
, n
)
1143 _IO_default_showmanyc (fp
)
1150 _IO_default_imbue (fp
, locale
)
1159 return (_IO_ITER
) _IO_list_all
;
1172 return iter
->_chain
;
1185 #ifdef _IO_MTSAFE_IO
1186 _IO_lock_lock (list_all_lock
);
1193 #ifdef _IO_MTSAFE_IO
1194 _IO_lock_unlock (list_all_lock
);
1199 _IO_list_resetlock()
1201 #ifdef _IO_MTSAFE_IO
1202 _IO_lock_init (list_all_lock
);
1209 #define IO_CLEANUP ;
1217 ~__io_defs() { _IO_cleanup (); }
1219 __io_defs io_defs__
;
1225 weak_alias (_IO_cleanup
, _cleanup
)
1228 #ifdef text_set_element
1229 text_set_element(__libc_atexit
, _cleanup
);