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
);
787 _IO_flush_all_lockp (int do_lock
)
794 _IO_cleanup_region_start_noarg (flush_cleanup
);
796 _IO_lock_lock (list_all_lock
);
799 last_stamp
= _IO_list_all_stamp
;
800 fp
= (_IO_FILE
*) _IO_list_all
;
807 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
808 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
809 || (fp
->_vtable_offset
== 0
810 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
811 > fp
->_wide_data
->_IO_write_base
))
814 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
818 _IO_funlockfile (fp
);
821 if (last_stamp
!= _IO_list_all_stamp
)
823 /* Something was added to the list. Start all over again. */
824 fp
= (_IO_FILE
*) _IO_list_all
;
825 last_stamp
= _IO_list_all_stamp
;
833 _IO_lock_unlock (list_all_lock
);
834 _IO_cleanup_region_end (0);
844 /* We want locking. */
845 return _IO_flush_all_lockp (1);
849 _IO_flush_all_linebuffered ()
855 _IO_cleanup_region_start_noarg (flush_cleanup
);
856 _IO_lock_lock (list_all_lock
);
859 last_stamp
= _IO_list_all_stamp
;
860 fp
= (_IO_FILE
*) _IO_list_all
;
866 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
867 _IO_OVERFLOW (fp
, EOF
);
869 _IO_funlockfile (fp
);
872 if (last_stamp
!= _IO_list_all_stamp
)
874 /* Something was added to the list. Start all over again. */
875 fp
= (_IO_FILE
*) _IO_list_all
;
876 last_stamp
= _IO_list_all_stamp
;
883 _IO_lock_unlock (list_all_lock
);
884 _IO_cleanup_region_end (0);
888 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
891 static void _IO_unbuffer_write
__P ((void));
894 _IO_unbuffer_write ()
897 for (fp
= (_IO_FILE
*) _IO_list_all
; fp
; fp
= fp
->_chain
)
899 if (! (fp
->_flags
& _IO_UNBUFFERED
)
900 && (! (fp
->_flags
& _IO_NO_WRITES
)
901 || (fp
->_flags
& _IO_IS_APPENDING
))
902 /* Iff stream is un-orientated, it wasn't used. */
904 _IO_SETBUF (fp
, NULL
, 0);
906 /* Make sure that never again the wide char functions can be
915 int result
= _IO_flush_all ();
917 /* We currently don't have a reliable mechanism for making sure that
918 C++ static destructors are executed in the correct order.
919 So it is possible that other static destructors might want to
920 write to cout - and they're supposed to be able to do so.
922 The following will make the standard streambufs be unbuffered,
923 which forces any output from late destructors to be written out. */
924 _IO_unbuffer_write ();
931 _IO_init_marker (marker
, fp
)
932 struct _IO_marker
*marker
;
936 if (_IO_in_put_mode (fp
))
937 _IO_switch_to_get_mode (fp
);
938 if (_IO_in_backup (fp
))
939 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
941 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
943 /* Should perhaps sort the chain? */
944 marker
->_next
= fp
->_markers
;
945 fp
->_markers
= marker
;
949 _IO_remove_marker (marker
)
950 struct _IO_marker
*marker
;
952 /* Unlink from sb's chain. */
953 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
954 for (; ; ptr
= &(*ptr
)->_next
)
958 else if (*ptr
== marker
)
960 *ptr
= marker
->_next
;
965 if _sbuf has a backup area that is no longer needed
, should we
delete
966 it now
, or wait until the next underflow
?
970 #define BAD_DELTA EOF
973 _IO_marker_difference (mark1
, mark2
)
974 struct _IO_marker
*mark1
;
975 struct _IO_marker
*mark2
;
977 return mark1
->_pos
- mark2
->_pos
;
980 /* Return difference between MARK and current position of MARK's stream. */
982 _IO_marker_delta (mark
)
983 struct _IO_marker
*mark
;
986 if (mark
->_sbuf
== NULL
)
988 if (_IO_in_backup (mark
->_sbuf
))
989 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
991 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
992 return mark
->_pos
- cur_pos
;
996 _IO_seekmark (fp
, mark
, delta
)
998 struct _IO_marker
*mark
;
1001 if (mark
->_sbuf
!= fp
)
1003 if (mark
->_pos
>= 0)
1005 if (_IO_in_backup (fp
))
1006 _IO_switch_to_main_get_area (fp
);
1007 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
1011 if (!_IO_in_backup (fp
))
1012 _IO_switch_to_backup_area (fp
);
1013 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1019 _IO_unsave_markers (fp
)
1022 struct _IO_marker
*mark
= fp
->_markers
;
1026 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1029 offset
+= eGptr () - Gbase ();
1030 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1031 mark
->set_streampos (mark
->_pos
+ offset
);
1035 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1036 mark
->set_streampos (EOF
);
1042 if (_IO_have_backup (fp
))
1043 _IO_free_backup_area (fp
);
1047 /* Seems not to be needed. --drepper */
1049 _IO_nobackup_pbackfail (fp
, c
)
1053 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1055 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1056 *fp
->_IO_read_ptr
= c
;
1057 return (unsigned char) c
;
1062 _IO_default_pbackfail (fp
, c
)
1066 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1067 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1071 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1072 if (!_IO_in_backup (fp
))
1074 /* We need to keep the invariant that the main get area
1075 logically follows the backup area. */
1076 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1078 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1081 else if (!_IO_have_backup (fp
))
1083 /* No backup buffer: allocate one. */
1084 /* Use nshort buffer, if unused? (probably not) FIXME */
1085 int backup_size
= 128;
1086 char *bbuf
= (char *) malloc (backup_size
);
1089 fp
->_IO_save_base
= bbuf
;
1090 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1091 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1093 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1094 _IO_switch_to_backup_area (fp
);
1096 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1098 /* Increase size of existing backup buffer. */
1099 _IO_size_t new_size
;
1100 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1102 new_size
= 2 * old_size
;
1103 new_buf
= (char *) malloc (new_size
);
1104 if (new_buf
== NULL
)
1106 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1108 free (fp
->_IO_read_base
);
1109 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1110 new_buf
+ new_size
);
1111 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1114 *--fp
->_IO_read_ptr
= c
;
1116 return (unsigned char) c
;
1120 _IO_default_seek (fp
, offset
, dir
)
1129 _IO_default_stat (fp
, st
)
1137 _IO_default_read (fp
, data
, n
)
1146 _IO_default_write (fp
, data
, n
)
1155 _IO_default_showmanyc (fp
)
1162 _IO_default_imbue (fp
, locale
)
1171 return (_IO_ITER
) _IO_list_all
;
1184 return iter
->_chain
;
1197 #ifdef _IO_MTSAFE_IO
1198 _IO_lock_lock (list_all_lock
);
1205 #ifdef _IO_MTSAFE_IO
1206 _IO_lock_unlock (list_all_lock
);
1211 _IO_list_resetlock()
1213 #ifdef _IO_MTSAFE_IO
1214 _IO_lock_init (list_all_lock
);
1221 #define IO_CLEANUP ;
1229 ~__io_defs() { _IO_cleanup (); }
1231 __io_defs io_defs__
;
1237 weak_alias (_IO_cleanup
, _cleanup
)
1240 #ifdef text_set_element
1241 text_set_element(__libc_atexit
, _cleanup
);