2003-05-04 Roland McGrath <roland@redhat.com>
[glibc.git] / libio / genops.c
blobc88a26f5f9e39e340fdb07cf43db5ad67239fbd0
1 /* Copyright (C) 1993,1995,1997-2002, 2003 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);
239 libc_hidden_def (__overflow)
241 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
242 #ifdef _LIBC
243 internal_function
244 #endif
247 static int
248 #ifdef _LIBC
249 internal_function
250 #endif
251 save_for_backup (fp, end_p)
252 _IO_FILE *fp;
253 char *end_p;
255 /* Append [_IO_read_base..end_p] to backup area. */
256 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
257 /* needed_size is how much space we need in the backup area. */
258 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
259 /* FIXME: Dubious arithmetic if pointers are NULL */
260 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
261 _IO_size_t avail; /* Extra space available for future expansion. */
262 _IO_ssize_t delta;
263 struct _IO_marker *mark;
264 if (needed_size > current_Bsize)
266 char *new_buffer;
267 avail = 100;
268 new_buffer = (char *) malloc (avail + needed_size);
269 if (new_buffer == NULL)
270 return EOF; /* FIXME */
271 if (least_mark < 0)
273 #ifdef _LIBC
274 __mempcpy (__mempcpy (new_buffer + avail,
275 fp->_IO_save_end + least_mark,
276 -least_mark),
277 fp->_IO_read_base,
278 end_p - fp->_IO_read_base);
279 #else
280 memcpy (new_buffer + avail,
281 fp->_IO_save_end + least_mark,
282 -least_mark);
283 memcpy (new_buffer + avail - least_mark,
284 fp->_IO_read_base,
285 end_p - fp->_IO_read_base);
286 #endif
288 else
289 memcpy (new_buffer + avail,
290 fp->_IO_read_base + least_mark,
291 needed_size);
292 if (fp->_IO_save_base)
293 free (fp->_IO_save_base);
294 fp->_IO_save_base = new_buffer;
295 fp->_IO_save_end = new_buffer + avail + needed_size;
297 else
299 avail = current_Bsize - needed_size;
300 if (least_mark < 0)
302 memmove (fp->_IO_save_base + avail,
303 fp->_IO_save_end + least_mark,
304 -least_mark);
305 memcpy (fp->_IO_save_base + avail - least_mark,
306 fp->_IO_read_base,
307 end_p - fp->_IO_read_base);
309 else if (needed_size > 0)
310 memcpy (fp->_IO_save_base + avail,
311 fp->_IO_read_base + least_mark,
312 needed_size);
314 fp->_IO_backup_base = fp->_IO_save_base + avail;
315 /* Adjust all the streammarkers. */
316 delta = end_p - fp->_IO_read_base;
317 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
318 mark->_pos -= delta;
319 return 0;
323 __underflow (fp)
324 _IO_FILE *fp;
326 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
327 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
328 return EOF;
329 #endif
331 if (fp->_mode == 0)
332 _IO_fwide (fp, -1);
333 if (_IO_in_put_mode (fp))
334 if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
335 return EOF;
336 if (fp->_IO_read_ptr < fp->_IO_read_end)
337 return *(unsigned char *) fp->_IO_read_ptr;
338 if (_IO_in_backup (fp))
340 _IO_switch_to_main_get_area (fp);
341 if (fp->_IO_read_ptr < fp->_IO_read_end)
342 return *(unsigned char *) fp->_IO_read_ptr;
344 if (_IO_have_markers (fp))
346 if (save_for_backup (fp, fp->_IO_read_end))
347 return EOF;
349 else if (_IO_have_backup (fp))
350 INTUSE(_IO_free_backup_area) (fp);
351 return _IO_UNDERFLOW (fp);
353 libc_hidden_def (__underflow)
356 __uflow (fp)
357 _IO_FILE *fp;
359 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
360 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
361 return EOF;
362 #endif
364 if (fp->_mode == 0)
365 _IO_fwide (fp, -11);
366 if (_IO_in_put_mode (fp))
367 if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
368 return EOF;
369 if (fp->_IO_read_ptr < fp->_IO_read_end)
370 return *(unsigned char *) fp->_IO_read_ptr++;
371 if (_IO_in_backup (fp))
373 _IO_switch_to_main_get_area (fp);
374 if (fp->_IO_read_ptr < fp->_IO_read_end)
375 return *(unsigned char *) fp->_IO_read_ptr++;
377 if (_IO_have_markers (fp))
379 if (save_for_backup (fp, fp->_IO_read_end))
380 return EOF;
382 else if (_IO_have_backup (fp))
383 INTUSE(_IO_free_backup_area) (fp);
384 return _IO_UFLOW (fp);
386 libc_hidden_def (__uflow)
388 void
389 _IO_setb (f, b, eb, a)
390 _IO_FILE *f;
391 char *b;
392 char *eb;
393 int a;
395 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
396 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
397 f->_IO_buf_base = b;
398 f->_IO_buf_end = eb;
399 if (a)
400 f->_flags &= ~_IO_USER_BUF;
401 else
402 f->_flags |= _IO_USER_BUF;
404 INTDEF(_IO_setb)
406 void
407 _IO_doallocbuf (fp)
408 _IO_FILE *fp;
410 if (fp->_IO_buf_base)
411 return;
412 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
413 if (_IO_DOALLOCATE (fp) != EOF)
414 return;
415 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
417 INTDEF(_IO_doallocbuf)
420 _IO_default_underflow (fp)
421 _IO_FILE *fp;
423 return EOF;
427 _IO_default_uflow (fp)
428 _IO_FILE *fp;
430 int ch = _IO_UNDERFLOW (fp);
431 if (ch == EOF)
432 return EOF;
433 return *(unsigned char *) fp->_IO_read_ptr++;
435 INTDEF(_IO_default_uflow)
437 _IO_size_t
438 _IO_default_xsputn (f, data, n)
439 _IO_FILE *f;
440 const void *data;
441 _IO_size_t n;
443 const char *s = (char *) data;
444 _IO_size_t more = n;
445 if (more <= 0)
446 return 0;
447 for (;;)
449 /* Space available. */
450 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
451 if (count > 0)
453 if ((_IO_size_t) count > more)
454 count = more;
455 if (count > 20)
457 #ifdef _LIBC
458 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
459 #else
460 memcpy (f->_IO_write_ptr, s, count);
461 f->_IO_write_ptr += count;
462 #endif
463 s += count;
465 else if (count <= 0)
466 count = 0;
467 else
469 char *p = f->_IO_write_ptr;
470 _IO_ssize_t i;
471 for (i = count; --i >= 0; )
472 *p++ = *s++;
473 f->_IO_write_ptr = p;
475 more -= count;
477 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
478 break;
479 more--;
481 return n - more;
483 INTDEF(_IO_default_xsputn)
485 _IO_size_t
486 _IO_sgetn (fp, data, n)
487 _IO_FILE *fp;
488 void *data;
489 _IO_size_t n;
491 /* FIXME handle putback buffer here! */
492 return _IO_XSGETN (fp, data, n);
494 INTDEF(_IO_sgetn)
496 _IO_size_t
497 _IO_default_xsgetn (fp, data, n)
498 _IO_FILE *fp;
499 void *data;
500 _IO_size_t n;
502 _IO_size_t more = n;
503 char *s = (char*) data;
504 for (;;)
506 /* Data available. */
507 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
508 if (count > 0)
510 if ((_IO_size_t) count > more)
511 count = more;
512 if (count > 20)
514 #ifdef _LIBC
515 s = __mempcpy (s, fp->_IO_read_ptr, count);
516 #else
517 memcpy (s, fp->_IO_read_ptr, count);
518 s += count;
519 #endif
520 fp->_IO_read_ptr += count;
522 else if (count <= 0)
523 count = 0;
524 else
526 char *p = fp->_IO_read_ptr;
527 int i = (int) count;
528 while (--i >= 0)
529 *s++ = *p++;
530 fp->_IO_read_ptr = p;
532 more -= count;
534 if (more == 0 || __underflow (fp) == EOF)
535 break;
537 return n - more;
539 INTDEF(_IO_default_xsgetn)
541 #if 0
542 /* Seems not to be needed. --drepper */
544 _IO_sync (fp)
545 _IO_FILE *fp;
547 return 0;
549 #endif
551 _IO_FILE *
552 _IO_default_setbuf (fp, p, len)
553 _IO_FILE *fp;
554 char *p;
555 _IO_ssize_t len;
557 if (_IO_SYNC (fp) == EOF)
558 return NULL;
559 if (p == NULL || len == 0)
561 fp->_flags |= _IO_UNBUFFERED;
562 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
564 else
566 fp->_flags &= ~_IO_UNBUFFERED;
567 INTUSE(_IO_setb) (fp, p, p+len, 0);
569 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
570 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
571 return fp;
574 _IO_off64_t
575 _IO_default_seekpos (fp, pos, mode)
576 _IO_FILE *fp;
577 _IO_off64_t pos;
578 int mode;
580 return _IO_SEEKOFF (fp, pos, 0, mode);
584 _IO_default_doallocate (fp)
585 _IO_FILE *fp;
587 char *buf;
589 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
590 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
591 return 1;
593 INTDEF(_IO_default_doallocate)
595 void
596 _IO_init (fp, flags)
597 _IO_FILE *fp;
598 int flags;
600 _IO_no_init (fp, flags, -1, NULL, NULL);
602 INTDEF(_IO_init)
604 void
605 _IO_no_init (fp, flags, orientation, wd, jmp)
606 _IO_FILE *fp;
607 int flags;
608 int orientation;
609 struct _IO_wide_data *wd;
610 struct _IO_jump_t *jmp;
612 fp->_flags = _IO_MAGIC|flags;
613 fp->_flags2 = 0;
614 fp->_IO_buf_base = NULL;
615 fp->_IO_buf_end = NULL;
616 fp->_IO_read_base = NULL;
617 fp->_IO_read_ptr = NULL;
618 fp->_IO_read_end = NULL;
619 fp->_IO_write_base = NULL;
620 fp->_IO_write_ptr = NULL;
621 fp->_IO_write_end = NULL;
622 fp->_chain = NULL; /* Not necessary. */
624 fp->_IO_save_base = NULL;
625 fp->_IO_backup_base = NULL;
626 fp->_IO_save_end = NULL;
627 fp->_markers = NULL;
628 fp->_cur_column = 0;
629 #if _IO_JUMPS_OFFSET
630 fp->_vtable_offset = 0;
631 #endif
632 #ifdef _IO_MTSAFE_IO
633 if (fp->_lock != NULL)
634 _IO_lock_init (*fp->_lock);
635 #endif
636 fp->_mode = orientation;
637 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
638 if (orientation >= 0)
640 fp->_wide_data = wd;
641 fp->_wide_data->_IO_buf_base = NULL;
642 fp->_wide_data->_IO_buf_end = NULL;
643 fp->_wide_data->_IO_read_base = NULL;
644 fp->_wide_data->_IO_read_ptr = NULL;
645 fp->_wide_data->_IO_read_end = NULL;
646 fp->_wide_data->_IO_write_base = NULL;
647 fp->_wide_data->_IO_write_ptr = NULL;
648 fp->_wide_data->_IO_write_end = NULL;
649 fp->_wide_data->_IO_save_base = NULL;
650 fp->_wide_data->_IO_backup_base = NULL;
651 fp->_wide_data->_IO_save_end = NULL;
653 fp->_wide_data->_wide_vtable = jmp;
655 #endif
659 _IO_default_sync (fp)
660 _IO_FILE *fp;
662 return 0;
665 /* The way the C++ classes are mapped into the C functions in the
666 current implementation, this function can get called twice! */
668 void
669 _IO_default_finish (fp, dummy)
670 _IO_FILE *fp;
671 int dummy;
673 struct _IO_marker *mark;
674 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
676 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
677 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
680 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
681 mark->_sbuf = NULL;
683 if (fp->_IO_save_base)
685 free (fp->_IO_save_base);
686 fp->_IO_save_base = NULL;
689 #ifdef _IO_MTSAFE_IO
690 if (fp->_lock != NULL)
691 _IO_lock_fini (*fp->_lock);
692 #endif
694 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
696 INTDEF(_IO_default_finish)
698 _IO_off64_t
699 _IO_default_seekoff (fp, offset, dir, mode)
700 _IO_FILE *fp;
701 _IO_off64_t offset;
702 int dir;
703 int mode;
705 return _IO_pos_BAD;
709 _IO_sputbackc (fp, c)
710 _IO_FILE *fp;
711 int c;
713 int result;
715 if (fp->_IO_read_ptr > fp->_IO_read_base
716 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
718 fp->_IO_read_ptr--;
719 result = (unsigned char) c;
721 else
722 result = _IO_PBACKFAIL (fp, c);
724 if (result != EOF)
725 fp->_flags &= ~_IO_EOF_SEEN;
727 return result;
729 INTDEF(_IO_sputbackc)
732 _IO_sungetc (fp)
733 _IO_FILE *fp;
735 int result;
737 if (fp->_IO_read_ptr > fp->_IO_read_base)
739 fp->_IO_read_ptr--;
740 result = (unsigned char) *fp->_IO_read_ptr;
742 else
743 result = _IO_PBACKFAIL (fp, EOF);
745 if (result != EOF)
746 fp->_flags &= ~_IO_EOF_SEEN;
748 return result;
751 #if 0 /* Work in progress */
752 /* Seems not to be needed. */
753 #if 0
754 void
755 _IO_set_column (fp, c)
756 _IO_FILE *fp;
757 int c;
759 if (c == -1)
760 fp->_column = -1;
761 else
762 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
764 #else
766 _IO_set_column (fp, i)
767 _IO_FILE *fp;
768 int i;
770 fp->_cur_column = i + 1;
771 return 0;
773 #endif
774 #endif
777 unsigned
778 _IO_adjust_column (start, line, count)
779 unsigned start;
780 const char *line;
781 int count;
783 const char *ptr = line + count;
784 while (ptr > line)
785 if (*--ptr == '\n')
786 return line + count - ptr - 1;
787 return start + count;
789 INTDEF(_IO_adjust_column)
791 #if 0
792 /* Seems not to be needed. --drepper */
794 _IO_get_column (fp)
795 _IO_FILE *fp;
797 if (fp->_cur_column)
798 return _IO_adjust_column (fp->_cur_column - 1,
799 fp->_IO_write_base,
800 fp->_IO_write_ptr - fp->_IO_write_base);
801 return -1;
803 #endif
807 _IO_flush_all_lockp (int do_lock)
809 int result = 0;
810 struct _IO_FILE *fp;
811 int last_stamp;
813 #ifdef _IO_MTSAFE_IO
814 _IO_cleanup_region_start_noarg (flush_cleanup);
815 if (do_lock)
816 _IO_lock_lock (list_all_lock);
817 #endif
819 last_stamp = _IO_list_all_stamp;
820 fp = (_IO_FILE *) INTUSE(_IO_list_all);
821 while (fp != NULL)
823 run_fp = fp;
824 if (do_lock)
825 _IO_flockfile (fp);
827 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
828 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
829 || (fp->_vtable_offset == 0
830 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
831 > fp->_wide_data->_IO_write_base))
832 #endif
834 && _IO_OVERFLOW (fp, EOF) == EOF)
835 result = EOF;
837 if (do_lock)
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 *) INTUSE(_IO_list_all);
845 last_stamp = _IO_list_all_stamp;
847 else
848 fp = fp->_chain;
851 #ifdef _IO_MTSAFE_IO
852 if (do_lock)
853 _IO_lock_unlock (list_all_lock);
854 _IO_cleanup_region_end (0);
855 #endif
857 return result;
862 _IO_flush_all ()
864 /* We want locking. */
865 return _IO_flush_all_lockp (1);
867 INTDEF(_IO_flush_all)
869 void
870 _IO_flush_all_linebuffered ()
872 struct _IO_FILE *fp;
873 int last_stamp;
875 #ifdef _IO_MTSAFE_IO
876 _IO_cleanup_region_start_noarg (flush_cleanup);
877 _IO_lock_lock (list_all_lock);
878 #endif
880 last_stamp = _IO_list_all_stamp;
881 fp = (_IO_FILE *) INTUSE(_IO_list_all);
882 while (fp != NULL)
884 run_fp = fp;
885 _IO_flockfile (fp);
887 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
888 _IO_OVERFLOW (fp, EOF);
890 _IO_funlockfile (fp);
891 run_fp = NULL;
893 if (last_stamp != _IO_list_all_stamp)
895 /* Something was added to the list. Start all over again. */
896 fp = (_IO_FILE *) INTUSE(_IO_list_all);
897 last_stamp = _IO_list_all_stamp;
899 else
900 fp = fp->_chain;
903 #ifdef _IO_MTSAFE_IO
904 _IO_lock_unlock (list_all_lock);
905 _IO_cleanup_region_end (0);
906 #endif
908 INTDEF(_IO_flush_all_linebuffered)
909 #ifdef _LIBC
910 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
911 #endif
913 static void _IO_unbuffer_write __P ((void));
915 static void
916 _IO_unbuffer_write ()
918 struct _IO_FILE *fp;
919 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
921 if (! (fp->_flags & _IO_UNBUFFERED)
922 && (! (fp->_flags & _IO_NO_WRITES)
923 || (fp->_flags & _IO_IS_APPENDING))
924 /* Iff stream is un-orientated, it wasn't used. */
925 && fp->_mode != 0)
926 _IO_SETBUF (fp, NULL, 0);
928 /* Make sure that never again the wide char functions can be
929 used. */
930 fp->_mode = -1;
935 _IO_cleanup ()
937 int result = INTUSE(_IO_flush_all) ();
939 /* We currently don't have a reliable mechanism for making sure that
940 C++ static destructors are executed in the correct order.
941 So it is possible that other static destructors might want to
942 write to cout - and they're supposed to be able to do so.
944 The following will make the standard streambufs be unbuffered,
945 which forces any output from late destructors to be written out. */
946 _IO_unbuffer_write ();
948 return result;
952 void
953 _IO_init_marker (marker, fp)
954 struct _IO_marker *marker;
955 _IO_FILE *fp;
957 marker->_sbuf = fp;
958 if (_IO_in_put_mode (fp))
959 INTUSE(_IO_switch_to_get_mode) (fp);
960 if (_IO_in_backup (fp))
961 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
962 else
963 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
965 /* Should perhaps sort the chain? */
966 marker->_next = fp->_markers;
967 fp->_markers = marker;
970 void
971 _IO_remove_marker (marker)
972 struct _IO_marker *marker;
974 /* Unlink from sb's chain. */
975 struct _IO_marker **ptr = &marker->_sbuf->_markers;
976 for (; ; ptr = &(*ptr)->_next)
978 if (*ptr == NULL)
979 break;
980 else if (*ptr == marker)
982 *ptr = marker->_next;
983 return;
986 #if 0
987 if _sbuf has a backup area that is no longer needed, should we delete
988 it now, or wait until the next underflow?
989 #endif
992 #define BAD_DELTA EOF
995 _IO_marker_difference (mark1, mark2)
996 struct _IO_marker *mark1;
997 struct _IO_marker *mark2;
999 return mark1->_pos - mark2->_pos;
1002 /* Return difference between MARK and current position of MARK's stream. */
1004 _IO_marker_delta (mark)
1005 struct _IO_marker *mark;
1007 int cur_pos;
1008 if (mark->_sbuf == NULL)
1009 return BAD_DELTA;
1010 if (_IO_in_backup (mark->_sbuf))
1011 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1012 else
1013 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1014 return mark->_pos - cur_pos;
1018 _IO_seekmark (fp, mark, delta)
1019 _IO_FILE *fp;
1020 struct _IO_marker *mark;
1021 int delta;
1023 if (mark->_sbuf != fp)
1024 return EOF;
1025 if (mark->_pos >= 0)
1027 if (_IO_in_backup (fp))
1028 _IO_switch_to_main_get_area (fp);
1029 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1031 else
1033 if (!_IO_in_backup (fp))
1034 _IO_switch_to_backup_area (fp);
1035 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1037 return 0;
1040 void
1041 _IO_unsave_markers (fp)
1042 _IO_FILE *fp;
1044 struct _IO_marker *mark = fp->_markers;
1045 if (mark)
1047 #ifdef TODO
1048 streampos offset = seekoff (0, ios::cur, ios::in);
1049 if (offset != EOF)
1051 offset += eGptr () - Gbase ();
1052 for ( ; mark != NULL; mark = mark->_next)
1053 mark->set_streampos (mark->_pos + offset);
1055 else
1057 for ( ; mark != NULL; mark = mark->_next)
1058 mark->set_streampos (EOF);
1060 #endif
1061 fp->_markers = 0;
1064 if (_IO_have_backup (fp))
1065 INTUSE(_IO_free_backup_area) (fp);
1067 INTDEF(_IO_unsave_markers)
1069 #if 0
1070 /* Seems not to be needed. --drepper */
1072 _IO_nobackup_pbackfail (fp, c)
1073 _IO_FILE *fp;
1074 int c;
1076 if (fp->_IO_read_ptr > fp->_IO_read_base)
1077 fp->_IO_read_ptr--;
1078 if (c != EOF && *fp->_IO_read_ptr != c)
1079 *fp->_IO_read_ptr = c;
1080 return (unsigned char) c;
1082 #endif
1085 _IO_default_pbackfail (fp, c)
1086 _IO_FILE *fp;
1087 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 INTDEF(_IO_default_pbackfail)
1143 _IO_off64_t
1144 _IO_default_seek (fp, offset, dir)
1145 _IO_FILE *fp;
1146 _IO_off64_t offset;
1147 int dir;
1149 return _IO_pos_BAD;
1153 _IO_default_stat (fp, st)
1154 _IO_FILE *fp;
1155 void* st;
1157 return EOF;
1160 _IO_ssize_t
1161 _IO_default_read (fp, data, n)
1162 _IO_FILE* fp;
1163 void *data;
1164 _IO_ssize_t n;
1166 return -1;
1169 _IO_ssize_t
1170 _IO_default_write (fp, data, n)
1171 _IO_FILE *fp;
1172 const void *data;
1173 _IO_ssize_t n;
1175 return 0;
1179 _IO_default_showmanyc (fp)
1180 _IO_FILE *fp;
1182 return -1;
1185 void
1186 _IO_default_imbue (fp, locale)
1187 _IO_FILE *fp;
1188 void *locale;
1192 _IO_ITER
1193 _IO_iter_begin()
1195 return (_IO_ITER) INTUSE(_IO_list_all);
1197 libc_hidden_def (_IO_iter_begin)
1199 _IO_ITER
1200 _IO_iter_end()
1202 return NULL;
1204 libc_hidden_def (_IO_iter_end)
1206 _IO_ITER
1207 _IO_iter_next(iter)
1208 _IO_ITER iter;
1210 return iter->_chain;
1212 libc_hidden_def (_IO_iter_next)
1214 _IO_FILE *
1215 _IO_iter_file(iter)
1216 _IO_ITER iter;
1218 return iter;
1220 libc_hidden_def (_IO_iter_file)
1222 void
1223 _IO_list_lock()
1225 #ifdef _IO_MTSAFE_IO
1226 _IO_lock_lock (list_all_lock);
1227 #endif
1229 libc_hidden_def (_IO_list_lock)
1231 void
1232 _IO_list_unlock()
1234 #ifdef _IO_MTSAFE_IO
1235 _IO_lock_unlock (list_all_lock);
1236 #endif
1238 libc_hidden_def (_IO_list_unlock)
1240 void
1241 _IO_list_resetlock()
1243 #ifdef _IO_MTSAFE_IO
1244 _IO_lock_init (list_all_lock);
1245 #endif
1247 libc_hidden_def (_IO_list_resetlock)
1250 #ifdef TODO
1251 #if defined(linux)
1252 #define IO_CLEANUP ;
1253 #endif
1255 #ifdef IO_CLEANUP
1256 IO_CLEANUP
1257 #else
1258 struct __io_defs {
1259 __io_defs() { }
1260 ~__io_defs() { _IO_cleanup (); }
1262 __io_defs io_defs__;
1263 #endif
1265 #endif /* TODO */
1267 #ifdef text_set_element
1268 text_set_element(__libc_atexit, _IO_cleanup);
1269 #endif