1 /* Copyright (C) 1993-2024 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, see
16 <https://www.gnu.org/licenses/>.
18 As a special exception, if you link the code in this file with
19 files compiled with a GNU compiler to produce an executable,
20 that does not cause the resulting executable to be covered by
21 the GNU Lesser General Public License. This exception does not
22 however invalidate any other reasons why the executable file
23 might be covered by the GNU Lesser General Public License.
24 This exception applies to code released by its copyright holders
25 in files containing the exception. */
27 /* Generic or default I/O operations. */
36 static _IO_lock_t list_all_lock
= _IO_lock_initializer
;
43 flush_cleanup (void *not_used
)
46 _IO_funlockfile (run_fp
);
47 _IO_lock_unlock (list_all_lock
);
52 _IO_un_link (struct _IO_FILE_plus
*fp
)
54 if (fp
->file
._flags
& _IO_LINKED
)
58 _IO_cleanup_region_start_noarg (flush_cleanup
);
59 _IO_lock_lock (list_all_lock
);
61 _IO_flockfile ((FILE *) fp
);
63 if (_IO_list_all
== NULL
)
65 else if (fp
== _IO_list_all
)
66 _IO_list_all
= (struct _IO_FILE_plus
*) _IO_list_all
->file
._chain
;
68 for (f
= &_IO_list_all
->file
._chain
; *f
; f
= &(*f
)->_chain
)
69 if (*f
== (FILE *) fp
)
74 fp
->file
._flags
&= ~_IO_LINKED
;
76 _IO_funlockfile ((FILE *) fp
);
78 _IO_lock_unlock (list_all_lock
);
79 _IO_cleanup_region_end (0);
83 libc_hidden_def (_IO_un_link
)
86 _IO_link_in (struct _IO_FILE_plus
*fp
)
88 if ((fp
->file
._flags
& _IO_LINKED
) == 0)
90 fp
->file
._flags
|= _IO_LINKED
;
92 _IO_cleanup_region_start_noarg (flush_cleanup
);
93 _IO_lock_lock (list_all_lock
);
95 _IO_flockfile ((FILE *) fp
);
97 fp
->file
._chain
= (FILE *) _IO_list_all
;
100 _IO_funlockfile ((FILE *) fp
);
102 _IO_lock_unlock (list_all_lock
);
103 _IO_cleanup_region_end (0);
107 libc_hidden_def (_IO_link_in
)
109 /* Return minimum _pos markers
110 Assumes the current get area is the main get area. */
111 ssize_t
_IO_least_marker (FILE *fp
, char *end_p
);
114 _IO_least_marker (FILE *fp
, char *end_p
)
116 ssize_t least_so_far
= end_p
- fp
->_IO_read_base
;
117 struct _IO_marker
*mark
;
118 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
119 if (mark
->_pos
< least_so_far
)
120 least_so_far
= mark
->_pos
;
124 /* Switch current get area from backup buffer to (start of) main get area. */
127 _IO_switch_to_main_get_area (FILE *fp
)
130 fp
->_flags
&= ~_IO_IN_BACKUP
;
131 /* Swap _IO_read_end and _IO_save_end. */
132 tmp
= fp
->_IO_read_end
;
133 fp
->_IO_read_end
= fp
->_IO_save_end
;
134 fp
->_IO_save_end
= tmp
;
135 /* Swap _IO_read_base and _IO_save_base. */
136 tmp
= fp
->_IO_read_base
;
137 fp
->_IO_read_base
= fp
->_IO_save_base
;
138 fp
->_IO_save_base
= tmp
;
139 /* Set _IO_read_ptr. */
140 fp
->_IO_read_ptr
= fp
->_IO_read_base
;
143 /* Switch current get area from main get area to (end of) backup area. */
146 _IO_switch_to_backup_area (FILE *fp
)
149 fp
->_flags
|= _IO_IN_BACKUP
;
150 /* Swap _IO_read_end and _IO_save_end. */
151 tmp
= fp
->_IO_read_end
;
152 fp
->_IO_read_end
= fp
->_IO_save_end
;
153 fp
->_IO_save_end
= tmp
;
154 /* Swap _IO_read_base and _IO_save_base. */
155 tmp
= fp
->_IO_read_base
;
156 fp
->_IO_read_base
= fp
->_IO_save_base
;
157 fp
->_IO_save_base
= tmp
;
158 /* Set _IO_read_ptr. */
159 fp
->_IO_read_ptr
= fp
->_IO_read_end
;
163 _IO_switch_to_get_mode (FILE *fp
)
165 if (fp
->_IO_write_ptr
> fp
->_IO_write_base
)
166 if (_IO_OVERFLOW (fp
, EOF
) == EOF
)
168 if (_IO_in_backup (fp
))
169 fp
->_IO_read_base
= fp
->_IO_backup_base
;
172 fp
->_IO_read_base
= fp
->_IO_buf_base
;
173 if (fp
->_IO_write_ptr
> fp
->_IO_read_end
)
174 fp
->_IO_read_end
= fp
->_IO_write_ptr
;
176 fp
->_IO_read_ptr
= fp
->_IO_write_ptr
;
178 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= fp
->_IO_read_ptr
;
180 fp
->_flags
&= ~_IO_CURRENTLY_PUTTING
;
183 libc_hidden_def (_IO_switch_to_get_mode
)
186 _IO_free_backup_area (FILE *fp
)
188 if (_IO_in_backup (fp
))
189 _IO_switch_to_main_get_area (fp
); /* Just in case. */
190 free (fp
->_IO_save_base
);
191 fp
->_IO_save_base
= NULL
;
192 fp
->_IO_save_end
= NULL
;
193 fp
->_IO_backup_base
= NULL
;
195 libc_hidden_def (_IO_free_backup_area
)
198 __overflow (FILE *f
, int ch
)
200 /* This is a single-byte stream. */
203 return _IO_OVERFLOW (f
, ch
);
205 libc_hidden_def (__overflow
)
208 save_for_backup (FILE *fp
, char *end_p
)
210 /* Append [_IO_read_base..end_p] to backup area. */
211 ssize_t least_mark
= _IO_least_marker (fp
, end_p
);
212 /* needed_size is how much space we need in the backup area. */
213 size_t needed_size
= (end_p
- fp
->_IO_read_base
) - least_mark
;
214 /* FIXME: Dubious arithmetic if pointers are NULL */
215 size_t current_Bsize
= fp
->_IO_save_end
- fp
->_IO_save_base
;
216 size_t avail
; /* Extra space available for future expansion. */
218 struct _IO_marker
*mark
;
219 if (needed_size
> current_Bsize
)
223 new_buffer
= (char *) malloc (avail
+ needed_size
);
224 if (new_buffer
== NULL
)
225 return EOF
; /* FIXME */
228 __mempcpy (__mempcpy (new_buffer
+ avail
,
229 fp
->_IO_save_end
+ least_mark
,
232 end_p
- fp
->_IO_read_base
);
235 memcpy (new_buffer
+ avail
,
236 fp
->_IO_read_base
+ least_mark
,
238 free (fp
->_IO_save_base
);
239 fp
->_IO_save_base
= new_buffer
;
240 fp
->_IO_save_end
= new_buffer
+ avail
+ needed_size
;
244 avail
= current_Bsize
- needed_size
;
247 memmove (fp
->_IO_save_base
+ avail
,
248 fp
->_IO_save_end
+ least_mark
,
250 memcpy (fp
->_IO_save_base
+ avail
- least_mark
,
252 end_p
- fp
->_IO_read_base
);
254 else if (needed_size
> 0)
255 memcpy (fp
->_IO_save_base
+ avail
,
256 fp
->_IO_read_base
+ least_mark
,
259 fp
->_IO_backup_base
= fp
->_IO_save_base
+ avail
;
260 /* Adjust all the streammarkers. */
261 delta
= end_p
- fp
->_IO_read_base
;
262 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
268 __underflow (FILE *fp
)
270 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
275 if (_IO_in_put_mode (fp
))
276 if (_IO_switch_to_get_mode (fp
) == EOF
)
278 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
279 return *(unsigned char *) fp
->_IO_read_ptr
;
280 if (_IO_in_backup (fp
))
282 _IO_switch_to_main_get_area (fp
);
283 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
284 return *(unsigned char *) fp
->_IO_read_ptr
;
286 if (_IO_have_markers (fp
))
288 if (save_for_backup (fp
, fp
->_IO_read_end
))
291 else if (_IO_have_backup (fp
))
292 _IO_free_backup_area (fp
);
293 return _IO_UNDERFLOW (fp
);
295 libc_hidden_def (__underflow
)
300 if (_IO_vtable_offset (fp
) == 0 && _IO_fwide (fp
, -1) != -1)
305 if (_IO_in_put_mode (fp
))
306 if (_IO_switch_to_get_mode (fp
) == EOF
)
308 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
309 return *(unsigned char *) fp
->_IO_read_ptr
++;
310 if (_IO_in_backup (fp
))
312 _IO_switch_to_main_get_area (fp
);
313 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
314 return *(unsigned char *) fp
->_IO_read_ptr
++;
316 if (_IO_have_markers (fp
))
318 if (save_for_backup (fp
, fp
->_IO_read_end
))
321 else if (_IO_have_backup (fp
))
322 _IO_free_backup_area (fp
);
323 return _IO_UFLOW (fp
);
325 libc_hidden_def (__uflow
)
328 _IO_setb (FILE *f
, char *b
, char *eb
, int a
)
330 if (f
->_IO_buf_base
&& !(f
->_flags
& _IO_USER_BUF
))
331 free (f
->_IO_buf_base
);
335 f
->_flags
&= ~_IO_USER_BUF
;
337 f
->_flags
|= _IO_USER_BUF
;
339 libc_hidden_def (_IO_setb
)
342 _IO_doallocbuf (FILE *fp
)
344 if (fp
->_IO_buf_base
)
346 if (!(fp
->_flags
& _IO_UNBUFFERED
) || fp
->_mode
> 0)
347 if (_IO_DOALLOCATE (fp
) != EOF
)
349 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
351 libc_hidden_def (_IO_doallocbuf
)
354 _IO_default_underflow (FILE *fp
)
360 _IO_default_uflow (FILE *fp
)
362 int ch
= _IO_UNDERFLOW (fp
);
365 return *(unsigned char *) fp
->_IO_read_ptr
++;
367 libc_hidden_def (_IO_default_uflow
)
370 _IO_default_xsputn (FILE *f
, const void *data
, size_t n
)
372 const char *s
= (char *) data
;
378 /* Space available. */
379 if (f
->_IO_write_ptr
< f
->_IO_write_end
)
381 size_t count
= f
->_IO_write_end
- f
->_IO_write_ptr
;
386 f
->_IO_write_ptr
= __mempcpy (f
->_IO_write_ptr
, s
, count
);
391 char *p
= f
->_IO_write_ptr
;
393 for (i
= count
; --i
>= 0; )
395 f
->_IO_write_ptr
= p
;
399 if (more
== 0 || _IO_OVERFLOW (f
, (unsigned char) *s
++) == EOF
)
405 libc_hidden_def (_IO_default_xsputn
)
408 _IO_sgetn (FILE *fp
, void *data
, size_t n
)
410 /* FIXME handle putback buffer here! */
411 return _IO_XSGETN (fp
, data
, n
);
413 libc_hidden_def (_IO_sgetn
)
416 _IO_default_xsgetn (FILE *fp
, void *data
, size_t n
)
419 char *s
= (char*) data
;
422 /* Data available. */
423 if (fp
->_IO_read_ptr
< fp
->_IO_read_end
)
425 size_t count
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
430 s
= __mempcpy (s
, fp
->_IO_read_ptr
, count
);
431 fp
->_IO_read_ptr
+= count
;
435 char *p
= fp
->_IO_read_ptr
;
439 fp
->_IO_read_ptr
= p
;
443 if (more
== 0 || __underflow (fp
) == EOF
)
448 libc_hidden_def (_IO_default_xsgetn
)
451 _IO_default_setbuf (FILE *fp
, char *p
, ssize_t len
)
453 if (_IO_SYNC (fp
) == EOF
)
455 if (p
== NULL
|| len
== 0)
457 fp
->_flags
|= _IO_UNBUFFERED
;
458 _IO_setb (fp
, fp
->_shortbuf
, fp
->_shortbuf
+1, 0);
462 fp
->_flags
&= ~_IO_UNBUFFERED
;
463 _IO_setb (fp
, p
, p
+len
, 0);
465 fp
->_IO_write_base
= fp
->_IO_write_ptr
= fp
->_IO_write_end
= 0;
466 fp
->_IO_read_base
= fp
->_IO_read_ptr
= fp
->_IO_read_end
= 0;
471 _IO_default_seekpos (FILE *fp
, off64_t pos
, int mode
)
473 return _IO_SEEKOFF (fp
, pos
, 0, mode
);
477 _IO_default_doallocate (FILE *fp
)
481 buf
= malloc(BUFSIZ
);
482 if (__glibc_unlikely (buf
== NULL
))
485 _IO_setb (fp
, buf
, buf
+BUFSIZ
, 1);
488 libc_hidden_def (_IO_default_doallocate
)
491 _IO_init_internal (FILE *fp
, int flags
)
493 _IO_no_init (fp
, flags
, -1, NULL
, NULL
);
497 _IO_init (FILE *fp
, int flags
)
499 IO_set_accept_foreign_vtables (&_IO_vtable_check
);
500 _IO_init_internal (fp
, flags
);
503 static int stdio_needs_locking
;
505 /* In a single-threaded process most stdio locks can be omitted. After
506 _IO_enable_locks is called, locks are not optimized away any more.
507 It must be first called while the process is still single-threaded.
509 This lock optimization can be disabled on a per-file basis by setting
510 _IO_FLAGS2_NEED_LOCK, because a file can have user-defined callbacks
511 or can be locked with flockfile and then a thread may be created
512 between a lock and unlock, so omitting the lock is not valid.
514 Here we have to make sure that the flag is set on all existing files
515 and files created later. */
517 _IO_enable_locks (void)
521 if (stdio_needs_locking
)
523 stdio_needs_locking
= 1;
524 for (i
= _IO_iter_begin (); i
!= _IO_iter_end (); i
= _IO_iter_next (i
))
525 _IO_iter_file (i
)->_flags2
|= _IO_FLAGS2_NEED_LOCK
;
527 libc_hidden_def (_IO_enable_locks
)
530 _IO_old_init (FILE *fp
, int flags
)
532 fp
->_flags
= _IO_MAGIC
|flags
;
534 if (stdio_needs_locking
)
535 fp
->_flags2
|= _IO_FLAGS2_NEED_LOCK
;
536 fp
->_IO_buf_base
= NULL
;
537 fp
->_IO_buf_end
= NULL
;
538 fp
->_IO_read_base
= NULL
;
539 fp
->_IO_read_ptr
= NULL
;
540 fp
->_IO_read_end
= NULL
;
541 fp
->_IO_write_base
= NULL
;
542 fp
->_IO_write_ptr
= NULL
;
543 fp
->_IO_write_end
= NULL
;
544 fp
->_chain
= NULL
; /* Not necessary. */
546 fp
->_IO_save_base
= NULL
;
547 fp
->_IO_backup_base
= NULL
;
548 fp
->_IO_save_end
= NULL
;
552 fp
->_vtable_offset
= 0;
555 if (fp
->_lock
!= NULL
)
556 _IO_lock_init (*fp
->_lock
);
561 _IO_no_init (FILE *fp
, int flags
, int orientation
,
562 struct _IO_wide_data
*wd
, const struct _IO_jump_t
*jmp
)
564 _IO_old_init (fp
, flags
);
565 fp
->_mode
= orientation
;
566 if (orientation
>= 0)
569 fp
->_wide_data
->_IO_buf_base
= NULL
;
570 fp
->_wide_data
->_IO_buf_end
= NULL
;
571 fp
->_wide_data
->_IO_read_base
= NULL
;
572 fp
->_wide_data
->_IO_read_ptr
= NULL
;
573 fp
->_wide_data
->_IO_read_end
= NULL
;
574 fp
->_wide_data
->_IO_write_base
= NULL
;
575 fp
->_wide_data
->_IO_write_ptr
= NULL
;
576 fp
->_wide_data
->_IO_write_end
= NULL
;
577 fp
->_wide_data
->_IO_save_base
= NULL
;
578 fp
->_wide_data
->_IO_backup_base
= NULL
;
579 fp
->_wide_data
->_IO_save_end
= NULL
;
581 fp
->_wide_data
->_wide_vtable
= jmp
;
584 /* Cause predictable crash when a wide function is called on a byte
586 fp
->_wide_data
= (struct _IO_wide_data
*) -1L;
587 fp
->_freeres_list
= NULL
;
591 _IO_default_sync (FILE *fp
)
596 /* The way the C++ classes are mapped into the C functions in the
597 current implementation, this function can get called twice! */
600 _IO_default_finish (FILE *fp
, int dummy
)
602 struct _IO_marker
*mark
;
603 if (fp
->_IO_buf_base
&& !(fp
->_flags
& _IO_USER_BUF
))
605 free (fp
->_IO_buf_base
);
606 fp
->_IO_buf_base
= fp
->_IO_buf_end
= NULL
;
609 for (mark
= fp
->_markers
; mark
!= NULL
; mark
= mark
->_next
)
612 if (fp
->_IO_save_base
)
614 free (fp
->_IO_save_base
);
615 fp
->_IO_save_base
= NULL
;
618 _IO_un_link ((struct _IO_FILE_plus
*) fp
);
621 if (fp
->_lock
!= NULL
)
622 _IO_lock_fini (*fp
->_lock
);
625 libc_hidden_def (_IO_default_finish
)
628 _IO_default_seekoff (FILE *fp
, off64_t offset
, int dir
, int mode
)
634 _IO_sputbackc (FILE *fp
, int c
)
638 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
639 && (unsigned char)fp
->_IO_read_ptr
[-1] == (unsigned char)c
)
642 result
= (unsigned char) c
;
645 result
= _IO_PBACKFAIL (fp
, c
);
648 fp
->_flags
&= ~_IO_EOF_SEEN
;
652 libc_hidden_def (_IO_sputbackc
)
655 _IO_sungetc (FILE *fp
)
659 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
)
662 result
= (unsigned char) *fp
->_IO_read_ptr
;
665 result
= _IO_PBACKFAIL (fp
, EOF
);
668 fp
->_flags
&= ~_IO_EOF_SEEN
;
674 _IO_adjust_column (unsigned start
, const char *line
, int count
)
676 const char *ptr
= line
+ count
;
679 return line
+ count
- ptr
- 1;
680 return start
+ count
;
682 libc_hidden_def (_IO_adjust_column
)
691 _IO_cleanup_region_start_noarg (flush_cleanup
);
692 _IO_lock_lock (list_all_lock
);
695 for (fp
= (FILE *) _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
700 if (((fp
->_mode
<= 0 && fp
->_IO_write_ptr
> fp
->_IO_write_base
)
701 || (_IO_vtable_offset (fp
) == 0
702 && fp
->_mode
> 0 && (fp
->_wide_data
->_IO_write_ptr
703 > fp
->_wide_data
->_IO_write_base
))
705 && _IO_OVERFLOW (fp
, EOF
) == EOF
)
708 _IO_funlockfile (fp
);
713 _IO_lock_unlock (list_all_lock
);
714 _IO_cleanup_region_end (0);
719 libc_hidden_def (_IO_flush_all
)
722 _IO_flush_all_linebuffered (void)
727 _IO_cleanup_region_start_noarg (flush_cleanup
);
728 _IO_lock_lock (list_all_lock
);
731 for (fp
= (FILE *) _IO_list_all
; fp
!= NULL
; fp
= fp
->_chain
)
736 if ((fp
->_flags
& _IO_NO_WRITES
) == 0 && fp
->_flags
& _IO_LINE_BUF
)
737 _IO_OVERFLOW (fp
, EOF
);
739 _IO_funlockfile (fp
);
744 _IO_lock_unlock (list_all_lock
);
745 _IO_cleanup_region_end (0);
748 libc_hidden_def (_IO_flush_all_linebuffered
)
749 weak_alias (_IO_flush_all_linebuffered
, _flushlbf
)
752 /* The following is a bit tricky. In general, we want to unbuffer the
753 streams so that all output which follows is seen. If we are not
754 looking for memory leaks it does not make much sense to free the
755 actual buffer because this will happen anyway once the program
756 terminated. If we do want to look for memory leaks we have to free
757 the buffers. Whether something is freed is determined by the
758 function called by __libc_freeres (those are not called as part of
759 the atexit routine, different from _IO_cleanup). The problem is we do
760 not know whether the freeres code is called first or _IO_cleanup.
761 if the former is the case, we set the DEALLOC_BUFFER variable to
762 true and _IO_unbuffer_all will take care of the rest. If
763 _IO_unbuffer_all is called first we add the streams to a list
764 which the freeres function later can walk through. */
765 static void _IO_unbuffer_all (void);
767 static bool dealloc_buffers
;
768 static FILE *freeres_list
;
771 _IO_unbuffer_all (void)
776 _IO_cleanup_region_start_noarg (flush_cleanup
);
777 _IO_lock_lock (list_all_lock
);
780 for (fp
= (FILE *) _IO_list_all
; fp
; fp
= fp
->_chain
)
787 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
788 if (__glibc_unlikely (_IO_vtable_offset (fp
) != 0))
792 if (! (fp
->_flags
& _IO_UNBUFFERED
)
793 /* Iff stream is un-orientated, it wasn't used. */
794 && (legacy
|| fp
->_mode
!= 0))
796 if (! legacy
&& ! dealloc_buffers
&& !(fp
->_flags
& _IO_USER_BUF
))
798 fp
->_flags
|= _IO_USER_BUF
;
800 fp
->_freeres_list
= freeres_list
;
802 fp
->_freeres_buf
= fp
->_IO_buf_base
;
805 _IO_SETBUF (fp
, NULL
, 0);
807 if (! legacy
&& fp
->_mode
> 0)
808 _IO_wsetb (fp
, NULL
, NULL
, 0);
811 /* Make sure that never again the wide char functions can be
816 _IO_funlockfile (fp
);
821 _IO_lock_unlock (list_all_lock
);
822 _IO_cleanup_region_end (0);
827 __libio_freemem (void)
829 dealloc_buffers
= true;
831 while (freeres_list
!= NULL
)
833 free (freeres_list
->_freeres_buf
);
835 freeres_list
= freeres_list
->_freeres_list
;
843 int result
= _IO_flush_all ();
845 /* We currently don't have a reliable mechanism for making sure that
846 C++ static destructors are executed in the correct order.
847 So it is possible that other static destructors might want to
848 write to cout - and they're supposed to be able to do so.
850 The following will make the standard streambufs be unbuffered,
851 which forces any output from late destructors to be written out. */
859 _IO_init_marker (struct _IO_marker
*marker
, FILE *fp
)
862 if (_IO_in_put_mode (fp
))
863 _IO_switch_to_get_mode (fp
);
864 if (_IO_in_backup (fp
))
865 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_end
;
867 marker
->_pos
= fp
->_IO_read_ptr
- fp
->_IO_read_base
;
869 /* Should perhaps sort the chain? */
870 marker
->_next
= fp
->_markers
;
871 fp
->_markers
= marker
;
875 _IO_remove_marker (struct _IO_marker
*marker
)
877 /* Unlink from sb's chain. */
878 struct _IO_marker
**ptr
= &marker
->_sbuf
->_markers
;
879 for (; ; ptr
= &(*ptr
)->_next
)
883 else if (*ptr
== marker
)
885 *ptr
= marker
->_next
;
889 /* FIXME: if _sbuf has a backup area that is no longer needed,
890 should we delete it now, or wait until the next underflow? */
893 #define BAD_DELTA EOF
896 _IO_marker_difference (struct _IO_marker
*mark1
, struct _IO_marker
*mark2
)
898 return mark1
->_pos
- mark2
->_pos
;
901 /* Return difference between MARK and current position of MARK's stream. */
903 _IO_marker_delta (struct _IO_marker
*mark
)
906 if (mark
->_sbuf
== NULL
)
908 if (_IO_in_backup (mark
->_sbuf
))
909 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_end
;
911 cur_pos
= mark
->_sbuf
->_IO_read_ptr
- mark
->_sbuf
->_IO_read_base
;
912 return mark
->_pos
- cur_pos
;
916 _IO_seekmark (FILE *fp
, struct _IO_marker
*mark
, int delta
)
918 if (mark
->_sbuf
!= fp
)
922 if (_IO_in_backup (fp
))
923 _IO_switch_to_main_get_area (fp
);
924 fp
->_IO_read_ptr
= fp
->_IO_read_base
+ mark
->_pos
;
928 if (!_IO_in_backup (fp
))
929 _IO_switch_to_backup_area (fp
);
930 fp
->_IO_read_ptr
= fp
->_IO_read_end
+ mark
->_pos
;
936 _IO_unsave_markers (FILE *fp
)
938 struct _IO_marker
*mark
= fp
->_markers
;
944 if (_IO_have_backup (fp
))
945 _IO_free_backup_area (fp
);
947 libc_hidden_def (_IO_unsave_markers
)
950 _IO_default_pbackfail (FILE *fp
, int c
)
952 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& !_IO_in_backup (fp
)
953 && (unsigned char) fp
->_IO_read_ptr
[-1] == c
)
957 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
958 if (!_IO_in_backup (fp
))
960 /* We need to keep the invariant that the main get area
961 logically follows the backup area. */
962 if (fp
->_IO_read_ptr
> fp
->_IO_read_base
&& _IO_have_backup (fp
))
964 if (save_for_backup (fp
, fp
->_IO_read_ptr
))
967 else if (!_IO_have_backup (fp
))
969 /* No backup buffer: allocate one. */
970 /* Use nshort buffer, if unused? (probably not) FIXME */
971 int backup_size
= 128;
972 char *bbuf
= (char *) malloc (backup_size
);
975 fp
->_IO_save_base
= bbuf
;
976 fp
->_IO_save_end
= fp
->_IO_save_base
+ backup_size
;
977 fp
->_IO_backup_base
= fp
->_IO_save_end
;
979 fp
->_IO_read_base
= fp
->_IO_read_ptr
;
980 _IO_switch_to_backup_area (fp
);
982 else if (fp
->_IO_read_ptr
<= fp
->_IO_read_base
)
984 /* Increase size of existing backup buffer. */
986 size_t old_size
= fp
->_IO_read_end
- fp
->_IO_read_base
;
988 new_size
= 2 * old_size
;
989 new_buf
= (char *) malloc (new_size
);
992 memcpy (new_buf
+ (new_size
- old_size
), fp
->_IO_read_base
,
994 free (fp
->_IO_read_base
);
995 _IO_setg (fp
, new_buf
, new_buf
+ (new_size
- old_size
),
997 fp
->_IO_backup_base
= fp
->_IO_read_ptr
;
1000 *--fp
->_IO_read_ptr
= c
;
1002 return (unsigned char) c
;
1004 libc_hidden_def (_IO_default_pbackfail
)
1007 _IO_default_seek (FILE *fp
, off64_t offset
, int dir
)
1013 _IO_default_stat (FILE *fp
, void *st
)
1019 _IO_default_read (FILE *fp
, void *data
, ssize_t n
)
1025 _IO_default_write (FILE *fp
, const void *data
, ssize_t n
)
1031 _IO_default_showmanyc (FILE *fp
)
1037 _IO_default_imbue (FILE *fp
, void *locale
)
1042 _IO_iter_begin (void)
1044 return (_IO_ITER
) _IO_list_all
;
1046 libc_hidden_def (_IO_iter_begin
)
1053 libc_hidden_def (_IO_iter_end
)
1056 _IO_iter_next (_IO_ITER iter
)
1058 return iter
->_chain
;
1060 libc_hidden_def (_IO_iter_next
)
1063 _IO_iter_file (_IO_ITER iter
)
1067 libc_hidden_def (_IO_iter_file
)
1070 _IO_list_lock (void)
1072 #ifdef _IO_MTSAFE_IO
1073 _IO_lock_lock (list_all_lock
);
1076 libc_hidden_def (_IO_list_lock
)
1079 _IO_list_unlock (void)
1081 #ifdef _IO_MTSAFE_IO
1082 _IO_lock_unlock (list_all_lock
);
1085 libc_hidden_def (_IO_list_unlock
)
1088 _IO_list_resetlock (void)
1090 #ifdef _IO_MTSAFE_IO
1091 _IO_lock_init (list_all_lock
);
1094 libc_hidden_def (_IO_list_resetlock
)