Convert 69 more function definitions to prototype style (line wrap cases).
[glibc.git] / libio / genops.c
blob377bda311f00cdd36477c07c91661c9f751844a5
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 (fp, end_p)
247 _IO_FILE *fp;
248 char *end_p;
250 /* Append [_IO_read_base..end_p] to backup area. */
251 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
252 /* needed_size is how much space we need in the backup area. */
253 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
254 /* FIXME: Dubious arithmetic if pointers are NULL */
255 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
256 _IO_size_t avail; /* Extra space available for future expansion. */
257 _IO_ssize_t delta;
258 struct _IO_marker *mark;
259 if (needed_size > current_Bsize)
261 char *new_buffer;
262 avail = 100;
263 new_buffer = (char *) malloc (avail + needed_size);
264 if (new_buffer == NULL)
265 return EOF; /* FIXME */
266 if (least_mark < 0)
268 #ifdef _LIBC
269 __mempcpy (__mempcpy (new_buffer + avail,
270 fp->_IO_save_end + least_mark,
271 -least_mark),
272 fp->_IO_read_base,
273 end_p - fp->_IO_read_base);
274 #else
275 memcpy (new_buffer + avail,
276 fp->_IO_save_end + least_mark,
277 -least_mark);
278 memcpy (new_buffer + avail - least_mark,
279 fp->_IO_read_base,
280 end_p - fp->_IO_read_base);
281 #endif
283 else
284 memcpy (new_buffer + avail,
285 fp->_IO_read_base + least_mark,
286 needed_size);
287 free (fp->_IO_save_base);
288 fp->_IO_save_base = new_buffer;
289 fp->_IO_save_end = new_buffer + avail + needed_size;
291 else
293 avail = current_Bsize - needed_size;
294 if (least_mark < 0)
296 memmove (fp->_IO_save_base + avail,
297 fp->_IO_save_end + least_mark,
298 -least_mark);
299 memcpy (fp->_IO_save_base + avail - least_mark,
300 fp->_IO_read_base,
301 end_p - fp->_IO_read_base);
303 else if (needed_size > 0)
304 memcpy (fp->_IO_save_base + avail,
305 fp->_IO_read_base + least_mark,
306 needed_size);
308 fp->_IO_backup_base = fp->_IO_save_base + avail;
309 /* Adjust all the streammarkers. */
310 delta = end_p - fp->_IO_read_base;
311 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
312 mark->_pos -= delta;
313 return 0;
317 __underflow (_IO_FILE *fp)
319 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
320 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
321 return EOF;
322 #endif
324 if (fp->_mode == 0)
325 _IO_fwide (fp, -1);
326 if (_IO_in_put_mode (fp))
327 if (_IO_switch_to_get_mode (fp) == EOF)
328 return EOF;
329 if (fp->_IO_read_ptr < fp->_IO_read_end)
330 return *(unsigned char *) fp->_IO_read_ptr;
331 if (_IO_in_backup (fp))
333 _IO_switch_to_main_get_area (fp);
334 if (fp->_IO_read_ptr < fp->_IO_read_end)
335 return *(unsigned char *) fp->_IO_read_ptr;
337 if (_IO_have_markers (fp))
339 if (save_for_backup (fp, fp->_IO_read_end))
340 return EOF;
342 else if (_IO_have_backup (fp))
343 _IO_free_backup_area (fp);
344 return _IO_UNDERFLOW (fp);
346 libc_hidden_def (__underflow)
349 __uflow (_IO_FILE *fp)
351 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
352 if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
353 return EOF;
354 #endif
356 if (fp->_mode == 0)
357 _IO_fwide (fp, -1);
358 if (_IO_in_put_mode (fp))
359 if (_IO_switch_to_get_mode (fp) == EOF)
360 return EOF;
361 if (fp->_IO_read_ptr < fp->_IO_read_end)
362 return *(unsigned char *) fp->_IO_read_ptr++;
363 if (_IO_in_backup (fp))
365 _IO_switch_to_main_get_area (fp);
366 if (fp->_IO_read_ptr < fp->_IO_read_end)
367 return *(unsigned char *) fp->_IO_read_ptr++;
369 if (_IO_have_markers (fp))
371 if (save_for_backup (fp, fp->_IO_read_end))
372 return EOF;
374 else if (_IO_have_backup (fp))
375 _IO_free_backup_area (fp);
376 return _IO_UFLOW (fp);
378 libc_hidden_def (__uflow)
380 void
381 _IO_setb (_IO_FILE *f, char *b, char *eb, int a)
383 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
384 free (f->_IO_buf_base);
385 f->_IO_buf_base = b;
386 f->_IO_buf_end = eb;
387 if (a)
388 f->_flags &= ~_IO_USER_BUF;
389 else
390 f->_flags |= _IO_USER_BUF;
392 libc_hidden_def (_IO_setb)
394 void
395 _IO_doallocbuf (_IO_FILE *fp)
397 if (fp->_IO_buf_base)
398 return;
399 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
400 if (_IO_DOALLOCATE (fp) != EOF)
401 return;
402 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
404 libc_hidden_def (_IO_doallocbuf)
407 _IO_default_underflow (_IO_FILE *fp)
409 return EOF;
413 _IO_default_uflow (_IO_FILE *fp)
415 int ch = _IO_UNDERFLOW (fp);
416 if (ch == EOF)
417 return EOF;
418 return *(unsigned char *) fp->_IO_read_ptr++;
420 libc_hidden_def (_IO_default_uflow)
422 _IO_size_t
423 _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
425 const char *s = (char *) data;
426 _IO_size_t more = n;
427 if (more <= 0)
428 return 0;
429 for (;;)
431 /* Space available. */
432 if (f->_IO_write_ptr < f->_IO_write_end)
434 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
435 if (count > more)
436 count = more;
437 if (count > 20)
439 #ifdef _LIBC
440 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
441 #else
442 memcpy (f->_IO_write_ptr, s, count);
443 f->_IO_write_ptr += count;
444 #endif
445 s += count;
447 else if (count)
449 char *p = f->_IO_write_ptr;
450 _IO_ssize_t i;
451 for (i = count; --i >= 0; )
452 *p++ = *s++;
453 f->_IO_write_ptr = p;
455 more -= count;
457 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
458 break;
459 more--;
461 return n - more;
463 libc_hidden_def (_IO_default_xsputn)
465 _IO_size_t
466 _IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n)
468 /* FIXME handle putback buffer here! */
469 return _IO_XSGETN (fp, data, n);
471 libc_hidden_def (_IO_sgetn)
473 _IO_size_t
474 _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
476 _IO_size_t more = n;
477 char *s = (char*) data;
478 for (;;)
480 /* Data available. */
481 if (fp->_IO_read_ptr < fp->_IO_read_end)
483 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
484 if (count > more)
485 count = more;
486 if (count > 20)
488 #ifdef _LIBC
489 s = __mempcpy (s, fp->_IO_read_ptr, count);
490 #else
491 memcpy (s, fp->_IO_read_ptr, count);
492 s += count;
493 #endif
494 fp->_IO_read_ptr += count;
496 else if (count)
498 char *p = fp->_IO_read_ptr;
499 int i = (int) count;
500 while (--i >= 0)
501 *s++ = *p++;
502 fp->_IO_read_ptr = p;
504 more -= count;
506 if (more == 0 || __underflow (fp) == EOF)
507 break;
509 return n - more;
511 libc_hidden_def (_IO_default_xsgetn)
513 #if 0
514 /* Seems not to be needed. --drepper */
516 _IO_sync (_IO_FILE *fp)
518 return 0;
520 #endif
522 _IO_FILE *
523 _IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len)
525 if (_IO_SYNC (fp) == EOF)
526 return NULL;
527 if (p == NULL || len == 0)
529 fp->_flags |= _IO_UNBUFFERED;
530 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
532 else
534 fp->_flags &= ~_IO_UNBUFFERED;
535 _IO_setb (fp, p, p+len, 0);
537 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
538 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
539 return fp;
542 _IO_off64_t
543 _IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode)
545 return _IO_SEEKOFF (fp, pos, 0, mode);
549 _IO_default_doallocate (_IO_FILE *fp)
551 char *buf;
553 buf = malloc(_IO_BUFSIZ);
554 if (__glibc_unlikely (buf == NULL))
555 return EOF;
557 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
558 return 1;
560 libc_hidden_def (_IO_default_doallocate)
562 void
563 _IO_init (_IO_FILE *fp, int flags)
565 _IO_no_init (fp, flags, -1, NULL, NULL);
567 libc_hidden_def (_IO_init)
569 void
570 _IO_old_init (_IO_FILE *fp, int flags)
572 fp->_flags = _IO_MAGIC|flags;
573 fp->_flags2 = 0;
574 fp->_IO_buf_base = NULL;
575 fp->_IO_buf_end = NULL;
576 fp->_IO_read_base = NULL;
577 fp->_IO_read_ptr = NULL;
578 fp->_IO_read_end = NULL;
579 fp->_IO_write_base = NULL;
580 fp->_IO_write_ptr = NULL;
581 fp->_IO_write_end = NULL;
582 fp->_chain = NULL; /* Not necessary. */
584 fp->_IO_save_base = NULL;
585 fp->_IO_backup_base = NULL;
586 fp->_IO_save_end = NULL;
587 fp->_markers = NULL;
588 fp->_cur_column = 0;
589 #if _IO_JUMPS_OFFSET
590 fp->_vtable_offset = 0;
591 #endif
592 #ifdef _IO_MTSAFE_IO
593 if (fp->_lock != NULL)
594 _IO_lock_init (*fp->_lock);
595 #endif
598 void
599 _IO_no_init (_IO_FILE *fp, int flags, int orientation,
600 struct _IO_wide_data *wd, const struct _IO_jump_t *jmp)
602 _IO_old_init (fp, flags);
603 fp->_mode = orientation;
604 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
605 if (orientation >= 0)
607 fp->_wide_data = wd;
608 fp->_wide_data->_IO_buf_base = NULL;
609 fp->_wide_data->_IO_buf_end = NULL;
610 fp->_wide_data->_IO_read_base = NULL;
611 fp->_wide_data->_IO_read_ptr = NULL;
612 fp->_wide_data->_IO_read_end = NULL;
613 fp->_wide_data->_IO_write_base = NULL;
614 fp->_wide_data->_IO_write_ptr = NULL;
615 fp->_wide_data->_IO_write_end = NULL;
616 fp->_wide_data->_IO_save_base = NULL;
617 fp->_wide_data->_IO_backup_base = NULL;
618 fp->_wide_data->_IO_save_end = NULL;
620 fp->_wide_data->_wide_vtable = jmp;
622 else
623 /* Cause predictable crash when a wide function is called on a byte
624 stream. */
625 fp->_wide_data = (struct _IO_wide_data *) -1L;
626 #endif
627 fp->_freeres_list = NULL;
631 _IO_default_sync (_IO_FILE *fp)
633 return 0;
636 /* The way the C++ classes are mapped into the C functions in the
637 current implementation, this function can get called twice! */
639 void
640 _IO_default_finish (_IO_FILE *fp, int dummy)
642 struct _IO_marker *mark;
643 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
645 free (fp->_IO_buf_base);
646 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
649 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
650 mark->_sbuf = NULL;
652 if (fp->_IO_save_base)
654 free (fp->_IO_save_base);
655 fp->_IO_save_base = NULL;
658 _IO_un_link ((struct _IO_FILE_plus *) fp);
660 #ifdef _IO_MTSAFE_IO
661 if (fp->_lock != NULL)
662 _IO_lock_fini (*fp->_lock);
663 #endif
665 libc_hidden_def (_IO_default_finish)
667 _IO_off64_t
668 _IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
670 return _IO_pos_BAD;
674 _IO_sputbackc (_IO_FILE *fp, int c)
676 int result;
678 if (fp->_IO_read_ptr > fp->_IO_read_base
679 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
681 fp->_IO_read_ptr--;
682 result = (unsigned char) c;
684 else
685 result = _IO_PBACKFAIL (fp, c);
687 if (result != EOF)
688 fp->_flags &= ~_IO_EOF_SEEN;
690 return result;
692 libc_hidden_def (_IO_sputbackc)
695 _IO_sungetc (_IO_FILE *fp)
697 int result;
699 if (fp->_IO_read_ptr > fp->_IO_read_base)
701 fp->_IO_read_ptr--;
702 result = (unsigned char) *fp->_IO_read_ptr;
704 else
705 result = _IO_PBACKFAIL (fp, EOF);
707 if (result != EOF)
708 fp->_flags &= ~_IO_EOF_SEEN;
710 return result;
713 #if 0 /* Work in progress */
714 /* Seems not to be needed. */
715 #if 0
716 void
717 _IO_set_column (_IO_FILE *fp, int c)
719 if (c == -1)
720 fp->_column = -1;
721 else
722 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
724 #else
726 _IO_set_column (_IO_FILE *fp, int i)
728 fp->_cur_column = i + 1;
729 return 0;
731 #endif
732 #endif
735 unsigned
736 _IO_adjust_column (unsigned start, const char *line, int count)
738 const char *ptr = line + count;
739 while (ptr > line)
740 if (*--ptr == '\n')
741 return line + count - ptr - 1;
742 return start + count;
744 libc_hidden_def (_IO_adjust_column)
746 #if 0
747 /* Seems not to be needed. --drepper */
749 _IO_get_column (_IO_FILE *fp)
751 if (fp->_cur_column)
752 return _IO_adjust_column (fp->_cur_column - 1,
753 fp->_IO_write_base,
754 fp->_IO_write_ptr - fp->_IO_write_base);
755 return -1;
757 #endif
761 _IO_flush_all_lockp (int do_lock)
763 int result = 0;
764 struct _IO_FILE *fp;
765 int last_stamp;
767 #ifdef _IO_MTSAFE_IO
768 __libc_cleanup_region_start (do_lock, flush_cleanup, NULL);
769 if (do_lock)
770 _IO_lock_lock (list_all_lock);
771 #endif
773 last_stamp = _IO_list_all_stamp;
774 fp = (_IO_FILE *) _IO_list_all;
775 while (fp != NULL)
777 run_fp = fp;
778 if (do_lock)
779 _IO_flockfile (fp);
781 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
782 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
783 || (_IO_vtable_offset (fp) == 0
784 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
785 > fp->_wide_data->_IO_write_base))
786 #endif
788 && _IO_OVERFLOW (fp, EOF) == EOF)
789 result = EOF;
791 if (do_lock)
792 _IO_funlockfile (fp);
793 run_fp = NULL;
795 if (last_stamp != _IO_list_all_stamp)
797 /* Something was added to the list. Start all over again. */
798 fp = (_IO_FILE *) _IO_list_all;
799 last_stamp = _IO_list_all_stamp;
801 else
802 fp = fp->_chain;
805 #ifdef _IO_MTSAFE_IO
806 if (do_lock)
807 _IO_lock_unlock (list_all_lock);
808 __libc_cleanup_region_end (0);
809 #endif
811 return result;
816 _IO_flush_all (void)
818 /* We want locking. */
819 return _IO_flush_all_lockp (1);
821 libc_hidden_def (_IO_flush_all)
823 void
824 _IO_flush_all_linebuffered (void)
826 struct _IO_FILE *fp;
827 int last_stamp;
829 #ifdef _IO_MTSAFE_IO
830 _IO_cleanup_region_start_noarg (flush_cleanup);
831 _IO_lock_lock (list_all_lock);
832 #endif
834 last_stamp = _IO_list_all_stamp;
835 fp = (_IO_FILE *) _IO_list_all;
836 while (fp != NULL)
838 run_fp = fp;
839 _IO_flockfile (fp);
841 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
842 _IO_OVERFLOW (fp, EOF);
844 _IO_funlockfile (fp);
845 run_fp = NULL;
847 if (last_stamp != _IO_list_all_stamp)
849 /* Something was added to the list. Start all over again. */
850 fp = (_IO_FILE *) _IO_list_all;
851 last_stamp = _IO_list_all_stamp;
853 else
854 fp = fp->_chain;
857 #ifdef _IO_MTSAFE_IO
858 _IO_lock_unlock (list_all_lock);
859 _IO_cleanup_region_end (0);
860 #endif
862 libc_hidden_def (_IO_flush_all_linebuffered)
863 #ifdef _LIBC
864 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
865 #endif
868 /* The following is a bit tricky. In general, we want to unbuffer the
869 streams so that all output which follows is seen. If we are not
870 looking for memory leaks it does not make much sense to free the
871 actual buffer because this will happen anyway once the program
872 terminated. If we do want to look for memory leaks we have to free
873 the buffers. Whether something is freed is determined by the
874 function sin the libc_freeres section. Those are called as part of
875 the atexit routine, just like _IO_cleanup. The problem is we do
876 not know whether the freeres code is called first or _IO_cleanup.
877 if the former is the case, we set the DEALLOC_BUFFER variable to
878 true and _IO_unbuffer_all will take care of the rest. If
879 _IO_unbuffer_all is called first we add the streams to a list
880 which the freeres function later can walk through. */
881 static void _IO_unbuffer_all (void);
883 static bool dealloc_buffers;
884 static _IO_FILE *freeres_list;
886 static void
887 _IO_unbuffer_all (void)
889 struct _IO_FILE *fp;
890 for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain)
892 if (! (fp->_flags & _IO_UNBUFFERED)
893 /* Iff stream is un-orientated, it wasn't used. */
894 && fp->_mode != 0)
896 #ifdef _IO_MTSAFE_IO
897 int cnt;
898 #define MAXTRIES 2
899 for (cnt = 0; cnt < MAXTRIES; ++cnt)
900 if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0)
901 break;
902 else
903 /* Give the other thread time to finish up its use of the
904 stream. */
905 __sched_yield ();
906 #endif
908 if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
910 fp->_flags |= _IO_USER_BUF;
912 fp->_freeres_list = freeres_list;
913 freeres_list = fp;
914 fp->_freeres_buf = fp->_IO_buf_base;
917 _IO_SETBUF (fp, NULL, 0);
919 if (fp->_mode > 0)
920 _IO_wsetb (fp, NULL, NULL, 0);
922 #ifdef _IO_MTSAFE_IO
923 if (cnt < MAXTRIES && fp->_lock != NULL)
924 _IO_lock_unlock (*fp->_lock);
925 #endif
928 /* Make sure that never again the wide char functions can be
929 used. */
930 fp->_mode = -1;
935 libc_freeres_fn (buffer_free)
937 dealloc_buffers = true;
939 while (freeres_list != NULL)
941 free (freeres_list->_freeres_buf);
943 freeres_list = freeres_list->_freeres_list;
949 _IO_cleanup (void)
951 /* We do *not* want locking. Some threads might use streams but
952 that is their problem, we flush them underneath them. */
953 int result = _IO_flush_all_lockp (0);
955 /* We currently don't have a reliable mechanism for making sure that
956 C++ static destructors are executed in the correct order.
957 So it is possible that other static destructors might want to
958 write to cout - and they're supposed to be able to do so.
960 The following will make the standard streambufs be unbuffered,
961 which forces any output from late destructors to be written out. */
962 _IO_unbuffer_all ();
964 return result;
968 void
969 _IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp)
971 marker->_sbuf = fp;
972 if (_IO_in_put_mode (fp))
973 _IO_switch_to_get_mode (fp);
974 if (_IO_in_backup (fp))
975 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
976 else
977 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
979 /* Should perhaps sort the chain? */
980 marker->_next = fp->_markers;
981 fp->_markers = marker;
984 void
985 _IO_remove_marker (struct _IO_marker *marker)
987 /* Unlink from sb's chain. */
988 struct _IO_marker **ptr = &marker->_sbuf->_markers;
989 for (; ; ptr = &(*ptr)->_next)
991 if (*ptr == NULL)
992 break;
993 else if (*ptr == marker)
995 *ptr = marker->_next;
996 return;
999 #if 0
1000 if _sbuf has a backup area that is no longer needed, should we delete
1001 it now, or wait until the next underflow?
1002 #endif
1005 #define BAD_DELTA EOF
1008 _IO_marker_difference (struct _IO_marker *mark1, struct _IO_marker *mark2)
1010 return mark1->_pos - mark2->_pos;
1013 /* Return difference between MARK and current position of MARK's stream. */
1015 _IO_marker_delta (struct _IO_marker *mark)
1017 int cur_pos;
1018 if (mark->_sbuf == NULL)
1019 return BAD_DELTA;
1020 if (_IO_in_backup (mark->_sbuf))
1021 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1022 else
1023 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1024 return mark->_pos - cur_pos;
1028 _IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta)
1030 if (mark->_sbuf != fp)
1031 return EOF;
1032 if (mark->_pos >= 0)
1034 if (_IO_in_backup (fp))
1035 _IO_switch_to_main_get_area (fp);
1036 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1038 else
1040 if (!_IO_in_backup (fp))
1041 _IO_switch_to_backup_area (fp);
1042 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1044 return 0;
1047 void
1048 _IO_unsave_markers (_IO_FILE *fp)
1050 struct _IO_marker *mark = fp->_markers;
1051 if (mark)
1053 #ifdef TODO
1054 streampos offset = seekoff (0, ios::cur, ios::in);
1055 if (offset != EOF)
1057 offset += eGptr () - Gbase ();
1058 for ( ; mark != NULL; mark = mark->_next)
1059 mark->set_streampos (mark->_pos + offset);
1061 else
1063 for ( ; mark != NULL; mark = mark->_next)
1064 mark->set_streampos (EOF);
1066 #endif
1067 fp->_markers = 0;
1070 if (_IO_have_backup (fp))
1071 _IO_free_backup_area (fp);
1073 libc_hidden_def (_IO_unsave_markers)
1075 #if 0
1076 /* Seems not to be needed. --drepper */
1078 _IO_nobackup_pbackfail (_IO_FILE *fp, int c)
1080 if (fp->_IO_read_ptr > fp->_IO_read_base)
1081 fp->_IO_read_ptr--;
1082 if (c != EOF && *fp->_IO_read_ptr != c)
1083 *fp->_IO_read_ptr = c;
1084 return (unsigned char) c;
1086 #endif
1089 _IO_default_pbackfail (_IO_FILE *fp, int c)
1091 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1092 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1093 --fp->_IO_read_ptr;
1094 else
1096 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1097 if (!_IO_in_backup (fp))
1099 /* We need to keep the invariant that the main get area
1100 logically follows the backup area. */
1101 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1103 if (save_for_backup (fp, fp->_IO_read_ptr))
1104 return EOF;
1106 else if (!_IO_have_backup (fp))
1108 /* No backup buffer: allocate one. */
1109 /* Use nshort buffer, if unused? (probably not) FIXME */
1110 int backup_size = 128;
1111 char *bbuf = (char *) malloc (backup_size);
1112 if (bbuf == NULL)
1113 return EOF;
1114 fp->_IO_save_base = bbuf;
1115 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1116 fp->_IO_backup_base = fp->_IO_save_end;
1118 fp->_IO_read_base = fp->_IO_read_ptr;
1119 _IO_switch_to_backup_area (fp);
1121 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1123 /* Increase size of existing backup buffer. */
1124 _IO_size_t new_size;
1125 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1126 char *new_buf;
1127 new_size = 2 * old_size;
1128 new_buf = (char *) malloc (new_size);
1129 if (new_buf == NULL)
1130 return EOF;
1131 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1132 old_size);
1133 free (fp->_IO_read_base);
1134 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1135 new_buf + new_size);
1136 fp->_IO_backup_base = fp->_IO_read_ptr;
1139 *--fp->_IO_read_ptr = c;
1141 return (unsigned char) c;
1143 libc_hidden_def (_IO_default_pbackfail)
1145 _IO_off64_t
1146 _IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
1148 return _IO_pos_BAD;
1152 _IO_default_stat (_IO_FILE *fp, void *st)
1154 return EOF;
1157 _IO_ssize_t
1158 _IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n)
1160 return -1;
1163 _IO_ssize_t
1164 _IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n)
1166 return 0;
1170 _IO_default_showmanyc (_IO_FILE *fp)
1172 return -1;
1175 void
1176 _IO_default_imbue (_IO_FILE *fp, void *locale)
1180 _IO_ITER
1181 _IO_iter_begin (void)
1183 return (_IO_ITER) _IO_list_all;
1185 libc_hidden_def (_IO_iter_begin)
1187 _IO_ITER
1188 _IO_iter_end (void)
1190 return NULL;
1192 libc_hidden_def (_IO_iter_end)
1194 _IO_ITER
1195 _IO_iter_next (_IO_ITER iter)
1197 return iter->_chain;
1199 libc_hidden_def (_IO_iter_next)
1201 _IO_FILE *
1202 _IO_iter_file (_IO_ITER iter)
1204 return iter;
1206 libc_hidden_def (_IO_iter_file)
1208 void
1209 _IO_list_lock (void)
1211 #ifdef _IO_MTSAFE_IO
1212 _IO_lock_lock (list_all_lock);
1213 #endif
1215 libc_hidden_def (_IO_list_lock)
1217 void
1218 _IO_list_unlock (void)
1220 #ifdef _IO_MTSAFE_IO
1221 _IO_lock_unlock (list_all_lock);
1222 #endif
1224 libc_hidden_def (_IO_list_unlock)
1226 void
1227 _IO_list_resetlock (void)
1229 #ifdef _IO_MTSAFE_IO
1230 _IO_lock_init (list_all_lock);
1231 #endif
1233 libc_hidden_def (_IO_list_resetlock)
1236 #ifdef TODO
1237 #if defined(linux)
1238 #define IO_CLEANUP ;
1239 #endif
1241 #ifdef IO_CLEANUP
1242 IO_CLEANUP
1243 #else
1244 struct __io_defs {
1245 __io_defs() { }
1246 ~__io_defs() { _IO_cleanup (); }
1248 __io_defs io_defs__;
1249 #endif
1251 #endif /* TODO */
1253 #ifdef text_set_element
1254 text_set_element(__libc_atexit, _IO_cleanup);
1255 #endif