1 /* Copyright (C) 1993,1995,1997-2002, 2003, 2004, 2006
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 As a special exception, if you link the code in this file with
21 files compiled with a GNU compiler to produce an executable,
22 that does not cause the resulting executable to be covered by
23 the GNU Lesser General Public License. This exception does not
24 however invalidate any other reasons why the executable file
25 might be covered by the GNU Lesser General Public License.
26 This exception applies to code released by its copyright holders
27 in files containing the exception. */
29 /* Generic or default I/O operations. */
39 static _IO_lock_t list_all_lock
= _IO_lock_initializer
;
42 /* Used to signal modifications to the list of FILE decriptors. */
43 static int _IO_list_all_stamp
;
46 static _IO_FILE
*run_fp
;
49 flush_cleanup (void *not_used
)
52 _IO_funlockfile (run_fp
);
54 _IO_lock_unlock (list_all_lock
);
60 struct _IO_FILE_plus
*fp
;
62 if (fp
->file
._flags
& _IO_LINKED
)
64 struct _IO_FILE_plus
**f
;
66 _IO_cleanup_region_start_noarg (flush_cleanup
);
67 _IO_lock_lock (list_all_lock
);
68 run_fp
= (_IO_FILE
*) fp
;
69 _IO_flockfile ((_IO_FILE
*) fp
);
71 for (f
= &INTUSE(_IO_list_all
); *f
;
72 f
= (struct _IO_FILE_plus
**) &(*f
)->file
._chain
)
76 *f
= (struct _IO_FILE_plus
*) fp
->file
._chain
;
81 fp
->file
._flags
&= ~_IO_LINKED
;
83 _IO_funlockfile ((_IO_FILE
*) fp
);
85 _IO_lock_unlock (list_all_lock
);
86 _IO_cleanup_region_end (0);
94 struct _IO_FILE_plus
*fp
;
96 if ((fp
->file
._flags
& _IO_LINKED
) == 0)
98 fp
->file
._flags
|= _IO_LINKED
;
100 _IO_cleanup_region_start_noarg (flush_cleanup
);
101 _IO_lock_lock (list_all_lock
);
102 run_fp
= (_IO_FILE
*) fp
;
103 _IO_flockfile ((_IO_FILE
*) fp
);
105 fp
->file
._chain
= (_IO_FILE
*) INTUSE(_IO_list_all
);
106 INTUSE(_IO_list_all
) = fp
;
107 ++_IO_list_all_stamp
;
109 _IO_funlockfile ((_IO_FILE
*) fp
);
111 _IO_lock_unlock (list_all_lock
);
112 _IO_cleanup_region_end (0);
118 /* Return minimum _pos markers
119 Assumes the current get area is the main get area. */
120 _IO_ssize_t
_IO_least_marker (_IO_FILE
*fp
, char *end_p
);
123 _IO_least_marker (fp
, end_p
)
127 _IO_ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
128 struct _IO_marker
*mark
;
129 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
130 if (mark
->_pos
< least_so_far
)
131 least_so_far
= mark
->_pos
;
135 /* Switch current get area from backup buffer to (start of) main get area. */
138 _IO_switch_to_main_get_area (fp
)
142 fp
->_flags
&= ~_IO_IN_BACKUP
;
143 /* Swap _IO_read_end and _IO_save_end. */
144 tmp
= fp
->_IO_read_end
;
145 fp
->_IO_read_end
= fp
->_IO_save_end
;
146 fp
->_IO_save_end
= tmp
;
147 /* Swap _IO_read_base and _IO_save_base. */
148 tmp
= fp
->_IO_read_base
;
149 fp
->_IO_read_base
= fp
->_IO_save_base
;
150 fp
->_IO_save_base
= tmp
;
151 /* Set _IO_read_ptr. */
152 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
155 /* Switch current get area from main get area to (end of) backup area. */
158 _IO_switch_to_backup_area (fp
)
162 fp
->_flags
|= _IO_IN_BACKUP
;
163 /* Swap _IO_read_end and _IO_save_end. */
164 tmp
= fp
->_IO_read_end
;
165 fp
->_IO_read_end
= fp
->_IO_save_end
;
166 fp
->_IO_save_end
= tmp
;
167 /* Swap _IO_read_base and _IO_save_base. */
168 tmp
= fp
->_IO_read_base
;
169 fp
->_IO_read_base
= fp
->_IO_save_base
;
170 fp
->_IO_save_base
= tmp
;
171 /* Set _IO_read_ptr. */
172 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
176 _IO_switch_to_get_mode (fp
)
179 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
180 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
182 if (_IO_in_backup (fp
))
183 fp
->_IO_read_base
= fp
->_IO_backup_base
;
186 fp
->_IO_read_base
= fp
->_IO_buf_base
;
187 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
188 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
190 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
192 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
194 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
197 INTDEF(_IO_switch_to_get_mode
)
200 _IO_free_backup_area (fp
)
203 if (_IO_in_backup (fp
))
204 _IO_switch_to_main_get_area (fp
); /* Just in case. */
205 free (fp
->_IO_save_base
);
206 fp
->_IO_save_base
= NULL
;
207 fp
->_IO_save_end
= NULL
;
208 fp
->_IO_backup_base
= NULL
;
210 INTDEF(_IO_free_backup_area
)
214 _IO_switch_to_put_mode (fp
)
217 fp
->_IO_write_base
= fp
->_IO_read_ptr
;
218 fp
->_IO_write_ptr
= fp
->_IO_read_ptr
;
219 /* Following is wrong if line- or un-buffered? */
220 fp
->_IO_write_end
= (fp
->_flags
& _IO_IN_BACKUP
221 ? fp
->_IO_read_end
: fp
->_IO_buf_end
);
223 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
224 fp
->_IO_read_base
= fp
->_IO_read_end
;
226 fp
->_flags
|= _IO_CURRENTLY_PUTTING
;
236 /* This is a single-byte stream. */
239 return _IO_OVERFLOW (f
, ch
);
241 libc_hidden_def (__overflow
)
243 static int save_for_backup (_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
)
328 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
329 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
335 if (_IO_in_put_mode (fp
))
336 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
338 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
339 return *(unsigned char *) fp
->_IO_read_ptr
;
340 if (_IO_in_backup (fp
))
342 _IO_switch_to_main_get_area (fp
);
343 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
344 return *(unsigned char *) fp
->_IO_read_ptr
;
346 if (_IO_have_markers (fp
))
348 if (save_for_backup (fp
, fp
->_IO_read_end
))
351 else if (_IO_have_backup (fp
))
352 INTUSE(_IO_free_backup_area
) (fp
);
353 return _IO_UNDERFLOW (fp
);
355 libc_hidden_def (__underflow
)
361 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
362 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
368 if (_IO_in_put_mode (fp
))
369 if (INTUSE(_IO_switch_to_get_mode
) (fp
) == EOF
)
371 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
372 return *(unsigned char *) fp
->_IO_read_ptr
++;
373 if (_IO_in_backup (fp
))
375 _IO_switch_to_main_get_area (fp
);
376 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
377 return *(unsigned char *) fp
->_IO_read_ptr
++;
379 if (_IO_have_markers (fp
))
381 if (save_for_backup (fp
, fp
->_IO_read_end
))
384 else if (_IO_have_backup (fp
))
385 INTUSE(_IO_free_backup_area
) (fp
);
386 return _IO_UFLOW (fp
);
388 libc_hidden_def (__uflow
)
391 _IO_setb (f
, b
, eb
, a
)
397 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
398 FREE_BUF (f
->_IO_buf_base
, _IO_blen (f
));
402 f
->_flags
&= ~_IO_USER_BUF
;
404 f
->_flags
|= _IO_USER_BUF
;
412 if (fp
->_IO_buf_base
)
414 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
415 if (_IO_DOALLOCATE (fp
) != EOF
)
417 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
419 INTDEF(_IO_doallocbuf
)
422 _IO_default_underflow (fp
)
429 _IO_default_uflow (fp
)
432 int ch
= _IO_UNDERFLOW (fp
);
435 return *(unsigned char *) fp
->_IO_read_ptr
++;
437 INTDEF(_IO_default_uflow
)
440 _IO_default_xsputn (f
, data
, n
)
445 const char *s
= (char *) data
;
451 /* Space available. */
452 if (f
->_IO_write_ptr
< f
->_IO_write_end
)
454 _IO_size_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
460 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
462 memcpy (f
->_IO_write_ptr
, s
, count
);
463 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 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
509 _IO_size_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
515 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
517 memcpy (s
, fp
->_IO_read_ptr
, count
);
520 fp
->_IO_read_ptr
+= count
;
524 char *p
= fp
->_IO_read_ptr
;
528 fp
->_IO_read_ptr
= p
;
532 if (more
== 0 || __underflow (fp
) == EOF
)
537 INTDEF(_IO_default_xsgetn
)
540 /* Seems not to be needed. --drepper */
550 _IO_default_setbuf (fp
, p
, len
)
555 if (_IO_SYNC (fp
) == EOF
)
557 if (p
== NULL
|| len
== 0)
559 fp
->_flags
|= _IO_UNBUFFERED
;
560 INTUSE(_IO_setb
) (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
564 fp
->_flags
&= ~_IO_UNBUFFERED
;
565 INTUSE(_IO_setb
) (fp
, p
, p
+len
, 0);
567 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
568 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
573 _IO_default_seekpos (fp
, pos
, mode
)
578 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
582 _IO_default_doallocate (fp
)
587 ALLOC_BUF (buf
, _IO_BUFSIZ
, EOF
);
588 INTUSE(_IO_setb
) (fp
, buf
, buf
+_IO_BUFSIZ
, 1);
591 INTDEF(_IO_default_doallocate
)
598 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
603 _IO_old_init (fp
, flags
)
607 fp
->_flags
= _IO_MAGIC
|flags
;
609 fp
->_IO_buf_base
= NULL
;
610 fp
->_IO_buf_end
= NULL
;
611 fp
->_IO_read_base
= NULL
;
612 fp
->_IO_read_ptr
= NULL
;
613 fp
->_IO_read_end
= NULL
;
614 fp
->_IO_write_base
= NULL
;
615 fp
->_IO_write_ptr
= NULL
;
616 fp
->_IO_write_end
= NULL
;
617 fp
->_chain
= NULL
; /* Not necessary. */
619 fp
->_IO_save_base
= NULL
;
620 fp
->_IO_backup_base
= NULL
;
621 fp
->_IO_save_end
= NULL
;
625 fp
->_vtable_offset
= 0;
628 if (fp
->_lock
!= NULL
)
629 _IO_lock_init (*fp
->_lock
);
634 _IO_no_init (fp
, flags
, orientation
, wd
, jmp
)
638 struct _IO_wide_data
*wd
;
639 const struct _IO_jump_t
*jmp
;
641 _IO_old_init (fp
, flags
);
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
;
662 fp
->_freeres_list
= NULL
;
666 _IO_default_sync (fp
)
672 /* The way the C++ classes are mapped into the C functions in the
673 current implementation, this function can get called twice! */
676 _IO_default_finish (fp
, dummy
)
680 struct _IO_marker
*mark
;
681 if (fp
->_IO_buf_base
&& !(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 || (_IO_vtable_offset (fp
) == 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
)
921 /* The following is a bit tricky. In general, we want to unbuffer the
922 streams so that all output which follows is seen. If we are not
923 looking for memory leaks it does not make much sense to free the
924 actual buffer because this will happen anyway once the program
925 terminated. If we do want to look for memory leaks we have to free
926 the buffers. Whether something is freed is determined by the
927 function sin the libc_freeres section. Those are called as part of
928 the atexit routine, just like _IO_cleanup. The problem is we do
929 not know whether the freeres code is called first or _IO_cleanup.
930 if the former is the case, we set the DEALLOC_BUFFER variable to
931 true and _IO_unbuffer_write will take care of the rest. If
932 _IO_unbuffer_write is called first we add the streams to a list
933 which the freeres function later can walk through. */
934 static void _IO_unbuffer_write (void);
936 static bool dealloc_buffers
;
937 static _IO_FILE
*freeres_list
;
940 _IO_unbuffer_write (void)
943 for (fp
= (_IO_FILE
*) INTUSE(_IO_list_all
); fp
; fp
= fp
->_chain
)
945 if (! (fp
->_flags
& _IO_UNBUFFERED
)
946 && (! (fp
->_flags
& _IO_NO_WRITES
)
947 || (fp
->_flags
& _IO_IS_APPENDING
))
948 /* Iff stream is un-orientated, it wasn't used. */
953 for (cnt
= 0; cnt
< MAXTRIES
; ++cnt
)
954 if (_IO_lock_trylock (*fp
->_lock
) == 0)
957 /* Give the other thread time to finish up its use of the
961 if (! dealloc_buffers
&& !(fp
->_flags
& _IO_USER_BUF
))
963 fp
->_flags
|= _IO_USER_BUF
;
965 fp
->_freeres_list
= freeres_list
;
967 fp
->_freeres_buf
= fp
->_IO_buf_base
;
968 fp
->_freeres_size
= _IO_blen (fp
);
971 _IO_SETBUF (fp
, NULL
, 0);
974 _IO_lock_unlock (*fp
->_lock
);
977 /* Make sure that never again the wide char functions can be
984 libc_freeres_fn (buffer_free
)
986 dealloc_buffers
= true;
988 while (freeres_list
!= NULL
)
990 FREE_BUF (freeres_list
->_freeres_buf
, freeres_list
->_freeres_size
);
992 freeres_list
= freeres_list
->_freeres_list
;
1000 /* We do *not* want locking. Some threads might use streams but
1001 that is their problem, we flush them underneath them. */
1002 int result
= _IO_flush_all_lockp (0);
1004 /* We currently don't have a reliable mechanism for making sure that
1005 C++ static destructors are executed in the correct order.
1006 So it is possible that other static destructors might want to
1007 write to cout - and they're supposed to be able to do so.
1009 The following will make the standard streambufs be unbuffered,
1010 which forces any output from late destructors to be written out. */
1011 _IO_unbuffer_write ();
1018 _IO_init_marker (marker
, fp
)
1019 struct _IO_marker
*marker
;
1023 if (_IO_in_put_mode (fp
))
1024 INTUSE(_IO_switch_to_get_mode
) (fp
);
1025 if (_IO_in_backup (fp
))
1026 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
1028 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
1030 /* Should perhaps sort the chain? */
1031 marker
->_next
= fp
->_markers
;
1032 fp
->_markers
= marker
;
1036 _IO_remove_marker (marker
)
1037 struct _IO_marker
*marker
;
1039 /* Unlink from sb's chain. */
1040 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
1041 for (; ; ptr
= &(*ptr
)->_next
)
1045 else if (*ptr
== marker
)
1047 *ptr
= marker
->_next
;
1052 if _sbuf has a backup area that is no longer needed
, should we
delete
1053 it now
, or wait until the next underflow
?
1057 #define BAD_DELTA EOF
1060 _IO_marker_difference (mark1
, mark2
)
1061 struct _IO_marker
*mark1
;
1062 struct _IO_marker
*mark2
;
1064 return mark1
->_pos
- mark2
->_pos
;
1067 /* Return difference between MARK and current position of MARK's stream. */
1069 _IO_marker_delta (mark
)
1070 struct _IO_marker
*mark
;
1073 if (mark
->_sbuf
== NULL
)
1075 if (_IO_in_backup (mark
->_sbuf
))
1076 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
1078 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
1079 return mark
->_pos
- cur_pos
;
1083 _IO_seekmark (fp
, mark
, delta
)
1085 struct _IO_marker
*mark
;
1088 if (mark
->_sbuf
!= fp
)
1090 if (mark
->_pos
>= 0)
1092 if (_IO_in_backup (fp
))
1093 _IO_switch_to_main_get_area (fp
);
1094 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
1098 if (!_IO_in_backup (fp
))
1099 _IO_switch_to_backup_area (fp
);
1100 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
1106 _IO_unsave_markers (fp
)
1109 struct _IO_marker
*mark
= fp
->_markers
;
1113 streampos offset
= seekoff (0, ios::cur
, ios::in
);
1116 offset
+= eGptr () - Gbase ();
1117 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1118 mark
->set_streampos (mark
->_pos
+ offset
);
1122 for ( ; mark
!= NULL
; mark
= mark
->_next
)
1123 mark
->set_streampos (EOF
);
1129 if (_IO_have_backup (fp
))
1130 INTUSE(_IO_free_backup_area
) (fp
);
1132 INTDEF(_IO_unsave_markers
)
1135 /* Seems not to be needed. --drepper */
1137 _IO_nobackup_pbackfail (fp
, c
)
1141 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
1143 if (c
!= EOF
&& *fp
->_IO_read_ptr
!= c
)
1144 *fp
->_IO_read_ptr
= c
;
1145 return (unsigned char) c
;
1150 _IO_default_pbackfail (fp
, c
)
1154 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
1155 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
1159 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1160 if (!_IO_in_backup (fp
))
1162 /* We need to keep the invariant that the main get area
1163 logically follows the backup area. */
1164 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
1166 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
1169 else if (!_IO_have_backup (fp
))
1171 /* No backup buffer: allocate one. */
1172 /* Use nshort buffer, if unused? (probably not) FIXME */
1173 int backup_size
= 128;
1174 char *bbuf
= (char *) malloc (backup_size
);
1177 fp
->_IO_save_base
= bbuf
;
1178 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
1179 fp
->_IO_backup_base
= fp
->_IO_save_end
;
1181 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
1182 _IO_switch_to_backup_area (fp
);
1184 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
1186 /* Increase size of existing backup buffer. */
1187 _IO_size_t new_size
;
1188 _IO_size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
1190 new_size
= 2 * old_size
;
1191 new_buf
= (char *) malloc (new_size
);
1192 if (new_buf
== NULL
)
1194 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
1196 free (fp
->_IO_read_base
);
1197 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
1198 new_buf
+ new_size
);
1199 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1202 *--fp
->_IO_read_ptr
= c
;
1204 return (unsigned char) c
;
1206 INTDEF(_IO_default_pbackfail
)
1209 _IO_default_seek (fp
, offset
, dir
)
1218 _IO_default_stat (fp
, st
)
1226 _IO_default_read (fp
, data
, n
)
1235 _IO_default_write (fp
, data
, n
)
1244 _IO_default_showmanyc (fp
)
1251 _IO_default_imbue (fp
, locale
)
1260 return (_IO_ITER
) INTUSE(_IO_list_all
);
1262 libc_hidden_def (_IO_iter_begin
)
1269 libc_hidden_def (_IO_iter_end
)
1275 return iter
->_chain
;
1277 libc_hidden_def (_IO_iter_next
)
1285 libc_hidden_def (_IO_iter_file
)
1290 #ifdef _IO_MTSAFE_IO
1291 _IO_lock_lock (list_all_lock
);
1294 libc_hidden_def (_IO_list_lock
)
1299 #ifdef _IO_MTSAFE_IO
1300 _IO_lock_unlock (list_all_lock
);
1303 libc_hidden_def (_IO_list_unlock
)
1306 _IO_list_resetlock()
1308 #ifdef _IO_MTSAFE_IO
1309 _IO_lock_init (list_all_lock
);
1312 libc_hidden_def (_IO_list_resetlock
)
1317 #define IO_CLEANUP ;
1325 ~__io_defs() { _IO_cleanup (); }
1327 __io_defs io_defs__
;
1332 #ifdef text_set_element
1333 text_set_element(__libc_atexit
, _IO_cleanup
);