libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / system / libroot / posix / glibc / libio / genops.c
blob7fa0a224c43f52fdfdbf65d4f752b21d2f550149
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.
29 /* Generic or default I/O operations. */
31 #include "libioP.h"
32 #include <stdlib.h>
33 #include <string.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 #if 0
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
55 #endif
58 void
59 _IO_un_link(struct _IO_FILE_plus *fp)
61 if (fp->file._flags & _IO_LINKED)
63 struct _IO_FILE_plus **f;
64 #ifdef _IO_MTSAFE_IO
65 _IO_cleanup_region_start_noarg (flush_cleanup);
66 _IO_lock_lock (list_all_lock);
67 run_fp = (_IO_FILE *) fp;
68 _IO_flockfile ((_IO_FILE *) fp);
69 #endif
70 for (f = &INTUSE(_IO_list_all); *f;
71 f = (struct _IO_FILE_plus **) &(*f)->file._chain)
73 if (*f == fp)
75 *f = (struct _IO_FILE_plus *) fp->file._chain;
76 ++_IO_list_all_stamp;
77 break;
80 fp->file._flags &= ~_IO_LINKED;
81 #ifdef _IO_MTSAFE_IO
82 _IO_funlockfile ((_IO_FILE *) fp);
83 run_fp = NULL;
84 _IO_lock_unlock (list_all_lock);
85 _IO_cleanup_region_end (0);
86 #endif
89 INTDEF(_IO_un_link)
91 void
92 _IO_link_in (fp)
93 struct _IO_FILE_plus *fp;
95 if ((fp->file._flags & _IO_LINKED) == 0)
97 fp->file._flags |= _IO_LINKED;
98 #ifdef _IO_MTSAFE_IO
99 _IO_cleanup_region_start_noarg (flush_cleanup);
100 _IO_lock_lock (list_all_lock);
101 run_fp = (_IO_FILE *) fp;
102 _IO_flockfile ((_IO_FILE *) fp);
103 #endif
104 fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
105 INTUSE(_IO_list_all) = fp;
106 ++_IO_list_all_stamp;
107 #ifdef _IO_MTSAFE_IO
108 _IO_funlockfile ((_IO_FILE *) fp);
109 run_fp = NULL;
110 _IO_lock_unlock (list_all_lock);
111 _IO_cleanup_region_end (0);
112 #endif
115 INTDEF(_IO_link_in)
117 /* Return minimum _pos markers
118 Assumes the current get area is the main get area. */
119 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
121 _IO_ssize_t
122 _IO_least_marker (fp, end_p)
123 _IO_FILE *fp;
124 char *end_p;
126 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
127 struct _IO_marker *mark;
128 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
129 if (mark->_pos < least_so_far)
130 least_so_far = mark->_pos;
131 return least_so_far;
134 /* Switch current get area from backup buffer to (start of) main get area. */
136 void
137 _IO_switch_to_main_get_area (fp)
138 _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 (fp)
158 _IO_FILE *fp;
160 char *tmp;
161 fp->_flags |= _IO_IN_BACKUP;
162 /* Swap _IO_read_end and _IO_save_end. */
163 tmp = fp->_IO_read_end;
164 fp->_IO_read_end = fp->_IO_save_end;
165 fp->_IO_save_end = tmp;
166 /* Swap _IO_read_base and _IO_save_base. */
167 tmp = fp->_IO_read_base;
168 fp->_IO_read_base = fp->_IO_save_base;
169 fp->_IO_save_base = tmp;
170 /* Set _IO_read_ptr. */
171 fp->_IO_read_ptr = fp->_IO_read_end;
175 _IO_switch_to_get_mode (fp)
176 _IO_FILE *fp;
178 if (fp->_IO_write_ptr > fp->_IO_write_base)
179 if (_IO_OVERFLOW (fp, EOF) == EOF)
180 return EOF;
181 if (_IO_in_backup (fp))
182 fp->_IO_read_base = fp->_IO_backup_base;
183 else
185 fp->_IO_read_base = fp->_IO_buf_base;
186 if (fp->_IO_write_ptr > fp->_IO_read_end)
187 fp->_IO_read_end = fp->_IO_write_ptr;
189 fp->_IO_read_ptr = fp->_IO_write_ptr;
191 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
193 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
194 return 0;
196 INTDEF(_IO_switch_to_get_mode)
198 void
199 _IO_free_backup_area (fp)
200 _IO_FILE *fp;
202 if (_IO_in_backup (fp))
203 _IO_switch_to_main_get_area (fp); /* Just in case. */
204 free (fp->_IO_save_base);
205 fp->_IO_save_base = NULL;
206 fp->_IO_save_end = NULL;
207 fp->_IO_backup_base = NULL;
209 INTDEF(_IO_free_backup_area)
211 #if 0
213 _IO_switch_to_put_mode (fp)
214 _IO_FILE *fp;
216 fp->_IO_write_base = fp->_IO_read_ptr;
217 fp->_IO_write_ptr = fp->_IO_read_ptr;
218 /* Following is wrong if line- or un-buffered? */
219 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
220 ? fp->_IO_read_end : fp->_IO_buf_end);
222 fp->_IO_read_ptr = fp->_IO_read_end;
223 fp->_IO_read_base = fp->_IO_read_end;
225 fp->_flags |= _IO_CURRENTLY_PUTTING;
226 return 0;
228 #endif
232 __overflow(_IO_FILE *file, int character)
234 /* This is a single-byte stream. */
235 if (file->_mode == 0)
236 _IO_fwide(file, -1);
238 return _IO_OVERFLOW(file, character);
240 libc_hidden_def(__overflow)
243 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
244 #ifdef _LIBC
245 internal_function
246 #endif
249 static int
250 #ifdef _LIBC
251 internal_function
252 #endif
253 save_for_backup (fp, end_p)
254 _IO_FILE *fp;
255 char *end_p;
257 /* Append [_IO_read_base..end_p] to backup area. */
258 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
259 /* needed_size is how much space we need in the backup area. */
260 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
261 /* FIXME: Dubious arithmetic if pointers are NULL */
262 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
263 _IO_size_t avail; /* Extra space available for future expansion. */
264 _IO_ssize_t delta;
265 struct _IO_marker *mark;
266 if (needed_size > current_Bsize)
268 char *new_buffer;
269 avail = 100;
270 new_buffer = (char *) malloc (avail + needed_size);
271 if (new_buffer == NULL)
272 return EOF; /* FIXME */
273 if (least_mark < 0)
275 #ifdef _LIBC
276 __mempcpy (__mempcpy (new_buffer + avail,
277 fp->_IO_save_end + least_mark,
278 -least_mark),
279 fp->_IO_read_base,
280 end_p - fp->_IO_read_base);
281 #else
282 memcpy (new_buffer + avail,
283 fp->_IO_save_end + least_mark,
284 -least_mark);
285 memcpy (new_buffer + avail - least_mark,
286 fp->_IO_read_base,
287 end_p - fp->_IO_read_base);
288 #endif
290 else
291 memcpy (new_buffer + avail,
292 fp->_IO_read_base + least_mark,
293 needed_size);
294 if (fp->_IO_save_base)
295 free (fp->_IO_save_base);
296 fp->_IO_save_base = new_buffer;
297 fp->_IO_save_end = new_buffer + avail + needed_size;
299 else
301 avail = current_Bsize - needed_size;
302 if (least_mark < 0)
304 memmove (fp->_IO_save_base + avail,
305 fp->_IO_save_end + least_mark,
306 -least_mark);
307 memcpy (fp->_IO_save_base + avail - least_mark,
308 fp->_IO_read_base,
309 end_p - fp->_IO_read_base);
311 else if (needed_size > 0)
312 memcpy (fp->_IO_save_base + avail,
313 fp->_IO_read_base + least_mark,
314 needed_size);
316 fp->_IO_backup_base = fp->_IO_save_base + avail;
317 /* Adjust all the streammarkers. */
318 delta = end_p - fp->_IO_read_base;
319 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
320 mark->_pos -= delta;
321 return 0;
326 __underflow(_IO_FILE *file)
328 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
329 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1)
330 return EOF;
331 #endif
333 if (file->_mode == 0)
334 _IO_fwide(file, -1);
336 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF)
337 return EOF;
339 if (file->_IO_read_ptr < file->_IO_read_end)
340 return *(unsigned char *)file->_IO_read_ptr;
342 if (_IO_in_backup(file)) {
343 _IO_switch_to_main_get_area(file);
345 if (file->_IO_read_ptr < file->_IO_read_end)
346 return *(unsigned char *)file->_IO_read_ptr;
348 if (_IO_have_markers(file)) {
349 if (save_for_backup(file, file->_IO_read_end))
350 return EOF;
351 } else if (_IO_have_backup(file))
352 INTUSE(_IO_free_backup_area)(file);
354 return _IO_UNDERFLOW(file);
356 libc_hidden_def(__underflow)
360 __uflow(_IO_FILE *file)
362 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
363 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1)
364 return EOF;
365 #endif
367 if (file->_mode == 0)
368 _IO_fwide(file, -11);
370 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF)
371 return EOF;
373 if (file->_IO_read_ptr < file->_IO_read_end)
374 return *(unsigned char *)file->_IO_read_ptr++;
376 if (_IO_in_backup(file)) {
377 _IO_switch_to_main_get_area(file);
379 if (file->_IO_read_ptr < file->_IO_read_end)
380 return *(unsigned char *)file->_IO_read_ptr++;
383 if (_IO_have_markers(file)) {
384 if (save_for_backup(file, file->_IO_read_end))
385 return EOF;
386 } else if (_IO_have_backup(file))
387 INTUSE(_IO_free_backup_area)(file);
389 return _IO_UFLOW(file);
391 libc_hidden_def(__uflow)
394 void
395 _IO_setb (f, b, eb, a)
396 _IO_FILE *f;
397 char *b;
398 char *eb;
399 int a;
401 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
402 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
403 f->_IO_buf_base = b;
404 f->_IO_buf_end = eb;
405 if (a)
406 f->_flags &= ~_IO_USER_BUF;
407 else
408 f->_flags |= _IO_USER_BUF;
410 INTDEF(_IO_setb)
412 void
413 _IO_doallocbuf (fp)
414 _IO_FILE *fp;
416 if (fp->_IO_buf_base)
417 return;
418 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
419 if (_IO_DOALLOCATE (fp) != EOF)
420 return;
421 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
423 INTDEF(_IO_doallocbuf)
426 _IO_default_underflow (fp)
427 _IO_FILE *fp;
429 return EOF;
433 _IO_default_uflow (fp)
434 _IO_FILE *fp;
436 int ch = _IO_UNDERFLOW (fp);
437 if (ch == EOF)
438 return EOF;
439 return *(unsigned char *) fp->_IO_read_ptr++;
441 INTDEF(_IO_default_uflow)
443 _IO_size_t
444 _IO_default_xsputn (f, data, n)
445 _IO_FILE *f;
446 const void *data;
447 _IO_size_t n;
449 const char *s = (char *) data;
450 _IO_size_t more = n;
451 if (more <= 0)
452 return 0;
453 for (;;)
455 /* Space available. */
456 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
457 if (count > 0)
459 if ((_IO_size_t) count > more)
460 count = more;
461 if (count > 20)
463 #ifdef _LIBC
464 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
465 #else
466 memcpy (f->_IO_write_ptr, s, count);
467 f->_IO_write_ptr += count;
468 #endif
469 s += count;
471 else if (count <= 0)
472 count = 0;
473 else
475 char *p = f->_IO_write_ptr;
476 _IO_ssize_t i;
477 for (i = count; --i >= 0; )
478 *p++ = *s++;
479 f->_IO_write_ptr = p;
481 more -= count;
483 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
484 break;
485 more--;
487 return n - more;
489 INTDEF(_IO_default_xsputn)
491 _IO_size_t
492 _IO_sgetn (fp, data, n)
493 _IO_FILE *fp;
494 void *data;
495 _IO_size_t n;
497 /* FIXME handle putback buffer here! */
498 return _IO_XSGETN (fp, data, n);
500 INTDEF(_IO_sgetn)
502 _IO_size_t
503 _IO_default_xsgetn (fp, data, n)
504 _IO_FILE *fp;
505 void *data;
506 _IO_size_t n;
508 _IO_size_t more = n;
509 char *s = (char*) data;
510 for (;;)
512 /* Data available. */
513 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
514 if (count > 0)
516 if ((_IO_size_t) count > more)
517 count = more;
518 if (count > 20)
520 #ifdef _LIBC
521 s = __mempcpy (s, fp->_IO_read_ptr, count);
522 #else
523 memcpy (s, fp->_IO_read_ptr, count);
524 s += count;
525 #endif
526 fp->_IO_read_ptr += count;
528 else if (count <= 0)
529 count = 0;
530 else
532 char *p = fp->_IO_read_ptr;
533 int i = (int) count;
534 while (--i >= 0)
535 *s++ = *p++;
536 fp->_IO_read_ptr = p;
538 more -= count;
540 if (more == 0 || __underflow (fp) == EOF)
541 break;
543 return n - more;
545 INTDEF(_IO_default_xsgetn)
547 #if 0
548 /* Seems not to be needed. --drepper */
550 _IO_sync (fp)
551 _IO_FILE *fp;
553 return 0;
555 #endif
557 _IO_FILE *
558 _IO_default_setbuf (fp, p, len)
559 _IO_FILE *fp;
560 char *p;
561 _IO_ssize_t len;
563 if (_IO_SYNC (fp) == EOF)
564 return NULL;
565 if (p == NULL || len == 0)
567 fp->_flags |= _IO_UNBUFFERED;
568 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
570 else
572 fp->_flags &= ~_IO_UNBUFFERED;
573 INTUSE(_IO_setb) (fp, p, p+len, 0);
575 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
576 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
577 return fp;
580 _IO_off64_t
581 _IO_default_seekpos (fp, pos, mode)
582 _IO_FILE *fp;
583 _IO_off64_t pos;
584 int mode;
586 return _IO_SEEKOFF (fp, pos, 0, mode);
590 _IO_default_doallocate (fp)
591 _IO_FILE *fp;
593 char *buf;
595 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
596 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
597 return 1;
599 INTDEF(_IO_default_doallocate)
601 void
602 _IO_init (fp, flags)
603 _IO_FILE *fp;
604 int flags;
606 _IO_no_init (fp, flags, -1, NULL, NULL);
608 INTDEF(_IO_init)
610 void
611 _IO_no_init (fp, flags, orientation, wd, jmp)
612 _IO_FILE *fp;
613 int flags;
614 int orientation;
615 struct _IO_wide_data *wd;
616 struct _IO_jump_t *jmp;
618 fp->_flags = _IO_MAGIC|flags;
619 fp->_flags2 = 0;
620 fp->_IO_buf_base = NULL;
621 fp->_IO_buf_end = NULL;
622 fp->_IO_read_base = NULL;
623 fp->_IO_read_ptr = NULL;
624 fp->_IO_read_end = NULL;
625 fp->_IO_write_base = NULL;
626 fp->_IO_write_ptr = NULL;
627 fp->_IO_write_end = NULL;
628 fp->_chain = NULL; /* Not necessary. */
630 fp->_IO_save_base = NULL;
631 fp->_IO_backup_base = NULL;
632 fp->_IO_save_end = NULL;
633 fp->_markers = NULL;
634 fp->_cur_column = 0;
635 #if _IO_JUMPS_OFFSET
636 fp->_vtable_offset = 0;
637 #endif
638 #ifdef _IO_MTSAFE_IO
639 if (fp->_lock != NULL)
640 _IO_lock_init (*fp->_lock);
641 #endif
642 fp->_mode = orientation;
643 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
644 if (orientation >= 0)
646 fp->_wide_data = wd;
647 fp->_wide_data->_IO_buf_base = NULL;
648 fp->_wide_data->_IO_buf_end = NULL;
649 fp->_wide_data->_IO_read_base = NULL;
650 fp->_wide_data->_IO_read_ptr = NULL;
651 fp->_wide_data->_IO_read_end = NULL;
652 fp->_wide_data->_IO_write_base = NULL;
653 fp->_wide_data->_IO_write_ptr = NULL;
654 fp->_wide_data->_IO_write_end = NULL;
655 fp->_wide_data->_IO_save_base = NULL;
656 fp->_wide_data->_IO_backup_base = NULL;
657 fp->_wide_data->_IO_save_end = NULL;
659 fp->_wide_data->_wide_vtable = jmp;
661 #endif
665 _IO_default_sync (fp)
666 _IO_FILE *fp;
668 return 0;
671 /* The way the C++ classes are mapped into the C functions in the
672 current implementation, this function can get called twice! */
674 void
675 _IO_default_finish (fp, dummy)
676 _IO_FILE *fp;
677 int dummy;
679 struct _IO_marker *mark;
680 if (fp->_IO_buf_base && fp->_IO_buf_base != fp->_shortbuf
681 && !(fp->_flags & _IO_USER_BUF))
683 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
684 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
687 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
688 mark->_sbuf = NULL;
690 if (fp->_IO_save_base)
692 free (fp->_IO_save_base);
693 fp->_IO_save_base = NULL;
696 #ifdef _IO_MTSAFE_IO
697 if (fp->_lock != NULL)
698 _IO_lock_fini (*fp->_lock);
699 #endif
701 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
703 INTDEF(_IO_default_finish)
705 _IO_off64_t
706 _IO_default_seekoff (fp, offset, dir, mode)
707 _IO_FILE *fp;
708 _IO_off64_t offset;
709 int dir;
710 int mode;
712 return _IO_pos_BAD;
716 _IO_sputbackc (fp, c)
717 _IO_FILE *fp;
718 int c;
720 int result;
722 if (fp->_IO_read_ptr > fp->_IO_read_base
723 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
725 fp->_IO_read_ptr--;
726 result = (unsigned char) c;
728 else
729 result = _IO_PBACKFAIL (fp, c);
731 if (result != EOF)
732 fp->_flags &= ~_IO_EOF_SEEN;
734 return result;
736 INTDEF(_IO_sputbackc)
739 _IO_sungetc (fp)
740 _IO_FILE *fp;
742 int result;
744 if (fp->_IO_read_ptr > fp->_IO_read_base)
746 fp->_IO_read_ptr--;
747 result = (unsigned char) *fp->_IO_read_ptr;
749 else
750 result = _IO_PBACKFAIL (fp, EOF);
752 if (result != EOF)
753 fp->_flags &= ~_IO_EOF_SEEN;
755 return result;
758 #if 0 /* Work in progress */
759 /* Seems not to be needed. */
760 #if 0
761 void
762 _IO_set_column (fp, c)
763 _IO_FILE *fp;
764 int c;
766 if (c == -1)
767 fp->_column = -1;
768 else
769 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
771 #else
773 _IO_set_column (fp, i)
774 _IO_FILE *fp;
775 int i;
777 fp->_cur_column = i + 1;
778 return 0;
780 #endif
781 #endif
784 unsigned
785 _IO_adjust_column (start, line, count)
786 unsigned start;
787 const char *line;
788 int count;
790 const char *ptr = line + count;
791 while (ptr > line)
792 if (*--ptr == '\n')
793 return line + count - ptr - 1;
794 return start + count;
796 INTDEF(_IO_adjust_column)
798 #if 0
799 /* Seems not to be needed. --drepper */
801 _IO_get_column (fp)
802 _IO_FILE *fp;
804 if (fp->_cur_column)
805 return _IO_adjust_column (fp->_cur_column - 1,
806 fp->_IO_write_base,
807 fp->_IO_write_ptr - fp->_IO_write_base);
808 return -1;
810 #endif
814 _IO_flush_all_lockp (int do_lock)
816 int result = 0;
817 struct _IO_FILE *fp;
818 int last_stamp;
820 #ifdef _IO_MTSAFE_IO
821 _IO_cleanup_region_start_noarg (flush_cleanup);
822 if (do_lock)
823 _IO_lock_lock (list_all_lock);
824 #endif
826 last_stamp = _IO_list_all_stamp;
827 fp = (_IO_FILE *) INTUSE(_IO_list_all);
828 while (fp != NULL)
830 run_fp = fp;
831 if (do_lock)
832 _IO_flockfile (fp);
834 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
835 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
836 || (fp->_vtable_offset == 0
837 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
838 > fp->_wide_data->_IO_write_base))
839 #endif
841 && _IO_OVERFLOW (fp, EOF) == EOF)
842 result = EOF;
844 if (do_lock)
845 _IO_funlockfile (fp);
846 run_fp = NULL;
848 if (last_stamp != _IO_list_all_stamp)
850 /* Something was added to the list. Start all over again. */
851 fp = (_IO_FILE *) INTUSE(_IO_list_all);
852 last_stamp = _IO_list_all_stamp;
854 else
855 fp = fp->_chain;
858 #ifdef _IO_MTSAFE_IO
859 if (do_lock)
860 _IO_lock_unlock (list_all_lock);
861 _IO_cleanup_region_end (0);
862 #endif
864 return result;
869 _IO_flush_all ()
871 /* We want locking. */
872 return _IO_flush_all_lockp (1);
874 INTDEF(_IO_flush_all)
876 void
877 _IO_flush_all_linebuffered ()
879 struct _IO_FILE *fp;
880 int last_stamp;
882 #ifdef _IO_MTSAFE_IO
883 _IO_cleanup_region_start_noarg (flush_cleanup);
884 _IO_lock_lock (list_all_lock);
885 #endif
887 last_stamp = _IO_list_all_stamp;
888 fp = (_IO_FILE *) INTUSE(_IO_list_all);
889 while (fp != NULL)
891 run_fp = fp;
892 _IO_flockfile (fp);
894 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
895 _IO_OVERFLOW (fp, EOF);
897 _IO_funlockfile (fp);
898 run_fp = NULL;
900 if (last_stamp != _IO_list_all_stamp)
902 /* Something was added to the list. Start all over again. */
903 fp = (_IO_FILE *) INTUSE(_IO_list_all);
904 last_stamp = _IO_list_all_stamp;
906 else
907 fp = fp->_chain;
910 #ifdef _IO_MTSAFE_IO
911 _IO_lock_unlock (list_all_lock);
912 _IO_cleanup_region_end (0);
913 #endif
915 INTDEF(_IO_flush_all_linebuffered)
916 #ifdef _LIBC
917 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
918 #endif
920 static void _IO_unbuffer_write __P ((void));
922 static void
923 _IO_unbuffer_write ()
925 struct _IO_FILE *fp;
926 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
928 if (! (fp->_flags & _IO_UNBUFFERED)
929 && (! (fp->_flags & _IO_NO_WRITES)
930 || (fp->_flags & _IO_IS_APPENDING))
931 /* Iff stream is un-orientated, it wasn't used. */
932 && fp->_mode != 0)
933 _IO_SETBUF (fp, NULL, 0);
935 /* Make sure that never again the wide char functions can be
936 used. */
937 fp->_mode = -1;
942 _IO_cleanup ()
944 /* We do *not* want locking. Some threads might use streams but
945 that is there problem, we flush them underneath them. */
946 int result = _IO_flush_all_lockp (0);
948 /* We currently don't have a reliable mechanism for making sure that
949 C++ static destructors are executed in the correct order.
950 So it is possible that other static destructors might want to
951 write to cout - and they're supposed to be able to do so.
953 The following will make the standard streambufs be unbuffered,
954 which forces any output from late destructors to be written out. */
955 _IO_unbuffer_write ();
957 return result;
961 void
962 _IO_init_marker (marker, fp)
963 struct _IO_marker *marker;
964 _IO_FILE *fp;
966 marker->_sbuf = fp;
967 if (_IO_in_put_mode (fp))
968 INTUSE(_IO_switch_to_get_mode) (fp);
969 if (_IO_in_backup (fp))
970 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
971 else
972 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
974 /* Should perhaps sort the chain? */
975 marker->_next = fp->_markers;
976 fp->_markers = marker;
979 void
980 _IO_remove_marker (marker)
981 struct _IO_marker *marker;
983 /* Unlink from sb's chain. */
984 struct _IO_marker **ptr = &marker->_sbuf->_markers;
985 for (; ; ptr = &(*ptr)->_next)
987 if (*ptr == NULL)
988 break;
989 else if (*ptr == marker)
991 *ptr = marker->_next;
992 return;
995 #if 0
996 if _sbuf has a backup area that is no longer needed, should we delete
997 it now, or wait until the next underflow?
998 #endif
1001 #define BAD_DELTA EOF
1004 _IO_marker_difference (mark1, mark2)
1005 struct _IO_marker *mark1;
1006 struct _IO_marker *mark2;
1008 return mark1->_pos - mark2->_pos;
1011 /* Return difference between MARK and current position of MARK's stream. */
1013 _IO_marker_delta (mark)
1014 struct _IO_marker *mark;
1016 int cur_pos;
1017 if (mark->_sbuf == NULL)
1018 return BAD_DELTA;
1019 if (_IO_in_backup (mark->_sbuf))
1020 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1021 else
1022 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1023 return mark->_pos - cur_pos;
1027 _IO_seekmark (fp, mark, delta)
1028 _IO_FILE *fp;
1029 struct _IO_marker *mark;
1030 int delta;
1032 if (mark->_sbuf != fp)
1033 return EOF;
1034 if (mark->_pos >= 0)
1036 if (_IO_in_backup (fp))
1037 _IO_switch_to_main_get_area (fp);
1038 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1040 else
1042 if (!_IO_in_backup (fp))
1043 _IO_switch_to_backup_area (fp);
1044 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1046 return 0;
1049 void
1050 _IO_unsave_markers (fp)
1051 _IO_FILE *fp;
1053 struct _IO_marker *mark = fp->_markers;
1054 if (mark)
1056 #ifdef TODO
1057 streampos offset = seekoff (0, ios::cur, ios::in);
1058 if (offset != EOF)
1060 offset += eGptr () - Gbase ();
1061 for ( ; mark != NULL; mark = mark->_next)
1062 mark->set_streampos (mark->_pos + offset);
1064 else
1066 for ( ; mark != NULL; mark = mark->_next)
1067 mark->set_streampos (EOF);
1069 #endif
1070 fp->_markers = 0;
1073 if (_IO_have_backup (fp))
1074 INTUSE(_IO_free_backup_area) (fp);
1076 INTDEF(_IO_unsave_markers)
1078 #if 0
1079 /* Seems not to be needed. --drepper */
1081 _IO_nobackup_pbackfail (fp, c)
1082 _IO_FILE *fp;
1083 int c;
1085 if (fp->_IO_read_ptr > fp->_IO_read_base)
1086 fp->_IO_read_ptr--;
1087 if (c != EOF && *fp->_IO_read_ptr != c)
1088 *fp->_IO_read_ptr = c;
1089 return (unsigned char) c;
1091 #endif
1094 _IO_default_pbackfail (fp, c)
1095 _IO_FILE *fp;
1096 int c;
1098 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1099 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1100 --fp->_IO_read_ptr;
1101 else
1103 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1104 if (!_IO_in_backup (fp))
1106 /* We need to keep the invariant that the main get area
1107 logically follows the backup area. */
1108 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1110 if (save_for_backup (fp, fp->_IO_read_ptr))
1111 return EOF;
1113 else if (!_IO_have_backup (fp))
1115 /* No backup buffer: allocate one. */
1116 /* Use nshort buffer, if unused? (probably not) FIXME */
1117 int backup_size = 128;
1118 char *bbuf = (char *) malloc (backup_size);
1119 if (bbuf == NULL)
1120 return EOF;
1121 fp->_IO_save_base = bbuf;
1122 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1123 fp->_IO_backup_base = fp->_IO_save_end;
1125 fp->_IO_read_base = fp->_IO_read_ptr;
1126 _IO_switch_to_backup_area (fp);
1128 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1130 /* Increase size of existing backup buffer. */
1131 _IO_size_t new_size;
1132 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1133 char *new_buf;
1134 new_size = 2 * old_size;
1135 new_buf = (char *) malloc (new_size);
1136 if (new_buf == NULL)
1137 return EOF;
1138 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1139 old_size);
1140 free (fp->_IO_read_base);
1141 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1142 new_buf + new_size);
1143 fp->_IO_backup_base = fp->_IO_read_ptr;
1146 *--fp->_IO_read_ptr = c;
1148 return (unsigned char) c;
1150 INTDEF(_IO_default_pbackfail)
1152 _IO_off64_t
1153 _IO_default_seek (fp, offset, dir)
1154 _IO_FILE *fp;
1155 _IO_off64_t offset;
1156 int dir;
1158 return _IO_pos_BAD;
1162 _IO_default_stat (fp, st)
1163 _IO_FILE *fp;
1164 void* st;
1166 return EOF;
1169 _IO_ssize_t
1170 _IO_default_read (fp, data, n)
1171 _IO_FILE* fp;
1172 void *data;
1173 _IO_ssize_t n;
1175 return -1;
1178 _IO_ssize_t
1179 _IO_default_write (fp, data, n)
1180 _IO_FILE *fp;
1181 const void *data;
1182 _IO_ssize_t n;
1184 return 0;
1188 _IO_default_showmanyc (fp)
1189 _IO_FILE *fp;
1191 return -1;
1194 void
1195 _IO_default_imbue (fp, locale)
1196 _IO_FILE *fp;
1197 void *locale;
1201 _IO_ITER
1202 _IO_iter_begin()
1204 return (_IO_ITER) INTUSE(_IO_list_all);
1206 libc_hidden_def (_IO_iter_begin)
1208 _IO_ITER
1209 _IO_iter_end()
1211 return NULL;
1213 libc_hidden_def (_IO_iter_end)
1215 _IO_ITER
1216 _IO_iter_next(iter)
1217 _IO_ITER iter;
1219 return iter->_chain;
1221 libc_hidden_def (_IO_iter_next)
1223 _IO_FILE *
1224 _IO_iter_file(iter)
1225 _IO_ITER iter;
1227 return iter;
1229 libc_hidden_def (_IO_iter_file)
1231 void
1232 _IO_list_lock()
1234 #ifdef _IO_MTSAFE_IO
1235 _IO_lock_lock (list_all_lock);
1236 #endif
1238 libc_hidden_def (_IO_list_lock)
1240 void
1241 _IO_list_unlock()
1243 #ifdef _IO_MTSAFE_IO
1244 _IO_lock_unlock (list_all_lock);
1245 #endif
1247 libc_hidden_def (_IO_list_unlock)
1249 void
1250 _IO_list_resetlock()
1252 #ifdef _IO_MTSAFE_IO
1253 _IO_lock_init (list_all_lock);
1254 #endif
1256 libc_hidden_def (_IO_list_resetlock)
1259 #ifdef TODO
1260 #if defined(linux)
1261 #define IO_CLEANUP ;
1262 #endif
1264 #ifdef IO_CLEANUP
1265 IO_CLEANUP
1266 #else
1267 struct __io_defs {
1268 __io_defs() { }
1269 ~__io_defs() { _IO_cleanup (); }
1271 __io_defs io_defs__;
1272 #endif
1274 #endif /* TODO */
1276 #ifdef text_set_element
1277 text_set_element(__libc_atexit, _IO_cleanup);
1278 #endif