hurd: Initialize __libc_stack_end for hidden support
[glibc.git] / libio / genops.c
blob32fec76648e2e66c6e4ac9480b11ce3c526d08a4
1 /* Copyright (C) 1993-2015 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 <http://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. */
29 #include "libioP.h"
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdbool.h>
33 #ifdef _LIBC
34 #include <sched.h>
35 #endif
37 #ifdef _IO_MTSAFE_IO
38 static _IO_lock_t list_all_lock = _IO_lock_initializer;
39 #endif
41 /* Used to signal modifications to the list of FILE decriptors. */
42 static int _IO_list_all_stamp;
45 static _IO_FILE *run_fp;
47 #ifdef _IO_MTSAFE_IO
48 static void
49 flush_cleanup (void *not_used)
51 if (run_fp != NULL)
52 _IO_funlockfile (run_fp);
53 _IO_lock_unlock (list_all_lock);
55 #endif
57 void
58 _IO_un_link (struct _IO_FILE_plus *fp)
60 if (fp->file._flags & _IO_LINKED)
62 struct _IO_FILE **f;
63 #ifdef _IO_MTSAFE_IO
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);
68 #endif
69 if (_IO_list_all == NULL)
71 else if (fp == _IO_list_all)
73 _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
74 ++_IO_list_all_stamp;
76 else
77 for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
78 if (*f == (_IO_FILE *) fp)
80 *f = fp->file._chain;
81 ++_IO_list_all_stamp;
82 break;
84 fp->file._flags &= ~_IO_LINKED;
85 #ifdef _IO_MTSAFE_IO
86 _IO_funlockfile ((_IO_FILE *) fp);
87 run_fp = NULL;
88 _IO_lock_unlock (list_all_lock);
89 _IO_cleanup_region_end (0);
90 #endif
93 libc_hidden_def (_IO_un_link)
95 void
96 _IO_link_in (struct _IO_FILE_plus *fp)
98 if ((fp->file._flags & _IO_LINKED) == 0)
100 fp->file._flags |= _IO_LINKED;
101 #ifdef _IO_MTSAFE_IO
102 _IO_cleanup_region_start_noarg (flush_cleanup);
103 _IO_lock_lock (list_all_lock);
104 run_fp = (_IO_FILE *) fp;
105 _IO_flockfile ((_IO_FILE *) fp);
106 #endif
107 fp->file._chain = (_IO_FILE *) _IO_list_all;
108 _IO_list_all = fp;
109 ++_IO_list_all_stamp;
110 #ifdef _IO_MTSAFE_IO
111 _IO_funlockfile ((_IO_FILE *) fp);
112 run_fp = NULL;
113 _IO_lock_unlock (list_all_lock);
114 _IO_cleanup_region_end (0);
115 #endif
118 libc_hidden_def (_IO_link_in)
120 /* Return minimum _pos markers
121 Assumes the current get area is the main get area. */
122 _IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
124 _IO_ssize_t
125 _IO_least_marker (_IO_FILE *fp, char *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;
132 return least_so_far;
135 /* Switch current get area from backup buffer to (start of) main get area. */
137 void
138 _IO_switch_to_main_get_area (_IO_FILE *fp)
140 char *tmp;
141 fp->_flags &= ~_IO_IN_BACKUP;
142 /* Swap _IO_read_end and _IO_save_end. */
143 tmp = fp->_IO_read_end;
144 fp->_IO_read_end = fp->_IO_save_end;
145 fp->_IO_save_end= tmp;
146 /* Swap _IO_read_base and _IO_save_base. */
147 tmp = fp->_IO_read_base;
148 fp->_IO_read_base = fp->_IO_save_base;
149 fp->_IO_save_base = tmp;
150 /* Set _IO_read_ptr. */
151 fp->_IO_read_ptr = fp->_IO_read_base;
154 /* Switch current get area from main get area to (end of) backup area. */
156 void
157 _IO_switch_to_backup_area (_IO_FILE *fp)
159 char *tmp;
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 (_IO_FILE *fp)
176 if (fp->_IO_write_ptr > fp->_IO_write_base)
177 if (_IO_OVERFLOW (fp, EOF) == EOF)
178 return EOF;
179 if (_IO_in_backup (fp))
180 fp->_IO_read_base = fp->_IO_backup_base;
181 else
183 fp->_IO_read_base = fp->_IO_buf_base;
184 if (fp->_IO_write_ptr > fp->_IO_read_end)
185 fp->_IO_read_end = fp->_IO_write_ptr;
187 fp->_IO_read_ptr = fp->_IO_write_ptr;
189 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
191 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
192 return 0;
194 libc_hidden_def (_IO_switch_to_get_mode)
196 void
197 _IO_free_backup_area (_IO_FILE *fp)
199 if (_IO_in_backup (fp))
200 _IO_switch_to_main_get_area (fp); /* Just in case. */
201 free (fp->_IO_save_base);
202 fp->_IO_save_base = NULL;
203 fp->_IO_save_end = NULL;
204 fp->_IO_backup_base = NULL;
206 libc_hidden_def (_IO_free_backup_area)
208 #if 0
210 _IO_switch_to_put_mode (_IO_FILE *fp)
212 fp->_IO_write_base = fp->_IO_read_ptr;
213 fp->_IO_write_ptr = fp->_IO_read_ptr;
214 /* Following is wrong if line- or un-buffered? */
215 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
216 ? fp->_IO_read_end : fp->_IO_buf_end);
218 fp->_IO_read_ptr = fp->_IO_read_end;
219 fp->_IO_read_base = fp->_IO_read_end;
221 fp->_flags |= _IO_CURRENTLY_PUTTING;
222 return 0;
224 #endif
227 __overflow (_IO_FILE *f, int ch)
229 /* This is a single-byte stream. */
230 if (f->_mode == 0)
231 _IO_fwide (f, -1);
232 return _IO_OVERFLOW (f, ch);
234 libc_hidden_def (__overflow)
236 static int save_for_backup (_IO_FILE *fp, char *end_p)
237 #ifdef _LIBC
238 internal_function
239 #endif
242 static int
243 #ifdef _LIBC
244 internal_function
245 #endif
246 save_for_backup (_IO_FILE *fp, char *end_p)
248 /* Append [_IO_read_base..end_p] to backup area. */
249 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
250 /* needed_size is how much space we need in the backup area. */
251 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
252 /* FIXME: Dubious arithmetic if pointers are NULL */
253 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
254 _IO_size_t avail; /* Extra space available for future expansion. */
255 _IO_ssize_t delta;
256 struct _IO_marker *mark;
257 if (needed_size > current_Bsize)
259 char *new_buffer;
260 avail = 100;
261 new_buffer = (char *) malloc (avail + needed_size);
262 if (new_buffer == NULL)
263 return EOF; /* FIXME */
264 if (least_mark < 0)
266 #ifdef _LIBC
267 __mempcpy (__mempcpy (new_buffer + avail,
268 fp->_IO_save_end + least_mark,
269 -least_mark),
270 fp->_IO_read_base,
271 end_p - fp->_IO_read_base);
272 #else
273 memcpy (new_buffer + avail,
274 fp->_IO_save_end + least_mark,
275 -least_mark);
276 memcpy (new_buffer + avail - least_mark,
277 fp->_IO_read_base,
278 end_p - fp->_IO_read_base);
279 #endif
281 else
282 memcpy (new_buffer + avail,
283 fp->_IO_read_base + least_mark,
284 needed_size);
285 free (fp->_IO_save_base);
286 fp->_IO_save_base = new_buffer;
287 fp->_IO_save_end = new_buffer + avail + needed_size;
289 else
291 avail = current_Bsize - needed_size;
292 if (least_mark < 0)
294 memmove (fp->_IO_save_base + avail,
295 fp->_IO_save_end + least_mark,
296 -least_mark);
297 memcpy (fp->_IO_save_base + avail - least_mark,
298 fp->_IO_read_base,
299 end_p - fp->_IO_read_base);
301 else if (needed_size > 0)
302 memcpy (fp->_IO_save_base + avail,
303 fp->_IO_read_base + least_mark,
304 needed_size);
306 fp->_IO_backup_base = fp->_IO_save_base + avail;
307 /* Adjust all the streammarkers. */
308 delta = end_p - fp->_IO_read_base;
309 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
310 mark->_pos -= delta;
311 return 0;
315 __underflow (_IO_FILE *fp)
317 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
318 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
319 return EOF;
320 #endif
322 if (fp->_mode == 0)
323 _IO_fwide (fp, -1);
324 if (_IO_in_put_mode (fp))
325 if (_IO_switch_to_get_mode (fp) == EOF)
326 return EOF;
327 if (fp->_IO_read_ptr < fp->_IO_read_end)
328 return *(unsigned char *) fp->_IO_read_ptr;
329 if (_IO_in_backup (fp))
331 _IO_switch_to_main_get_area (fp);
332 if (fp->_IO_read_ptr < fp->_IO_read_end)
333 return *(unsigned char *) fp->_IO_read_ptr;
335 if (_IO_have_markers (fp))
337 if (save_for_backup (fp, fp->_IO_read_end))
338 return EOF;
340 else if (_IO_have_backup (fp))
341 _IO_free_backup_area (fp);
342 return _IO_UNDERFLOW (fp);
344 libc_hidden_def (__underflow)
347 __uflow (_IO_FILE *fp)
349 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
350 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
351 return EOF;
352 #endif
354 if (fp->_mode == 0)
355 _IO_fwide (fp, -1);
356 if (_IO_in_put_mode (fp))
357 if (_IO_switch_to_get_mode (fp) == EOF)
358 return EOF;
359 if (fp->_IO_read_ptr < fp->_IO_read_end)
360 return *(unsigned char *) fp->_IO_read_ptr++;
361 if (_IO_in_backup (fp))
363 _IO_switch_to_main_get_area (fp);
364 if (fp->_IO_read_ptr < fp->_IO_read_end)
365 return *(unsigned char *) fp->_IO_read_ptr++;
367 if (_IO_have_markers (fp))
369 if (save_for_backup (fp, fp->_IO_read_end))
370 return EOF;
372 else if (_IO_have_backup (fp))
373 _IO_free_backup_area (fp);
374 return _IO_UFLOW (fp);
376 libc_hidden_def (__uflow)
378 void
379 _IO_setb (_IO_FILE *f, char *b, char *eb, int a)
381 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
382 free (f->_IO_buf_base);
383 f->_IO_buf_base = b;
384 f->_IO_buf_end = eb;
385 if (a)
386 f->_flags &= ~_IO_USER_BUF;
387 else
388 f->_flags |= _IO_USER_BUF;
390 libc_hidden_def (_IO_setb)
392 void
393 _IO_doallocbuf (_IO_FILE *fp)
395 if (fp->_IO_buf_base)
396 return;
397 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
398 if (_IO_DOALLOCATE (fp) != EOF)
399 return;
400 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
402 libc_hidden_def (_IO_doallocbuf)
405 _IO_default_underflow (_IO_FILE *fp)
407 return EOF;
411 _IO_default_uflow (_IO_FILE *fp)
413 int ch = _IO_UNDERFLOW (fp);
414 if (ch == EOF)
415 return EOF;
416 return *(unsigned char *) fp->_IO_read_ptr++;
418 libc_hidden_def (_IO_default_uflow)
420 _IO_size_t
421 _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
423 const char *s = (char *) data;
424 _IO_size_t more = n;
425 if (more <= 0)
426 return 0;
427 for (;;)
429 /* Space available. */
430 if (f->_IO_write_ptr < f->_IO_write_end)
432 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
433 if (count > more)
434 count = more;
435 if (count > 20)
437 #ifdef _LIBC
438 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
439 #else
440 memcpy (f->_IO_write_ptr, s, count);
441 f->_IO_write_ptr += count;
442 #endif
443 s += count;
445 else if (count)
447 char *p = f->_IO_write_ptr;
448 _IO_ssize_t i;
449 for (i = count; --i >= 0; )
450 *p++ = *s++;
451 f->_IO_write_ptr = p;
453 more -= count;
455 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
456 break;
457 more--;
459 return n - more;
461 libc_hidden_def (_IO_default_xsputn)
463 _IO_size_t
464 _IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n)
466 /* FIXME handle putback buffer here! */
467 return _IO_XSGETN (fp, data, n);
469 libc_hidden_def (_IO_sgetn)
471 _IO_size_t
472 _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
474 _IO_size_t more = n;
475 char *s = (char*) data;
476 for (;;)
478 /* Data available. */
479 if (fp->_IO_read_ptr < fp->_IO_read_end)
481 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
482 if (count > more)
483 count = more;
484 if (count > 20)
486 #ifdef _LIBC
487 s = __mempcpy (s, fp->_IO_read_ptr, count);
488 #else
489 memcpy (s, fp->_IO_read_ptr, count);
490 s += count;
491 #endif
492 fp->_IO_read_ptr += count;
494 else if (count)
496 char *p = fp->_IO_read_ptr;
497 int i = (int) count;
498 while (--i >= 0)
499 *s++ = *p++;
500 fp->_IO_read_ptr = p;
502 more -= count;
504 if (more == 0 || __underflow (fp) == EOF)
505 break;
507 return n - more;
509 libc_hidden_def (_IO_default_xsgetn)
511 #if 0
512 /* Seems not to be needed. --drepper */
514 _IO_sync (_IO_FILE *fp)
516 return 0;
518 #endif
520 _IO_FILE *
521 _IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
523 if (_IO_SYNC (fp) == EOF)
524 return NULL;
525 if (p == NULL || len == 0)
527 fp->_flags |= _IO_UNBUFFERED;
528 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
530 else
532 fp->_flags &= ~_IO_UNBUFFERED;
533 _IO_setb (fp, p, p+len, 0);
535 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
536 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
537 return fp;
540 _IO_off64_t
541 _IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode)
543 return _IO_SEEKOFF (fp, pos, 0, mode);
547 _IO_default_doallocate (_IO_FILE *fp)
549 char *buf;
551 buf = malloc(_IO_BUFSIZ);
552 if (__glibc_unlikely (buf == NULL))
553 return EOF;
555 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
556 return 1;
558 libc_hidden_def (_IO_default_doallocate)
560 void
561 _IO_init (_IO_FILE *fp, int flags)
563 _IO_no_init (fp, flags, -1, NULL, NULL);
565 libc_hidden_def (_IO_init)
567 void
568 _IO_old_init (_IO_FILE *fp, int flags)
570 fp->_flags = _IO_MAGIC|flags;
571 fp->_flags2 = 0;
572 fp->_IO_buf_base = NULL;
573 fp->_IO_buf_end = NULL;
574 fp->_IO_read_base = NULL;
575 fp->_IO_read_ptr = NULL;
576 fp->_IO_read_end = NULL;
577 fp->_IO_write_base = NULL;
578 fp->_IO_write_ptr = NULL;
579 fp->_IO_write_end = NULL;
580 fp->_chain = NULL; /* Not necessary. */
582 fp->_IO_save_base = NULL;
583 fp->_IO_backup_base = NULL;
584 fp->_IO_save_end = NULL;
585 fp->_markers = NULL;
586 fp->_cur_column = 0;
587 #if _IO_JUMPS_OFFSET
588 fp->_vtable_offset = 0;
589 #endif
590 #ifdef _IO_MTSAFE_IO
591 if (fp->_lock != NULL)
592 _IO_lock_init (*fp->_lock);
593 #endif
596 void
597 _IO_no_init (_IO_FILE *fp, int flags, int orientation,
598 struct _IO_wide_data *wd, const struct _IO_jump_t *jmp)
600 _IO_old_init (fp, flags);
601 fp->_mode = orientation;
602 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
603 if (orientation >= 0)
605 fp->_wide_data = wd;
606 fp->_wide_data->_IO_buf_base = NULL;
607 fp->_wide_data->_IO_buf_end = NULL;
608 fp->_wide_data->_IO_read_base = NULL;
609 fp->_wide_data->_IO_read_ptr = NULL;
610 fp->_wide_data->_IO_read_end = NULL;
611 fp->_wide_data->_IO_write_base = NULL;
612 fp->_wide_data->_IO_write_ptr = NULL;
613 fp->_wide_data->_IO_write_end = NULL;
614 fp->_wide_data->_IO_save_base = NULL;
615 fp->_wide_data->_IO_backup_base = NULL;
616 fp->_wide_data->_IO_save_end = NULL;
618 fp->_wide_data->_wide_vtable = jmp;
620 else
621 /* Cause predictable crash when a wide function is called on a byte
622 stream. */
623 fp->_wide_data = (struct _IO_wide_data *) -1L;
624 #endif
625 fp->_freeres_list = NULL;
629 _IO_default_sync (_IO_FILE *fp)
631 return 0;
634 /* The way the C++ classes are mapped into the C functions in the
635 current implementation, this function can get called twice! */
637 void
638 _IO_default_finish (_IO_FILE *fp, int dummy)
640 struct _IO_marker *mark;
641 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
643 free (fp->_IO_buf_base);
644 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
647 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
648 mark->_sbuf = NULL;
650 if (fp->_IO_save_base)
652 free (fp->_IO_save_base);
653 fp->_IO_save_base = NULL;
656 _IO_un_link ((struct _IO_FILE_plus *) fp);
658 #ifdef _IO_MTSAFE_IO
659 if (fp->_lock != NULL)
660 _IO_lock_fini (*fp->_lock);
661 #endif
663 libc_hidden_def (_IO_default_finish)
665 _IO_off64_t
666 _IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
668 return _IO_pos_BAD;
672 _IO_sputbackc (_IO_FILE *fp, int c)
674 int result;
676 if (fp->_IO_read_ptr > fp->_IO_read_base
677 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
679 fp->_IO_read_ptr--;
680 result = (unsigned char) c;
682 else
683 result = _IO_PBACKFAIL (fp, c);
685 if (result != EOF)
686 fp->_flags &= ~_IO_EOF_SEEN;
688 return result;
690 libc_hidden_def (_IO_sputbackc)
693 _IO_sungetc (_IO_FILE *fp)
695 int result;
697 if (fp->_IO_read_ptr > fp->_IO_read_base)
699 fp->_IO_read_ptr--;
700 result = (unsigned char) *fp->_IO_read_ptr;
702 else
703 result = _IO_PBACKFAIL (fp, EOF);
705 if (result != EOF)
706 fp->_flags &= ~_IO_EOF_SEEN;
708 return result;
711 #if 0 /* Work in progress */
712 /* Seems not to be needed. */
713 #if 0
714 void
715 _IO_set_column (_IO_FILE *fp, int c)
717 if (c == -1)
718 fp->_column = -1;
719 else
720 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
722 #else
724 _IO_set_column (_IO_FILE *fp, int i)
726 fp->_cur_column = i + 1;
727 return 0;
729 #endif
730 #endif
733 unsigned
734 _IO_adjust_column (unsigned start, const char *line, int count)
736 const char *ptr = line + count;
737 while (ptr > line)
738 if (*--ptr == '\n')
739 return line + count - ptr - 1;
740 return start + count;
742 libc_hidden_def (_IO_adjust_column)
744 #if 0
745 /* Seems not to be needed. --drepper */
747 _IO_get_column (_IO_FILE *fp)
749 if (fp->_cur_column)
750 return _IO_adjust_column (fp->_cur_column - 1,
751 fp->_IO_write_base,
752 fp->_IO_write_ptr - fp->_IO_write_base);
753 return -1;
755 #endif
759 _IO_flush_all_lockp (int do_lock)
761 int result = 0;
762 struct _IO_FILE *fp;
763 int last_stamp;
765 #ifdef _IO_MTSAFE_IO
766 __libc_cleanup_region_start (do_lock, flush_cleanup, NULL);
767 if (do_lock)
768 _IO_lock_lock (list_all_lock);
769 #endif
771 last_stamp = _IO_list_all_stamp;
772 fp = (_IO_FILE *) _IO_list_all;
773 while (fp != NULL)
775 run_fp = fp;
776 if (do_lock)
777 _IO_flockfile (fp);
779 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
780 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
781 || (_IO_vtable_offset (fp) == 0
782 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
783 > fp->_wide_data->_IO_write_base))
784 #endif
786 && _IO_OVERFLOW (fp, EOF) == EOF)
787 result = EOF;
789 if (do_lock)
790 _IO_funlockfile (fp);
791 run_fp = NULL;
793 if (last_stamp != _IO_list_all_stamp)
795 /* Something was added to the list. Start all over again. */
796 fp = (_IO_FILE *) _IO_list_all;
797 last_stamp = _IO_list_all_stamp;
799 else
800 fp = fp->_chain;
803 #ifdef _IO_MTSAFE_IO
804 if (do_lock)
805 _IO_lock_unlock (list_all_lock);
806 __libc_cleanup_region_end (0);
807 #endif
809 return result;
814 _IO_flush_all (void)
816 /* We want locking. */
817 return _IO_flush_all_lockp (1);
819 libc_hidden_def (_IO_flush_all)
821 void
822 _IO_flush_all_linebuffered (void)
824 struct _IO_FILE *fp;
825 int last_stamp;
827 #ifdef _IO_MTSAFE_IO
828 _IO_cleanup_region_start_noarg (flush_cleanup);
829 _IO_lock_lock (list_all_lock);
830 #endif
832 last_stamp = _IO_list_all_stamp;
833 fp = (_IO_FILE *) _IO_list_all;
834 while (fp != NULL)
836 run_fp = fp;
837 _IO_flockfile (fp);
839 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
840 _IO_OVERFLOW (fp, EOF);
842 _IO_funlockfile (fp);
843 run_fp = NULL;
845 if (last_stamp != _IO_list_all_stamp)
847 /* Something was added to the list. Start all over again. */
848 fp = (_IO_FILE *) _IO_list_all;
849 last_stamp = _IO_list_all_stamp;
851 else
852 fp = fp->_chain;
855 #ifdef _IO_MTSAFE_IO
856 _IO_lock_unlock (list_all_lock);
857 _IO_cleanup_region_end (0);
858 #endif
860 libc_hidden_def (_IO_flush_all_linebuffered)
861 #ifdef _LIBC
862 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
863 #endif
866 /* The following is a bit tricky. In general, we want to unbuffer the
867 streams so that all output which follows is seen. If we are not
868 looking for memory leaks it does not make much sense to free the
869 actual buffer because this will happen anyway once the program
870 terminated. If we do want to look for memory leaks we have to free
871 the buffers. Whether something is freed is determined by the
872 function sin the libc_freeres section. Those are called as part of
873 the atexit routine, just like _IO_cleanup. The problem is we do
874 not know whether the freeres code is called first or _IO_cleanup.
875 if the former is the case, we set the DEALLOC_BUFFER variable to
876 true and _IO_unbuffer_all will take care of the rest. If
877 _IO_unbuffer_all is called first we add the streams to a list
878 which the freeres function later can walk through. */
879 static void _IO_unbuffer_all (void);
881 static bool dealloc_buffers;
882 static _IO_FILE *freeres_list;
884 static void
885 _IO_unbuffer_all (void)
887 struct _IO_FILE *fp;
888 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
890 if (! (fp->_flags & _IO_UNBUFFERED)
891 /* Iff stream is un-orientated, it wasn't used. */
892 && fp->_mode != 0)
894 #ifdef _IO_MTSAFE_IO
895 int cnt;
896 #define MAXTRIES 2
897 for (cnt = 0; cnt < MAXTRIES; ++cnt)
898 if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
899 break;
900 else
901 /* Give the other thread time to finish up its use of the
902 stream. */
903 __sched_yield ();
904 #endif
906 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
908 fp->_flags |= _IO_USER_BUF;
910 fp->_freeres_list = freeres_list;
911 freeres_list = fp;
912 fp->_freeres_buf = fp->_IO_buf_base;
915 _IO_SETBUF (fp, NULL, 0);
917 if (fp->_mode > 0)
918 _IO_wsetb (fp, NULL, NULL, 0);
920 #ifdef _IO_MTSAFE_IO
921 if (cnt < MAXTRIES && fp->_lock != NULL)
922 _IO_lock_unlock (*fp->_lock);
923 #endif
926 /* Make sure that never again the wide char functions can be
927 used. */
928 fp->_mode = -1;
933 libc_freeres_fn (buffer_free)
935 dealloc_buffers = true;
937 while (freeres_list != NULL)
939 free (freeres_list->_freeres_buf);
941 freeres_list = freeres_list->_freeres_list;
947 _IO_cleanup (void)
949 /* We do *not* want locking. Some threads might use streams but
950 that is their problem, we flush them underneath them. */
951 int result = _IO_flush_all_lockp (0);
953 /* We currently don't have a reliable mechanism for making sure that
954 C++ static destructors are executed in the correct order.
955 So it is possible that other static destructors might want to
956 write to cout - and they're supposed to be able to do so.
958 The following will make the standard streambufs be unbuffered,
959 which forces any output from late destructors to be written out. */
960 _IO_unbuffer_all ();
962 return result;
966 void
967 _IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp)
969 marker->_sbuf = fp;
970 if (_IO_in_put_mode (fp))
971 _IO_switch_to_get_mode (fp);
972 if (_IO_in_backup (fp))
973 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
974 else
975 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
977 /* Should perhaps sort the chain? */
978 marker->_next = fp->_markers;
979 fp->_markers = marker;
982 void
983 _IO_remove_marker (struct _IO_marker *marker)
985 /* Unlink from sb's chain. */
986 struct _IO_marker **ptr = &marker->_sbuf->_markers;
987 for (; ; ptr = &(*ptr)->_next)
989 if (*ptr == NULL)
990 break;
991 else if (*ptr == marker)
993 *ptr = marker->_next;
994 return;
997 #if 0
998 if _sbuf has a backup area that is no longer needed, should we delete
999 it now, or wait until the next underflow?
1000 #endif
1003 #define BAD_DELTA EOF
1006 _IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2)
1008 return mark1->_pos - mark2->_pos;
1011 /* Return difference between MARK and current position of MARK's stream. */
1013 _IO_marker_delta (struct _IO_marker *mark)
1015 int cur_pos;
1016 if (mark->_sbuf == NULL)
1017 return BAD_DELTA;
1018 if (_IO_in_backup (mark->_sbuf))
1019 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1020 else
1021 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1022 return mark->_pos - cur_pos;
1026 _IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta)
1028 if (mark->_sbuf != fp)
1029 return EOF;
1030 if (mark->_pos >= 0)
1032 if (_IO_in_backup (fp))
1033 _IO_switch_to_main_get_area (fp);
1034 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1036 else
1038 if (!_IO_in_backup (fp))
1039 _IO_switch_to_backup_area (fp);
1040 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1042 return 0;
1045 void
1046 _IO_unsave_markers (_IO_FILE *fp)
1048 struct _IO_marker *mark = fp->_markers;
1049 if (mark)
1051 #ifdef TODO
1052 streampos offset = seekoff (0, ios::cur, ios::in);
1053 if (offset != EOF)
1055 offset += eGptr () - Gbase ();
1056 for ( ; mark != NULL; mark = mark->_next)
1057 mark->set_streampos (mark->_pos + offset);
1059 else
1061 for ( ; mark != NULL; mark = mark->_next)
1062 mark->set_streampos (EOF);
1064 #endif
1065 fp->_markers = 0;
1068 if (_IO_have_backup (fp))
1069 _IO_free_backup_area (fp);
1071 libc_hidden_def (_IO_unsave_markers)
1073 #if 0
1074 /* Seems not to be needed. --drepper */
1076 _IO_nobackup_pbackfail (_IO_FILE *fp, int c)
1078 if (fp->_IO_read_ptr > fp->_IO_read_base)
1079 fp->_IO_read_ptr--;
1080 if (c != EOF && *fp->_IO_read_ptr != c)
1081 *fp->_IO_read_ptr = c;
1082 return (unsigned char) c;
1084 #endif
1087 _IO_default_pbackfail (_IO_FILE *fp, int c)
1089 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1090 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1091 --fp->_IO_read_ptr;
1092 else
1094 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1095 if (!_IO_in_backup (fp))
1097 /* We need to keep the invariant that the main get area
1098 logically follows the backup area. */
1099 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1101 if (save_for_backup (fp, fp->_IO_read_ptr))
1102 return EOF;
1104 else if (!_IO_have_backup (fp))
1106 /* No backup buffer: allocate one. */
1107 /* Use nshort buffer, if unused? (probably not) FIXME */
1108 int backup_size = 128;
1109 char *bbuf = (char *) malloc (backup_size);
1110 if (bbuf == NULL)
1111 return EOF;
1112 fp->_IO_save_base = bbuf;
1113 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1114 fp->_IO_backup_base = fp->_IO_save_end;
1116 fp->_IO_read_base = fp->_IO_read_ptr;
1117 _IO_switch_to_backup_area (fp);
1119 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1121 /* Increase size of existing backup buffer. */
1122 _IO_size_t new_size;
1123 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1124 char *new_buf;
1125 new_size = 2 * old_size;
1126 new_buf = (char *) malloc (new_size);
1127 if (new_buf == NULL)
1128 return EOF;
1129 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1130 old_size);
1131 free (fp->_IO_read_base);
1132 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1133 new_buf + new_size);
1134 fp->_IO_backup_base = fp->_IO_read_ptr;
1137 *--fp->_IO_read_ptr = c;
1139 return (unsigned char) c;
1141 libc_hidden_def (_IO_default_pbackfail)
1143 _IO_off64_t
1144 _IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1146 return _IO_pos_BAD;
1150 _IO_default_stat (_IO_FILE *fp, void *st)
1152 return EOF;
1155 _IO_ssize_t
1156 _IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n)
1158 return -1;
1161 _IO_ssize_t
1162 _IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n)
1164 return 0;
1168 _IO_default_showmanyc (_IO_FILE *fp)
1170 return -1;
1173 void
1174 _IO_default_imbue (_IO_FILE *fp, void *locale)
1178 _IO_ITER
1179 _IO_iter_begin (void)
1181 return (_IO_ITER) _IO_list_all;
1183 libc_hidden_def (_IO_iter_begin)
1185 _IO_ITER
1186 _IO_iter_end (void)
1188 return NULL;
1190 libc_hidden_def (_IO_iter_end)
1192 _IO_ITER
1193 _IO_iter_next (_IO_ITER iter)
1195 return iter->_chain;
1197 libc_hidden_def (_IO_iter_next)
1199 _IO_FILE *
1200 _IO_iter_file (_IO_ITER iter)
1202 return iter;
1204 libc_hidden_def (_IO_iter_file)
1206 void
1207 _IO_list_lock (void)
1209 #ifdef _IO_MTSAFE_IO
1210 _IO_lock_lock (list_all_lock);
1211 #endif
1213 libc_hidden_def (_IO_list_lock)
1215 void
1216 _IO_list_unlock (void)
1218 #ifdef _IO_MTSAFE_IO
1219 _IO_lock_unlock (list_all_lock);
1220 #endif
1222 libc_hidden_def (_IO_list_unlock)
1224 void
1225 _IO_list_resetlock (void)
1227 #ifdef _IO_MTSAFE_IO
1228 _IO_lock_init (list_all_lock);
1229 #endif
1231 libc_hidden_def (_IO_list_resetlock)
1234 #ifdef TODO
1235 #if defined(linux)
1236 #define IO_CLEANUP ;
1237 #endif
1239 #ifdef IO_CLEANUP
1240 IO_CLEANUP
1241 #else
1242 struct __io_defs {
1243 __io_defs() { }
1244 ~__io_defs() { _IO_cleanup (); }
1246 __io_defs io_defs__;
1247 #endif
1249 #endif /* TODO */
1251 #ifdef text_set_element
1252 text_set_element(__libc_atexit, _IO_cleanup);
1253 #endif