Add thunderx2t99 and thunderx2t99p1 CPU names to tunables list
[glibc.git] / libio / genops.c
blobe3f372520a35e9bd349d7cab94bb2ed68d8e44dd
1 /* Copyright (C) 1993-2017 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 #include <sched.h>
35 #ifdef _IO_MTSAFE_IO
36 static _IO_lock_t list_all_lock = _IO_lock_initializer;
37 #endif
39 /* Used to signal modifications to the list of FILE decriptors. */
40 static int _IO_list_all_stamp;
43 static _IO_FILE *run_fp;
45 #ifdef _IO_MTSAFE_IO
46 static void
47 flush_cleanup (void *not_used)
49 if (run_fp != NULL)
50 _IO_funlockfile (run_fp);
51 _IO_lock_unlock (list_all_lock);
53 #endif
55 void
56 _IO_un_link (struct _IO_FILE_plus *fp)
58 if (fp->file._flags & _IO_LINKED)
60 struct _IO_FILE **f;
61 #ifdef _IO_MTSAFE_IO
62 _IO_cleanup_region_start_noarg (flush_cleanup);
63 _IO_lock_lock (list_all_lock);
64 run_fp = (_IO_FILE *) fp;
65 _IO_flockfile ((_IO_FILE *) fp);
66 #endif
67 if (_IO_list_all == NULL)
69 else if (fp == _IO_list_all)
71 _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain;
72 ++_IO_list_all_stamp;
74 else
75 for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain)
76 if (*f == (_IO_FILE *) fp)
78 *f = fp->file._chain;
79 ++_IO_list_all_stamp;
80 break;
82 fp->file._flags &= ~_IO_LINKED;
83 #ifdef _IO_MTSAFE_IO
84 _IO_funlockfile ((_IO_FILE *) fp);
85 run_fp = NULL;
86 _IO_lock_unlock (list_all_lock);
87 _IO_cleanup_region_end (0);
88 #endif
91 libc_hidden_def (_IO_un_link)
93 void
94 _IO_link_in (struct _IO_FILE_plus *fp)
96 if ((fp->file._flags & _IO_LINKED) == 0)
98 fp->file._flags |= _IO_LINKED;
99 #ifdef _IO_MTSAFE_IO
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);
104 #endif
105 fp->file._chain = (_IO_FILE *) _IO_list_all;
106 _IO_list_all = fp;
107 ++_IO_list_all_stamp;
108 #ifdef _IO_MTSAFE_IO
109 _IO_funlockfile ((_IO_FILE *) fp);
110 run_fp = NULL;
111 _IO_lock_unlock (list_all_lock);
112 _IO_cleanup_region_end (0);
113 #endif
116 libc_hidden_def (_IO_link_in)
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);
122 _IO_ssize_t
123 _IO_least_marker (_IO_FILE *fp, char *end_p)
125 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
126 struct _IO_marker *mark;
127 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
128 if (mark->_pos < least_so_far)
129 least_so_far = mark->_pos;
130 return least_so_far;
133 /* Switch current get area from backup buffer to (start of) main get area. */
135 void
136 _IO_switch_to_main_get_area (_IO_FILE *fp)
138 char *tmp;
139 fp->_flags &= ~_IO_IN_BACKUP;
140 /* Swap _IO_read_end and _IO_save_end. */
141 tmp = fp->_IO_read_end;
142 fp->_IO_read_end = fp->_IO_save_end;
143 fp->_IO_save_end= tmp;
144 /* Swap _IO_read_base and _IO_save_base. */
145 tmp = fp->_IO_read_base;
146 fp->_IO_read_base = fp->_IO_save_base;
147 fp->_IO_save_base = tmp;
148 /* Set _IO_read_ptr. */
149 fp->_IO_read_ptr = fp->_IO_read_base;
152 /* Switch current get area from main get area to (end of) backup area. */
154 void
155 _IO_switch_to_backup_area (_IO_FILE *fp)
157 char *tmp;
158 fp->_flags |= _IO_IN_BACKUP;
159 /* Swap _IO_read_end and _IO_save_end. */
160 tmp = fp->_IO_read_end;
161 fp->_IO_read_end = fp->_IO_save_end;
162 fp->_IO_save_end = tmp;
163 /* Swap _IO_read_base and _IO_save_base. */
164 tmp = fp->_IO_read_base;
165 fp->_IO_read_base = fp->_IO_save_base;
166 fp->_IO_save_base = tmp;
167 /* Set _IO_read_ptr. */
168 fp->_IO_read_ptr = fp->_IO_read_end;
172 _IO_switch_to_get_mode (_IO_FILE *fp)
174 if (fp->_IO_write_ptr > fp->_IO_write_base)
175 if (_IO_OVERFLOW (fp, EOF) == EOF)
176 return EOF;
177 if (_IO_in_backup (fp))
178 fp->_IO_read_base = fp->_IO_backup_base;
179 else
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;
190 return 0;
192 libc_hidden_def (_IO_switch_to_get_mode)
194 void
195 _IO_free_backup_area (_IO_FILE *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;
204 libc_hidden_def (_IO_free_backup_area)
206 #if 0
208 _IO_switch_to_put_mode (_IO_FILE *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;
220 return 0;
222 #endif
225 __overflow (_IO_FILE *f, int ch)
227 /* This is a single-byte stream. */
228 if (f->_mode == 0)
229 _IO_fwide (f, -1);
230 return _IO_OVERFLOW (f, ch);
232 libc_hidden_def (__overflow)
234 static int
235 save_for_backup (_IO_FILE *fp, char *end_p)
237 /* Append [_IO_read_base..end_p] to backup area. */
238 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
239 /* needed_size is how much space we need in the backup area. */
240 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
241 /* FIXME: Dubious arithmetic if pointers are NULL */
242 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
243 _IO_size_t avail; /* Extra space available for future expansion. */
244 _IO_ssize_t delta;
245 struct _IO_marker *mark;
246 if (needed_size > current_Bsize)
248 char *new_buffer;
249 avail = 100;
250 new_buffer = (char *) malloc (avail + needed_size);
251 if (new_buffer == NULL)
252 return EOF; /* FIXME */
253 if (least_mark < 0)
255 __mempcpy (__mempcpy (new_buffer + avail,
256 fp->_IO_save_end + least_mark,
257 -least_mark),
258 fp->_IO_read_base,
259 end_p - fp->_IO_read_base);
261 else
262 memcpy (new_buffer + avail,
263 fp->_IO_read_base + least_mark,
264 needed_size);
265 free (fp->_IO_save_base);
266 fp->_IO_save_base = new_buffer;
267 fp->_IO_save_end = new_buffer + avail + needed_size;
269 else
271 avail = current_Bsize - needed_size;
272 if (least_mark < 0)
274 memmove (fp->_IO_save_base + avail,
275 fp->_IO_save_end + least_mark,
276 -least_mark);
277 memcpy (fp->_IO_save_base + avail - least_mark,
278 fp->_IO_read_base,
279 end_p - fp->_IO_read_base);
281 else if (needed_size > 0)
282 memcpy (fp->_IO_save_base + avail,
283 fp->_IO_read_base + least_mark,
284 needed_size);
286 fp->_IO_backup_base = fp->_IO_save_base + avail;
287 /* Adjust all the streammarkers. */
288 delta = end_p - fp->_IO_read_base;
289 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
290 mark->_pos -= delta;
291 return 0;
295 __underflow (_IO_FILE *fp)
297 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
298 return EOF;
300 if (fp->_mode == 0)
301 _IO_fwide (fp, -1);
302 if (_IO_in_put_mode (fp))
303 if (_IO_switch_to_get_mode (fp) == EOF)
304 return EOF;
305 if (fp->_IO_read_ptr < fp->_IO_read_end)
306 return *(unsigned char *) fp->_IO_read_ptr;
307 if (_IO_in_backup (fp))
309 _IO_switch_to_main_get_area (fp);
310 if (fp->_IO_read_ptr < fp->_IO_read_end)
311 return *(unsigned char *) fp->_IO_read_ptr;
313 if (_IO_have_markers (fp))
315 if (save_for_backup (fp, fp->_IO_read_end))
316 return EOF;
318 else if (_IO_have_backup (fp))
319 _IO_free_backup_area (fp);
320 return _IO_UNDERFLOW (fp);
322 libc_hidden_def (__underflow)
325 __uflow (_IO_FILE *fp)
327 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
328 return EOF;
330 if (fp->_mode == 0)
331 _IO_fwide (fp, -1);
332 if (_IO_in_put_mode (fp))
333 if (_IO_switch_to_get_mode (fp) == EOF)
334 return EOF;
335 if (fp->_IO_read_ptr < fp->_IO_read_end)
336 return *(unsigned char *) fp->_IO_read_ptr++;
337 if (_IO_in_backup (fp))
339 _IO_switch_to_main_get_area (fp);
340 if (fp->_IO_read_ptr < fp->_IO_read_end)
341 return *(unsigned char *) fp->_IO_read_ptr++;
343 if (_IO_have_markers (fp))
345 if (save_for_backup (fp, fp->_IO_read_end))
346 return EOF;
348 else if (_IO_have_backup (fp))
349 _IO_free_backup_area (fp);
350 return _IO_UFLOW (fp);
352 libc_hidden_def (__uflow)
354 void
355 _IO_setb (_IO_FILE *f, char *b, char *eb, int a)
357 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
358 free (f->_IO_buf_base);
359 f->_IO_buf_base = b;
360 f->_IO_buf_end = eb;
361 if (a)
362 f->_flags &= ~_IO_USER_BUF;
363 else
364 f->_flags |= _IO_USER_BUF;
366 libc_hidden_def (_IO_setb)
368 void
369 _IO_doallocbuf (_IO_FILE *fp)
371 if (fp->_IO_buf_base)
372 return;
373 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
374 if (_IO_DOALLOCATE (fp) != EOF)
375 return;
376 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
378 libc_hidden_def (_IO_doallocbuf)
381 _IO_default_underflow (_IO_FILE *fp)
383 return EOF;
387 _IO_default_uflow (_IO_FILE *fp)
389 int ch = _IO_UNDERFLOW (fp);
390 if (ch == EOF)
391 return EOF;
392 return *(unsigned char *) fp->_IO_read_ptr++;
394 libc_hidden_def (_IO_default_uflow)
396 _IO_size_t
397 _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
399 const char *s = (char *) data;
400 _IO_size_t more = n;
401 if (more <= 0)
402 return 0;
403 for (;;)
405 /* Space available. */
406 if (f->_IO_write_ptr < f->_IO_write_end)
408 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
409 if (count > more)
410 count = more;
411 if (count > 20)
413 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
414 s += count;
416 else if (count)
418 char *p = f->_IO_write_ptr;
419 _IO_ssize_t i;
420 for (i = count; --i >= 0; )
421 *p++ = *s++;
422 f->_IO_write_ptr = p;
424 more -= count;
426 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
427 break;
428 more--;
430 return n - more;
432 libc_hidden_def (_IO_default_xsputn)
434 _IO_size_t
435 _IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n)
437 /* FIXME handle putback buffer here! */
438 return _IO_XSGETN (fp, data, n);
440 libc_hidden_def (_IO_sgetn)
442 _IO_size_t
443 _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
445 _IO_size_t more = n;
446 char *s = (char*) data;
447 for (;;)
449 /* Data available. */
450 if (fp->_IO_read_ptr < fp->_IO_read_end)
452 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
453 if (count > more)
454 count = more;
455 if (count > 20)
457 s = __mempcpy (s, fp->_IO_read_ptr, count);
458 fp->_IO_read_ptr += count;
460 else if (count)
462 char *p = fp->_IO_read_ptr;
463 int i = (int) count;
464 while (--i >= 0)
465 *s++ = *p++;
466 fp->_IO_read_ptr = p;
468 more -= count;
470 if (more == 0 || __underflow (fp) == EOF)
471 break;
473 return n - more;
475 libc_hidden_def (_IO_default_xsgetn)
477 #if 0
478 /* Seems not to be needed. --drepper */
480 _IO_sync (_IO_FILE *fp)
482 return 0;
484 #endif
486 _IO_FILE *
487 _IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
489 if (_IO_SYNC (fp) == EOF)
490 return NULL;
491 if (p == NULL || len == 0)
493 fp->_flags |= _IO_UNBUFFERED;
494 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
496 else
498 fp->_flags &= ~_IO_UNBUFFERED;
499 _IO_setb (fp, p, p+len, 0);
501 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
502 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
503 return fp;
506 _IO_off64_t
507 _IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode)
509 return _IO_SEEKOFF (fp, pos, 0, mode);
513 _IO_default_doallocate (_IO_FILE *fp)
515 char *buf;
517 buf = malloc(_IO_BUFSIZ);
518 if (__glibc_unlikely (buf == NULL))
519 return EOF;
521 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
522 return 1;
524 libc_hidden_def (_IO_default_doallocate)
526 void
527 _IO_init_internal (_IO_FILE *fp, int flags)
529 _IO_no_init (fp, flags, -1, NULL, NULL);
532 void
533 _IO_init (_IO_FILE *fp, int flags)
535 IO_set_accept_foreign_vtables (&_IO_vtable_check);
536 _IO_init_internal (fp, flags);
539 static int stdio_needs_locking;
541 /* In a single-threaded process most stdio locks can be omitted. After
542 _IO_enable_locks is called, locks are not optimized away any more.
543 It must be first called while the process is still single-threaded.
545 This lock optimization can be disabled on a per-file basis by setting
546 _IO_FLAGS2_NEED_LOCK, because a file can have user-defined callbacks
547 or can be locked with flockfile and then a thread may be created
548 between a lock and unlock, so omitting the lock is not valid.
550 Here we have to make sure that the flag is set on all existing files
551 and files created later. */
552 void
553 _IO_enable_locks (void)
555 _IO_ITER i;
557 if (stdio_needs_locking)
558 return;
559 stdio_needs_locking = 1;
560 for (i = _IO_iter_begin (); i != _IO_iter_end (); i = _IO_iter_next (i))
561 _IO_iter_file (i)->_flags2 |= _IO_FLAGS2_NEED_LOCK;
563 libc_hidden_def (_IO_enable_locks)
565 void
566 _IO_old_init (_IO_FILE *fp, int flags)
568 fp->_flags = _IO_MAGIC|flags;
569 fp->_flags2 = 0;
570 if (stdio_needs_locking)
571 fp->_flags2 |= _IO_FLAGS2_NEED_LOCK;
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 (orientation >= 0)
604 fp->_wide_data = wd;
605 fp->_wide_data->_IO_buf_base = NULL;
606 fp->_wide_data->_IO_buf_end = NULL;
607 fp->_wide_data->_IO_read_base = NULL;
608 fp->_wide_data->_IO_read_ptr = NULL;
609 fp->_wide_data->_IO_read_end = NULL;
610 fp->_wide_data->_IO_write_base = NULL;
611 fp->_wide_data->_IO_write_ptr = NULL;
612 fp->_wide_data->_IO_write_end = NULL;
613 fp->_wide_data->_IO_save_base = NULL;
614 fp->_wide_data->_IO_backup_base = NULL;
615 fp->_wide_data->_IO_save_end = NULL;
617 fp->_wide_data->_wide_vtable = jmp;
619 else
620 /* Cause predictable crash when a wide function is called on a byte
621 stream. */
622 fp->_wide_data = (struct _IO_wide_data *) -1L;
623 fp->_freeres_list = NULL;
627 _IO_default_sync (_IO_FILE *fp)
629 return 0;
632 /* The way the C++ classes are mapped into the C functions in the
633 current implementation, this function can get called twice! */
635 void
636 _IO_default_finish (_IO_FILE *fp, int dummy)
638 struct _IO_marker *mark;
639 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
641 free (fp->_IO_buf_base);
642 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
645 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
646 mark->_sbuf = NULL;
648 if (fp->_IO_save_base)
650 free (fp->_IO_save_base);
651 fp->_IO_save_base = NULL;
654 _IO_un_link ((struct _IO_FILE_plus *) fp);
656 #ifdef _IO_MTSAFE_IO
657 if (fp->_lock != NULL)
658 _IO_lock_fini (*fp->_lock);
659 #endif
661 libc_hidden_def (_IO_default_finish)
663 _IO_off64_t
664 _IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
666 return _IO_pos_BAD;
670 _IO_sputbackc (_IO_FILE *fp, int c)
672 int result;
674 if (fp->_IO_read_ptr > fp->_IO_read_base
675 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
677 fp->_IO_read_ptr--;
678 result = (unsigned char) c;
680 else
681 result = _IO_PBACKFAIL (fp, c);
683 if (result != EOF)
684 fp->_flags &= ~_IO_EOF_SEEN;
686 return result;
688 libc_hidden_def (_IO_sputbackc)
691 _IO_sungetc (_IO_FILE *fp)
693 int result;
695 if (fp->_IO_read_ptr > fp->_IO_read_base)
697 fp->_IO_read_ptr--;
698 result = (unsigned char) *fp->_IO_read_ptr;
700 else
701 result = _IO_PBACKFAIL (fp, EOF);
703 if (result != EOF)
704 fp->_flags &= ~_IO_EOF_SEEN;
706 return result;
709 #if 0 /* Work in progress */
710 /* Seems not to be needed. */
711 #if 0
712 void
713 _IO_set_column (_IO_FILE *fp, int c)
715 if (c == -1)
716 fp->_column = -1;
717 else
718 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
720 #else
722 _IO_set_column (_IO_FILE *fp, int i)
724 fp->_cur_column = i + 1;
725 return 0;
727 #endif
728 #endif
731 unsigned
732 _IO_adjust_column (unsigned start, const char *line, int count)
734 const char *ptr = line + count;
735 while (ptr > line)
736 if (*--ptr == '\n')
737 return line + count - ptr - 1;
738 return start + count;
740 libc_hidden_def (_IO_adjust_column)
742 #if 0
743 /* Seems not to be needed. --drepper */
745 _IO_get_column (_IO_FILE *fp)
747 if (fp->_cur_column)
748 return _IO_adjust_column (fp->_cur_column - 1,
749 fp->_IO_write_base,
750 fp->_IO_write_ptr - fp->_IO_write_base);
751 return -1;
753 #endif
757 _IO_flush_all_lockp (int do_lock)
759 int result = 0;
760 struct _IO_FILE *fp;
761 int last_stamp;
763 #ifdef _IO_MTSAFE_IO
764 __libc_cleanup_region_start (do_lock, flush_cleanup, NULL);
765 if (do_lock)
766 _IO_lock_lock (list_all_lock);
767 #endif
769 last_stamp = _IO_list_all_stamp;
770 fp = (_IO_FILE *) _IO_list_all;
771 while (fp != NULL)
773 run_fp = fp;
774 if (do_lock)
775 _IO_flockfile (fp);
777 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
778 || (_IO_vtable_offset (fp) == 0
779 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
780 > fp->_wide_data->_IO_write_base))
782 && _IO_OVERFLOW (fp, EOF) == EOF)
783 result = EOF;
785 if (do_lock)
786 _IO_funlockfile (fp);
787 run_fp = NULL;
789 if (last_stamp != _IO_list_all_stamp)
791 /* Something was added to the list. Start all over again. */
792 fp = (_IO_FILE *) _IO_list_all;
793 last_stamp = _IO_list_all_stamp;
795 else
796 fp = fp->_chain;
799 #ifdef _IO_MTSAFE_IO
800 if (do_lock)
801 _IO_lock_unlock (list_all_lock);
802 __libc_cleanup_region_end (0);
803 #endif
805 return result;
810 _IO_flush_all (void)
812 /* We want locking. */
813 return _IO_flush_all_lockp (1);
815 libc_hidden_def (_IO_flush_all)
817 void
818 _IO_flush_all_linebuffered (void)
820 struct _IO_FILE *fp;
821 int last_stamp;
823 #ifdef _IO_MTSAFE_IO
824 _IO_cleanup_region_start_noarg (flush_cleanup);
825 _IO_lock_lock (list_all_lock);
826 #endif
828 last_stamp = _IO_list_all_stamp;
829 fp = (_IO_FILE *) _IO_list_all;
830 while (fp != NULL)
832 run_fp = fp;
833 _IO_flockfile (fp);
835 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
836 _IO_OVERFLOW (fp, EOF);
838 _IO_funlockfile (fp);
839 run_fp = NULL;
841 if (last_stamp != _IO_list_all_stamp)
843 /* Something was added to the list. Start all over again. */
844 fp = (_IO_FILE *) _IO_list_all;
845 last_stamp = _IO_list_all_stamp;
847 else
848 fp = fp->_chain;
851 #ifdef _IO_MTSAFE_IO
852 _IO_lock_unlock (list_all_lock);
853 _IO_cleanup_region_end (0);
854 #endif
856 libc_hidden_def (_IO_flush_all_linebuffered)
857 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
860 /* The following is a bit tricky. In general, we want to unbuffer the
861 streams so that all output which follows is seen. If we are not
862 looking for memory leaks it does not make much sense to free the
863 actual buffer because this will happen anyway once the program
864 terminated. If we do want to look for memory leaks we have to free
865 the buffers. Whether something is freed is determined by the
866 function sin the libc_freeres section. Those are called as part of
867 the atexit routine, just like _IO_cleanup. The problem is we do
868 not know whether the freeres code is called first or _IO_cleanup.
869 if the former is the case, we set the DEALLOC_BUFFER variable to
870 true and _IO_unbuffer_all will take care of the rest. If
871 _IO_unbuffer_all is called first we add the streams to a list
872 which the freeres function later can walk through. */
873 static void _IO_unbuffer_all (void);
875 static bool dealloc_buffers;
876 static _IO_FILE *freeres_list;
878 static void
879 _IO_unbuffer_all (void)
881 struct _IO_FILE *fp;
882 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
884 if (! (fp->_flags & _IO_UNBUFFERED)
885 /* Iff stream is un-orientated, it wasn't used. */
886 && fp->_mode != 0)
888 #ifdef _IO_MTSAFE_IO
889 int cnt;
890 #define MAXTRIES 2
891 for (cnt = 0; cnt < MAXTRIES; ++cnt)
892 if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
893 break;
894 else
895 /* Give the other thread time to finish up its use of the
896 stream. */
897 __sched_yield ();
898 #endif
900 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
902 fp->_flags |= _IO_USER_BUF;
904 fp->_freeres_list = freeres_list;
905 freeres_list = fp;
906 fp->_freeres_buf = fp->_IO_buf_base;
909 _IO_SETBUF (fp, NULL, 0);
911 if (fp->_mode > 0)
912 _IO_wsetb (fp, NULL, NULL, 0);
914 #ifdef _IO_MTSAFE_IO
915 if (cnt < MAXTRIES && fp->_lock != NULL)
916 _IO_lock_unlock (*fp->_lock);
917 #endif
920 /* Make sure that never again the wide char functions can be
921 used. */
922 fp->_mode = -1;
927 libc_freeres_fn (buffer_free)
929 dealloc_buffers = true;
931 while (freeres_list != NULL)
933 free (freeres_list->_freeres_buf);
935 freeres_list = freeres_list->_freeres_list;
941 _IO_cleanup (void)
943 /* We do *not* want locking. Some threads might use streams but
944 that is their problem, we flush them underneath them. */
945 int result = _IO_flush_all_lockp (0);
947 /* We currently don't have a reliable mechanism for making sure that
948 C++ static destructors are executed in the correct order.
949 So it is possible that other static destructors might want to
950 write to cout - and they're supposed to be able to do so.
952 The following will make the standard streambufs be unbuffered,
953 which forces any output from late destructors to be written out. */
954 _IO_unbuffer_all ();
956 return result;
960 void
961 _IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp)
963 marker->_sbuf = fp;
964 if (_IO_in_put_mode (fp))
965 _IO_switch_to_get_mode (fp);
966 if (_IO_in_backup (fp))
967 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
968 else
969 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
971 /* Should perhaps sort the chain? */
972 marker->_next = fp->_markers;
973 fp->_markers = marker;
976 void
977 _IO_remove_marker (struct _IO_marker *marker)
979 /* Unlink from sb's chain. */
980 struct _IO_marker **ptr = &marker->_sbuf->_markers;
981 for (; ; ptr = &(*ptr)->_next)
983 if (*ptr == NULL)
984 break;
985 else if (*ptr == marker)
987 *ptr = marker->_next;
988 return;
991 #if 0
992 if _sbuf has a backup area that is no longer needed, should we delete
993 it now, or wait until the next underflow?
994 #endif
997 #define BAD_DELTA EOF
1000 _IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2)
1002 return mark1->_pos - mark2->_pos;
1005 /* Return difference between MARK and current position of MARK's stream. */
1007 _IO_marker_delta (struct _IO_marker *mark)
1009 int cur_pos;
1010 if (mark->_sbuf == NULL)
1011 return BAD_DELTA;
1012 if (_IO_in_backup (mark->_sbuf))
1013 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1014 else
1015 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1016 return mark->_pos - cur_pos;
1020 _IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta)
1022 if (mark->_sbuf != fp)
1023 return EOF;
1024 if (mark->_pos >= 0)
1026 if (_IO_in_backup (fp))
1027 _IO_switch_to_main_get_area (fp);
1028 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1030 else
1032 if (!_IO_in_backup (fp))
1033 _IO_switch_to_backup_area (fp);
1034 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1036 return 0;
1039 void
1040 _IO_unsave_markers (_IO_FILE *fp)
1042 struct _IO_marker *mark = fp->_markers;
1043 if (mark)
1045 #ifdef TODO
1046 streampos offset = seekoff (0, ios::cur, ios::in);
1047 if (offset != EOF)
1049 offset += eGptr () - Gbase ();
1050 for ( ; mark != NULL; mark = mark->_next)
1051 mark->set_streampos (mark->_pos + offset);
1053 else
1055 for ( ; mark != NULL; mark = mark->_next)
1056 mark->set_streampos (EOF);
1058 #endif
1059 fp->_markers = 0;
1062 if (_IO_have_backup (fp))
1063 _IO_free_backup_area (fp);
1065 libc_hidden_def (_IO_unsave_markers)
1067 #if 0
1068 /* Seems not to be needed. --drepper */
1070 _IO_nobackup_pbackfail (_IO_FILE *fp, int c)
1072 if (fp->_IO_read_ptr > fp->_IO_read_base)
1073 fp->_IO_read_ptr--;
1074 if (c != EOF && *fp->_IO_read_ptr != c)
1075 *fp->_IO_read_ptr = c;
1076 return (unsigned char) c;
1078 #endif
1081 _IO_default_pbackfail (_IO_FILE *fp, int c)
1083 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1084 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1085 --fp->_IO_read_ptr;
1086 else
1088 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1089 if (!_IO_in_backup (fp))
1091 /* We need to keep the invariant that the main get area
1092 logically follows the backup area. */
1093 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1095 if (save_for_backup (fp, fp->_IO_read_ptr))
1096 return EOF;
1098 else if (!_IO_have_backup (fp))
1100 /* No backup buffer: allocate one. */
1101 /* Use nshort buffer, if unused? (probably not) FIXME */
1102 int backup_size = 128;
1103 char *bbuf = (char *) malloc (backup_size);
1104 if (bbuf == NULL)
1105 return EOF;
1106 fp->_IO_save_base = bbuf;
1107 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1108 fp->_IO_backup_base = fp->_IO_save_end;
1110 fp->_IO_read_base = fp->_IO_read_ptr;
1111 _IO_switch_to_backup_area (fp);
1113 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1115 /* Increase size of existing backup buffer. */
1116 _IO_size_t new_size;
1117 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1118 char *new_buf;
1119 new_size = 2 * old_size;
1120 new_buf = (char *) malloc (new_size);
1121 if (new_buf == NULL)
1122 return EOF;
1123 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1124 old_size);
1125 free (fp->_IO_read_base);
1126 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1127 new_buf + new_size);
1128 fp->_IO_backup_base = fp->_IO_read_ptr;
1131 *--fp->_IO_read_ptr = c;
1133 return (unsigned char) c;
1135 libc_hidden_def (_IO_default_pbackfail)
1137 _IO_off64_t
1138 _IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1140 return _IO_pos_BAD;
1144 _IO_default_stat (_IO_FILE *fp, void *st)
1146 return EOF;
1149 _IO_ssize_t
1150 _IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n)
1152 return -1;
1155 _IO_ssize_t
1156 _IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n)
1158 return 0;
1162 _IO_default_showmanyc (_IO_FILE *fp)
1164 return -1;
1167 void
1168 _IO_default_imbue (_IO_FILE *fp, void *locale)
1172 _IO_ITER
1173 _IO_iter_begin (void)
1175 return (_IO_ITER) _IO_list_all;
1177 libc_hidden_def (_IO_iter_begin)
1179 _IO_ITER
1180 _IO_iter_end (void)
1182 return NULL;
1184 libc_hidden_def (_IO_iter_end)
1186 _IO_ITER
1187 _IO_iter_next (_IO_ITER iter)
1189 return iter->_chain;
1191 libc_hidden_def (_IO_iter_next)
1193 _IO_FILE *
1194 _IO_iter_file (_IO_ITER iter)
1196 return iter;
1198 libc_hidden_def (_IO_iter_file)
1200 void
1201 _IO_list_lock (void)
1203 #ifdef _IO_MTSAFE_IO
1204 _IO_lock_lock (list_all_lock);
1205 #endif
1207 libc_hidden_def (_IO_list_lock)
1209 void
1210 _IO_list_unlock (void)
1212 #ifdef _IO_MTSAFE_IO
1213 _IO_lock_unlock (list_all_lock);
1214 #endif
1216 libc_hidden_def (_IO_list_unlock)
1218 void
1219 _IO_list_resetlock (void)
1221 #ifdef _IO_MTSAFE_IO
1222 _IO_lock_init (list_all_lock);
1223 #endif
1225 libc_hidden_def (_IO_list_resetlock)
1228 #ifdef TODO
1229 #if defined(linux)
1230 #define IO_CLEANUP ;
1231 #endif
1233 #ifdef IO_CLEANUP
1234 IO_CLEANUP
1235 #else
1236 struct __io_defs {
1237 __io_defs() { }
1238 ~__io_defs() { _IO_cleanup (); }
1240 __io_defs io_defs__;
1241 #endif
1243 #endif /* TODO */
1245 #ifdef text_set_element
1246 text_set_element(__libc_atexit, _IO_cleanup);
1247 #endif