Update.
[glibc.git] / libio / genops.c
blob5f16894505c7634707406ce5670329b33931a1ce
1 /* Copyright (C) 1993,1995,1997-2001,2002 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, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
19 As a special exception, if you link the code in this file with
20 files compiled with a GNU compiler to produce an executable,
21 that does not cause the resulting executable to be covered by
22 the GNU Lesser General Public License. This exception does not
23 however invalidate any other reasons why the executable file
24 might be covered by the GNU Lesser General Public License.
25 This exception applies to code released by its copyright holders
26 in files containing the exception. */
28 /* Generic or default I/O operations. */
30 #include "libioP.h"
31 #ifdef __STDC__
32 #include <stdlib.h>
33 #endif
34 #include <string.h>
36 #ifdef _IO_MTSAFE_IO
37 static _IO_lock_t list_all_lock = _IO_lock_initializer;
38 #endif
40 /* Used to signal modifications to the list of FILE decriptors. */
41 static int _IO_list_all_stamp;
44 static _IO_FILE *run_fp;
46 static void
47 flush_cleanup (void *not_used)
49 if (run_fp != NULL)
50 _IO_funlockfile (run_fp);
51 #ifdef _IO_MTSAFE_IO
52 _IO_lock_unlock (list_all_lock);
53 #endif
56 void
57 _IO_un_link (fp)
58 struct _IO_FILE_plus *fp;
60 if (fp->file._flags & _IO_LINKED)
62 struct _IO_FILE_plus **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 for (f = &INTUSE(_IO_list_all); *f;
70 f = (struct _IO_FILE_plus **) &(*f)->file._chain)
72 if (*f == fp)
74 *f = (struct _IO_FILE_plus *) fp->file._chain;
75 ++_IO_list_all_stamp;
76 break;
79 fp->file._flags &= ~_IO_LINKED;
80 #ifdef _IO_MTSAFE_IO
81 _IO_funlockfile ((_IO_FILE *) fp);
82 run_fp = NULL;
83 _IO_lock_unlock (list_all_lock);
84 _IO_cleanup_region_end (0);
85 #endif
88 INTDEF(_IO_un_link)
90 void
91 _IO_link_in (fp)
92 struct _IO_FILE_plus *fp;
94 if ((fp->file._flags & _IO_LINKED) == 0)
96 fp->file._flags |= _IO_LINKED;
97 #ifdef _IO_MTSAFE_IO
98 _IO_cleanup_region_start_noarg (flush_cleanup);
99 _IO_lock_lock (list_all_lock);
100 run_fp = (_IO_FILE *) fp;
101 _IO_flockfile ((_IO_FILE *) fp);
102 #endif
103 fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
104 INTUSE(_IO_list_all) = fp;
105 ++_IO_list_all_stamp;
106 #ifdef _IO_MTSAFE_IO
107 _IO_funlockfile ((_IO_FILE *) fp);
108 run_fp = NULL;
109 _IO_lock_unlock (list_all_lock);
110 _IO_cleanup_region_end (0);
111 #endif
114 INTDEF(_IO_link_in)
116 /* Return minimum _pos markers
117 Assumes the current get area is the main get area. */
118 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
120 _IO_ssize_t
121 _IO_least_marker (fp, end_p)
122 _IO_FILE *fp;
123 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 (fp)
137 _IO_FILE *fp;
139 char *tmp;
140 fp->_flags &= ~_IO_IN_BACKUP;
141 /* Swap _IO_read_end and _IO_save_end. */
142 tmp = fp->_IO_read_end;
143 fp->_IO_read_end = fp->_IO_save_end;
144 fp->_IO_save_end= tmp;
145 /* Swap _IO_read_base and _IO_save_base. */
146 tmp = fp->_IO_read_base;
147 fp->_IO_read_base = fp->_IO_save_base;
148 fp->_IO_save_base = tmp;
149 /* Set _IO_read_ptr. */
150 fp->_IO_read_ptr = fp->_IO_read_base;
153 /* Switch current get area from main get area to (end of) backup area. */
155 void
156 _IO_switch_to_backup_area (fp)
157 _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 (fp)
175 _IO_FILE *fp;
177 if (fp->_IO_write_ptr > fp->_IO_write_base)
178 if (_IO_OVERFLOW (fp, EOF) == EOF)
179 return EOF;
180 if (_IO_in_backup (fp))
181 fp->_IO_read_base = fp->_IO_backup_base;
182 else
184 fp->_IO_read_base = fp->_IO_buf_base;
185 if (fp->_IO_write_ptr > fp->_IO_read_end)
186 fp->_IO_read_end = fp->_IO_write_ptr;
188 fp->_IO_read_ptr = fp->_IO_write_ptr;
190 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
192 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
193 return 0;
195 INTDEF(_IO_switch_to_get_mode)
197 void
198 _IO_free_backup_area (fp)
199 _IO_FILE *fp;
201 if (_IO_in_backup (fp))
202 _IO_switch_to_main_get_area (fp); /* Just in case. */
203 free (fp->_IO_save_base);
204 fp->_IO_save_base = NULL;
205 fp->_IO_save_end = NULL;
206 fp->_IO_backup_base = NULL;
208 INTDEF(_IO_free_backup_area)
210 #if 0
212 _IO_switch_to_put_mode (fp)
213 _IO_FILE *fp;
215 fp->_IO_write_base = fp->_IO_read_ptr;
216 fp->_IO_write_ptr = fp->_IO_read_ptr;
217 /* Following is wrong if line- or un-buffered? */
218 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
219 ? fp->_IO_read_end : fp->_IO_buf_end);
221 fp->_IO_read_ptr = fp->_IO_read_end;
222 fp->_IO_read_base = fp->_IO_read_end;
224 fp->_flags |= _IO_CURRENTLY_PUTTING;
225 return 0;
227 #endif
230 __overflow (f, ch)
231 _IO_FILE *f;
232 int ch;
234 /* This is a single-byte stream. */
235 if (f->_mode == 0)
236 _IO_fwide (f, -1);
237 return _IO_OVERFLOW (f, ch);
240 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
241 #ifdef _LIBC
242 internal_function
243 #endif
246 static int
247 #ifdef _LIBC
248 internal_function
249 #endif
250 save_for_backup (fp, end_p)
251 _IO_FILE *fp;
252 char *end_p;
254 /* Append [_IO_read_base..end_p] to backup area. */
255 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
256 /* needed_size is how much space we need in the backup area. */
257 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
258 /* FIXME: Dubious arithmetic if pointers are NULL */
259 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
260 _IO_size_t avail; /* Extra space available for future expansion. */
261 _IO_ssize_t delta;
262 struct _IO_marker *mark;
263 if (needed_size > current_Bsize)
265 char *new_buffer;
266 avail = 100;
267 new_buffer = (char *) malloc (avail + needed_size);
268 if (new_buffer == NULL)
269 return EOF; /* FIXME */
270 if (least_mark < 0)
272 #ifdef _LIBC
273 __mempcpy (__mempcpy (new_buffer + avail,
274 fp->_IO_save_end + least_mark,
275 -least_mark),
276 fp->_IO_read_base,
277 end_p - fp->_IO_read_base);
278 #else
279 memcpy (new_buffer + avail,
280 fp->_IO_save_end + least_mark,
281 -least_mark);
282 memcpy (new_buffer + avail - least_mark,
283 fp->_IO_read_base,
284 end_p - fp->_IO_read_base);
285 #endif
287 else
288 memcpy (new_buffer + avail,
289 fp->_IO_read_base + least_mark,
290 needed_size);
291 if (fp->_IO_save_base)
292 free (fp->_IO_save_base);
293 fp->_IO_save_base = new_buffer;
294 fp->_IO_save_end = new_buffer + avail + needed_size;
296 else
298 avail = current_Bsize - needed_size;
299 if (least_mark < 0)
301 memmove (fp->_IO_save_base + avail,
302 fp->_IO_save_end + least_mark,
303 -least_mark);
304 memcpy (fp->_IO_save_base + avail - least_mark,
305 fp->_IO_read_base,
306 end_p - fp->_IO_read_base);
308 else if (needed_size > 0)
309 memcpy (fp->_IO_save_base + avail,
310 fp->_IO_read_base + least_mark,
311 needed_size);
313 fp->_IO_backup_base = fp->_IO_save_base + avail;
314 /* Adjust all the streammarkers. */
315 delta = end_p - fp->_IO_read_base;
316 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
317 mark->_pos -= delta;
318 return 0;
322 __underflow (fp)
323 _IO_FILE *fp;
325 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
326 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
327 return EOF;
328 #endif
330 if (fp->_mode == 0)
331 _IO_fwide (fp, -1);
332 if (_IO_in_put_mode (fp))
333 if (INTUSE(_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 INTUSE(_IO_free_backup_area) (fp);
350 return _IO_UNDERFLOW (fp);
354 __uflow (fp)
355 _IO_FILE *fp;
357 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
358 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
359 return EOF;
360 #endif
362 if (fp->_mode == 0)
363 _IO_fwide (fp, -11);
364 if (_IO_in_put_mode (fp))
365 if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
366 return EOF;
367 if (fp->_IO_read_ptr < fp->_IO_read_end)
368 return *(unsigned char *) fp->_IO_read_ptr++;
369 if (_IO_in_backup (fp))
371 _IO_switch_to_main_get_area (fp);
372 if (fp->_IO_read_ptr < fp->_IO_read_end)
373 return *(unsigned char *) fp->_IO_read_ptr++;
375 if (_IO_have_markers (fp))
377 if (save_for_backup (fp, fp->_IO_read_end))
378 return EOF;
380 else if (_IO_have_backup (fp))
381 INTUSE(_IO_free_backup_area) (fp);
382 return _IO_UFLOW (fp);
385 void
386 _IO_setb (f, b, eb, a)
387 _IO_FILE *f;
388 char *b;
389 char *eb;
390 int a;
392 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
393 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
394 f->_IO_buf_base = b;
395 f->_IO_buf_end = eb;
396 if (a)
397 f->_flags &= ~_IO_USER_BUF;
398 else
399 f->_flags |= _IO_USER_BUF;
401 INTDEF(_IO_setb)
403 void
404 _IO_doallocbuf (fp)
405 _IO_FILE *fp;
407 if (fp->_IO_buf_base)
408 return;
409 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
410 if (_IO_DOALLOCATE (fp) != EOF)
411 return;
412 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
414 INTDEF(_IO_doallocbuf)
417 _IO_default_underflow (fp)
418 _IO_FILE *fp;
420 return EOF;
424 _IO_default_uflow (fp)
425 _IO_FILE *fp;
427 int ch = _IO_UNDERFLOW (fp);
428 if (ch == EOF)
429 return EOF;
430 return *(unsigned char *) fp->_IO_read_ptr++;
432 INTDEF(_IO_default_uflow)
434 _IO_size_t
435 _IO_default_xsputn (f, data, n)
436 _IO_FILE *f;
437 const void *data;
438 _IO_size_t n;
440 const char *s = (char *) data;
441 _IO_size_t more = n;
442 if (more <= 0)
443 return 0;
444 for (;;)
446 /* Space available. */
447 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
448 if (count > 0)
450 if ((_IO_size_t) count > more)
451 count = more;
452 if (count > 20)
454 #ifdef _LIBC
455 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
456 #else
457 memcpy (f->_IO_write_ptr, s, count);
458 f->_IO_write_ptr += count;
459 #endif
460 s += count;
462 else if (count <= 0)
463 count = 0;
464 else
466 char *p = f->_IO_write_ptr;
467 _IO_ssize_t i;
468 for (i = count; --i >= 0; )
469 *p++ = *s++;
470 f->_IO_write_ptr = p;
472 more -= count;
474 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
475 break;
476 more--;
478 return n - more;
480 INTDEF(_IO_default_xsputn)
482 _IO_size_t
483 _IO_sgetn (fp, data, n)
484 _IO_FILE *fp;
485 void *data;
486 _IO_size_t n;
488 /* FIXME handle putback buffer here! */
489 return _IO_XSGETN (fp, data, n);
491 INTDEF(_IO_sgetn)
493 _IO_size_t
494 _IO_default_xsgetn (fp, data, n)
495 _IO_FILE *fp;
496 void *data;
497 _IO_size_t n;
499 _IO_size_t more = n;
500 char *s = (char*) data;
501 for (;;)
503 /* Data available. */
504 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
505 if (count > 0)
507 if ((_IO_size_t) count > more)
508 count = more;
509 if (count > 20)
511 #ifdef _LIBC
512 s = __mempcpy (s, fp->_IO_read_ptr, count);
513 #else
514 memcpy (s, fp->_IO_read_ptr, count);
515 s += count;
516 #endif
517 fp->_IO_read_ptr += count;
519 else if (count <= 0)
520 count = 0;
521 else
523 char *p = fp->_IO_read_ptr;
524 int i = (int) count;
525 while (--i >= 0)
526 *s++ = *p++;
527 fp->_IO_read_ptr = p;
529 more -= count;
531 if (more == 0 || __underflow (fp) == EOF)
532 break;
534 return n - more;
536 INTDEF(_IO_default_xsgetn)
538 #if 0
539 /* Seems not to be needed. --drepper */
541 _IO_sync (fp)
542 _IO_FILE *fp;
544 return 0;
546 #endif
548 _IO_FILE *
549 _IO_default_setbuf (fp, p, len)
550 _IO_FILE *fp;
551 char *p;
552 _IO_ssize_t len;
554 if (_IO_SYNC (fp) == EOF)
555 return NULL;
556 if (p == NULL || len == 0)
558 fp->_flags |= _IO_UNBUFFERED;
559 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
561 else
563 fp->_flags &= ~_IO_UNBUFFERED;
564 INTUSE(_IO_setb) (fp, p, p+len, 0);
566 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
567 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
568 return fp;
571 _IO_off64_t
572 _IO_default_seekpos (fp, pos, mode)
573 _IO_FILE *fp;
574 _IO_off64_t pos;
575 int mode;
577 return _IO_SEEKOFF (fp, pos, 0, mode);
581 _IO_default_doallocate (fp)
582 _IO_FILE *fp;
584 char *buf;
586 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
587 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
588 return 1;
590 INTDEF(_IO_default_doallocate)
592 void
593 _IO_init (fp, flags)
594 _IO_FILE *fp;
595 int flags;
597 _IO_no_init (fp, flags, -1, NULL, NULL);
599 INTDEF(_IO_init)
601 void
602 _IO_no_init (fp, flags, orientation, wd, jmp)
603 _IO_FILE *fp;
604 int flags;
605 int orientation;
606 struct _IO_wide_data *wd;
607 struct _IO_jump_t *jmp;
609 fp->_flags = _IO_MAGIC|flags;
610 fp->_IO_buf_base = NULL;
611 fp->_IO_buf_end = NULL;
612 fp->_IO_read_base = NULL;
613 fp->_IO_read_ptr = NULL;
614 fp->_IO_read_end = NULL;
615 fp->_IO_write_base = NULL;
616 fp->_IO_write_ptr = NULL;
617 fp->_IO_write_end = NULL;
618 fp->_chain = NULL; /* Not necessary. */
620 fp->_IO_save_base = NULL;
621 fp->_IO_backup_base = NULL;
622 fp->_IO_save_end = NULL;
623 fp->_markers = NULL;
624 fp->_cur_column = 0;
625 #if _IO_JUMPS_OFFSET
626 fp->_vtable_offset = 0;
627 #endif
628 #ifdef _IO_MTSAFE_IO
629 if (fp->_lock != NULL)
630 _IO_lock_init (*fp->_lock);
631 #endif
632 fp->_mode = orientation;
633 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
634 if (orientation >= 0)
636 fp->_wide_data = wd;
637 fp->_wide_data->_IO_buf_base = NULL;
638 fp->_wide_data->_IO_buf_end = NULL;
639 fp->_wide_data->_IO_read_base = NULL;
640 fp->_wide_data->_IO_read_ptr = NULL;
641 fp->_wide_data->_IO_read_end = NULL;
642 fp->_wide_data->_IO_write_base = NULL;
643 fp->_wide_data->_IO_write_ptr = NULL;
644 fp->_wide_data->_IO_write_end = NULL;
645 fp->_wide_data->_IO_save_base = NULL;
646 fp->_wide_data->_IO_backup_base = NULL;
647 fp->_wide_data->_IO_save_end = NULL;
649 fp->_wide_data->_wide_vtable = jmp;
651 #endif
655 _IO_default_sync (fp)
656 _IO_FILE *fp;
658 return 0;
661 /* The way the C++ classes are mapped into the C functions in the
662 current implementation, this function can get called twice! */
664 void
665 _IO_default_finish (fp, dummy)
666 _IO_FILE *fp;
667 int dummy;
669 struct _IO_marker *mark;
670 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
672 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
673 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
676 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
677 mark->_sbuf = NULL;
679 if (fp->_IO_save_base)
681 free (fp->_IO_save_base);
682 fp->_IO_save_base = NULL;
685 #ifdef _IO_MTSAFE_IO
686 if (fp->_lock != NULL)
687 _IO_lock_fini (*fp->_lock);
688 #endif
690 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
692 INTDEF(_IO_default_finish)
694 _IO_off64_t
695 _IO_default_seekoff (fp, offset, dir, mode)
696 _IO_FILE *fp;
697 _IO_off64_t offset;
698 int dir;
699 int mode;
701 return _IO_pos_BAD;
705 _IO_sputbackc (fp, c)
706 _IO_FILE *fp;
707 int c;
709 int result;
711 if (fp->_IO_read_ptr > fp->_IO_read_base
712 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
714 fp->_IO_read_ptr--;
715 result = (unsigned char) c;
717 else
718 result = _IO_PBACKFAIL (fp, c);
720 if (result != EOF)
721 fp->_flags &= ~_IO_EOF_SEEN;
723 return result;
725 INTDEF(_IO_sputbackc)
728 _IO_sungetc (fp)
729 _IO_FILE *fp;
731 int result;
733 if (fp->_IO_read_ptr > fp->_IO_read_base)
735 fp->_IO_read_ptr--;
736 result = (unsigned char) *fp->_IO_read_ptr;
738 else
739 result = _IO_PBACKFAIL (fp, EOF);
741 if (result != EOF)
742 fp->_flags &= ~_IO_EOF_SEEN;
744 return result;
747 #if 0 /* Work in progress */
748 /* Seems not to be needed. */
749 #if 0
750 void
751 _IO_set_column (fp, c)
752 _IO_FILE *fp;
753 int c;
755 if (c == -1)
756 fp->_column = -1;
757 else
758 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
760 #else
762 _IO_set_column (fp, i)
763 _IO_FILE *fp;
764 int i;
766 fp->_cur_column = i + 1;
767 return 0;
769 #endif
770 #endif
773 unsigned
774 _IO_adjust_column (start, line, count)
775 unsigned start;
776 const char *line;
777 int count;
779 const char *ptr = line + count;
780 while (ptr > line)
781 if (*--ptr == '\n')
782 return line + count - ptr - 1;
783 return start + count;
785 INTDEF(_IO_adjust_column)
787 #if 0
788 /* Seems not to be needed. --drepper */
790 _IO_get_column (fp)
791 _IO_FILE *fp;
793 if (fp->_cur_column)
794 return _IO_adjust_column (fp->_cur_column - 1,
795 fp->_IO_write_base,
796 fp->_IO_write_ptr - fp->_IO_write_base);
797 return -1;
799 #endif
803 _IO_flush_all_lockp (int do_lock)
805 int result = 0;
806 struct _IO_FILE *fp;
807 int last_stamp;
809 #ifdef _IO_MTSAFE_IO
810 _IO_cleanup_region_start_noarg (flush_cleanup);
811 if (do_lock)
812 _IO_lock_lock (list_all_lock);
813 #endif
815 last_stamp = _IO_list_all_stamp;
816 fp = (_IO_FILE *) INTUSE(_IO_list_all);
817 while (fp != NULL)
819 run_fp = fp;
820 if (do_lock)
821 _IO_flockfile (fp);
823 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
824 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
825 || (fp->_vtable_offset == 0
826 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
827 > fp->_wide_data->_IO_write_base))
828 #endif
830 && _IO_OVERFLOW (fp, EOF) == EOF)
831 result = EOF;
833 if (do_lock)
834 _IO_funlockfile (fp);
835 run_fp = NULL;
837 if (last_stamp != _IO_list_all_stamp)
839 /* Something was added to the list. Start all over again. */
840 fp = (_IO_FILE *) INTUSE(_IO_list_all);
841 last_stamp = _IO_list_all_stamp;
843 else
844 fp = fp->_chain;
847 #ifdef _IO_MTSAFE_IO
848 if (do_lock)
849 _IO_lock_unlock (list_all_lock);
850 _IO_cleanup_region_end (0);
851 #endif
853 return result;
858 _IO_flush_all ()
860 /* We want locking. */
861 return _IO_flush_all_lockp (1);
863 INTDEF(_IO_flush_all)
865 void
866 _IO_flush_all_linebuffered ()
868 struct _IO_FILE *fp;
869 int last_stamp;
871 #ifdef _IO_MTSAFE_IO
872 _IO_cleanup_region_start_noarg (flush_cleanup);
873 _IO_lock_lock (list_all_lock);
874 #endif
876 last_stamp = _IO_list_all_stamp;
877 fp = (_IO_FILE *) INTUSE(_IO_list_all);
878 while (fp != NULL)
880 run_fp = fp;
881 _IO_flockfile (fp);
883 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
884 _IO_OVERFLOW (fp, EOF);
886 _IO_funlockfile (fp);
887 run_fp = NULL;
889 if (last_stamp != _IO_list_all_stamp)
891 /* Something was added to the list. Start all over again. */
892 fp = (_IO_FILE *) INTUSE(_IO_list_all);
893 last_stamp = _IO_list_all_stamp;
895 else
896 fp = fp->_chain;
899 #ifdef _IO_MTSAFE_IO
900 _IO_lock_unlock (list_all_lock);
901 _IO_cleanup_region_end (0);
902 #endif
904 INTDEF(_IO_flush_all_linebuffered)
905 #ifdef _LIBC
906 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
907 #endif
909 static void _IO_unbuffer_write __P ((void));
911 static void
912 _IO_unbuffer_write ()
914 struct _IO_FILE *fp;
915 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
917 if (! (fp->_flags & _IO_UNBUFFERED)
918 && (! (fp->_flags & _IO_NO_WRITES)
919 || (fp->_flags & _IO_IS_APPENDING))
920 /* Iff stream is un-orientated, it wasn't used. */
921 && fp->_mode != 0)
922 _IO_SETBUF (fp, NULL, 0);
924 /* Make sure that never again the wide char functions can be
925 used. */
926 fp->_mode = -1;
931 _IO_cleanup ()
933 int result = INTUSE(_IO_flush_all) ();
935 /* We currently don't have a reliable mechanism for making sure that
936 C++ static destructors are executed in the correct order.
937 So it is possible that other static destructors might want to
938 write to cout - and they're supposed to be able to do so.
940 The following will make the standard streambufs be unbuffered,
941 which forces any output from late destructors to be written out. */
942 _IO_unbuffer_write ();
944 return result;
948 void
949 _IO_init_marker (marker, fp)
950 struct _IO_marker *marker;
951 _IO_FILE *fp;
953 marker->_sbuf = fp;
954 if (_IO_in_put_mode (fp))
955 INTUSE(_IO_switch_to_get_mode) (fp);
956 if (_IO_in_backup (fp))
957 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
958 else
959 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
961 /* Should perhaps sort the chain? */
962 marker->_next = fp->_markers;
963 fp->_markers = marker;
966 void
967 _IO_remove_marker (marker)
968 struct _IO_marker *marker;
970 /* Unlink from sb's chain. */
971 struct _IO_marker **ptr = &marker->_sbuf->_markers;
972 for (; ; ptr = &(*ptr)->_next)
974 if (*ptr == NULL)
975 break;
976 else if (*ptr == marker)
978 *ptr = marker->_next;
979 return;
982 #if 0
983 if _sbuf has a backup area that is no longer needed, should we delete
984 it now, or wait until the next underflow?
985 #endif
988 #define BAD_DELTA EOF
991 _IO_marker_difference (mark1, mark2)
992 struct _IO_marker *mark1;
993 struct _IO_marker *mark2;
995 return mark1->_pos - mark2->_pos;
998 /* Return difference between MARK and current position of MARK's stream. */
1000 _IO_marker_delta (mark)
1001 struct _IO_marker *mark;
1003 int cur_pos;
1004 if (mark->_sbuf == NULL)
1005 return BAD_DELTA;
1006 if (_IO_in_backup (mark->_sbuf))
1007 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1008 else
1009 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1010 return mark->_pos - cur_pos;
1014 _IO_seekmark (fp, mark, delta)
1015 _IO_FILE *fp;
1016 struct _IO_marker *mark;
1017 int delta;
1019 if (mark->_sbuf != fp)
1020 return EOF;
1021 if (mark->_pos >= 0)
1023 if (_IO_in_backup (fp))
1024 _IO_switch_to_main_get_area (fp);
1025 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1027 else
1029 if (!_IO_in_backup (fp))
1030 _IO_switch_to_backup_area (fp);
1031 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1033 return 0;
1036 void
1037 _IO_unsave_markers (fp)
1038 _IO_FILE *fp;
1040 struct _IO_marker *mark = fp->_markers;
1041 if (mark)
1043 #ifdef TODO
1044 streampos offset = seekoff (0, ios::cur, ios::in);
1045 if (offset != EOF)
1047 offset += eGptr () - Gbase ();
1048 for ( ; mark != NULL; mark = mark->_next)
1049 mark->set_streampos (mark->_pos + offset);
1051 else
1053 for ( ; mark != NULL; mark = mark->_next)
1054 mark->set_streampos (EOF);
1056 #endif
1057 fp->_markers = 0;
1060 if (_IO_have_backup (fp))
1061 INTUSE(_IO_free_backup_area) (fp);
1063 INTDEF(_IO_unsave_markers)
1065 #if 0
1066 /* Seems not to be needed. --drepper */
1068 _IO_nobackup_pbackfail (fp, c)
1069 _IO_FILE *fp;
1070 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 (fp, c)
1082 _IO_FILE *fp;
1083 int c;
1085 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1086 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1087 --fp->_IO_read_ptr;
1088 else
1090 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1091 if (!_IO_in_backup (fp))
1093 /* We need to keep the invariant that the main get area
1094 logically follows the backup area. */
1095 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1097 if (save_for_backup (fp, fp->_IO_read_ptr))
1098 return EOF;
1100 else if (!_IO_have_backup (fp))
1102 /* No backup buffer: allocate one. */
1103 /* Use nshort buffer, if unused? (probably not) FIXME */
1104 int backup_size = 128;
1105 char *bbuf = (char *) malloc (backup_size);
1106 if (bbuf == NULL)
1107 return EOF;
1108 fp->_IO_save_base = bbuf;
1109 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1110 fp->_IO_backup_base = fp->_IO_save_end;
1112 fp->_IO_read_base = fp->_IO_read_ptr;
1113 _IO_switch_to_backup_area (fp);
1115 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1117 /* Increase size of existing backup buffer. */
1118 _IO_size_t new_size;
1119 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1120 char *new_buf;
1121 new_size = 2 * old_size;
1122 new_buf = (char *) malloc (new_size);
1123 if (new_buf == NULL)
1124 return EOF;
1125 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1126 old_size);
1127 free (fp->_IO_read_base);
1128 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1129 new_buf + new_size);
1130 fp->_IO_backup_base = fp->_IO_read_ptr;
1133 *--fp->_IO_read_ptr = c;
1135 return (unsigned char) c;
1137 INTDEF(_IO_default_pbackfail)
1139 _IO_off64_t
1140 _IO_default_seek (fp, offset, dir)
1141 _IO_FILE *fp;
1142 _IO_off64_t offset;
1143 int dir;
1145 return _IO_pos_BAD;
1149 _IO_default_stat (fp, st)
1150 _IO_FILE *fp;
1151 void* st;
1153 return EOF;
1156 _IO_ssize_t
1157 _IO_default_read (fp, data, n)
1158 _IO_FILE* fp;
1159 void *data;
1160 _IO_ssize_t n;
1162 return -1;
1165 _IO_ssize_t
1166 _IO_default_write (fp, data, n)
1167 _IO_FILE *fp;
1168 const void *data;
1169 _IO_ssize_t n;
1171 return 0;
1175 _IO_default_showmanyc (fp)
1176 _IO_FILE *fp;
1178 return -1;
1181 void
1182 _IO_default_imbue (fp, locale)
1183 _IO_FILE *fp;
1184 void *locale;
1188 _IO_ITER
1189 _IO_iter_begin()
1191 return (_IO_ITER) INTUSE(_IO_list_all);
1194 _IO_ITER
1195 _IO_iter_end()
1197 return NULL;
1200 _IO_ITER
1201 _IO_iter_next(iter)
1202 _IO_ITER iter;
1204 return iter->_chain;
1207 _IO_FILE *
1208 _IO_iter_file(iter)
1209 _IO_ITER iter;
1211 return iter;
1214 void
1215 _IO_list_lock()
1217 #ifdef _IO_MTSAFE_IO
1218 _IO_lock_lock (list_all_lock);
1219 #endif
1222 void
1223 _IO_list_unlock()
1225 #ifdef _IO_MTSAFE_IO
1226 _IO_lock_unlock (list_all_lock);
1227 #endif
1230 void
1231 _IO_list_resetlock()
1233 #ifdef _IO_MTSAFE_IO
1234 _IO_lock_init (list_all_lock);
1235 #endif
1239 #ifdef TODO
1240 #if defined(linux)
1241 #define IO_CLEANUP ;
1242 #endif
1244 #ifdef IO_CLEANUP
1245 IO_CLEANUP
1246 #else
1247 struct __io_defs {
1248 __io_defs() { }
1249 ~__io_defs() { _IO_cleanup (); }
1251 __io_defs io_defs__;
1252 #endif
1254 #endif /* TODO */
1256 #ifdef weak_alias
1257 weak_alias (_IO_cleanup, _cleanup)
1258 #endif
1260 #ifdef text_set_element
1261 text_set_element(__libc_atexit, _cleanup);
1262 #endif