Update.
[glibc.git] / libio / genops.c
blob741ed77f865f0b7d6f6ab168edfbe8c153f86396
1 /* Copyright (C) 1993,1995,1997-2002, 2003, 2004 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 (_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 (_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 (_IO_vtable_offset (fp) == 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 (_IO_vtable_offset (fp) == 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 if (f->_IO_write_ptr < f->_IO_write_end)
452 _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
453 if (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)
467 char *p = f->_IO_write_ptr;
468 _IO_ssize_t i;
469 for (i = count; --i >= 0; )
470 *p++ = *s++;
471 f->_IO_write_ptr = p;
473 more -= count;
475 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
476 break;
477 more--;
479 return n - more;
481 INTDEF(_IO_default_xsputn)
483 _IO_size_t
484 _IO_sgetn (fp, data, n)
485 _IO_FILE *fp;
486 void *data;
487 _IO_size_t n;
489 /* FIXME handle putback buffer here! */
490 return _IO_XSGETN (fp, data, n);
492 INTDEF(_IO_sgetn)
494 _IO_size_t
495 _IO_default_xsgetn (fp, data, n)
496 _IO_FILE *fp;
497 void *data;
498 _IO_size_t n;
500 _IO_size_t more = n;
501 char *s = (char*) data;
502 for (;;)
504 /* Data available. */
505 if (fp->_IO_read_ptr < fp->_IO_read_end)
507 _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
508 if (count > more)
509 count = more;
510 if (count > 20)
512 #ifdef _LIBC
513 s = __mempcpy (s, fp->_IO_read_ptr, count);
514 #else
515 memcpy (s, fp->_IO_read_ptr, count);
516 s += count;
517 #endif
518 fp->_IO_read_ptr += count;
520 else if (count)
522 char *p = fp->_IO_read_ptr;
523 int i = (int) count;
524 while (--i >= 0)
525 *s++ = *p++;
526 fp->_IO_read_ptr = p;
528 more -= count;
530 if (more == 0 || __underflow (fp) == EOF)
531 break;
533 return n - more;
535 INTDEF(_IO_default_xsgetn)
537 #if 0
538 /* Seems not to be needed. --drepper */
540 _IO_sync (fp)
541 _IO_FILE *fp;
543 return 0;
545 #endif
547 _IO_FILE *
548 _IO_default_setbuf (fp, p, len)
549 _IO_FILE *fp;
550 char *p;
551 _IO_ssize_t len;
553 if (_IO_SYNC (fp) == EOF)
554 return NULL;
555 if (p == NULL || len == 0)
557 fp->_flags |= _IO_UNBUFFERED;
558 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
560 else
562 fp->_flags &= ~_IO_UNBUFFERED;
563 INTUSE(_IO_setb) (fp, p, p+len, 0);
565 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
566 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
567 return fp;
570 _IO_off64_t
571 _IO_default_seekpos (fp, pos, mode)
572 _IO_FILE *fp;
573 _IO_off64_t pos;
574 int mode;
576 return _IO_SEEKOFF (fp, pos, 0, mode);
580 _IO_default_doallocate (fp)
581 _IO_FILE *fp;
583 char *buf;
585 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
586 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1);
587 return 1;
589 INTDEF(_IO_default_doallocate)
591 void
592 _IO_init (fp, flags)
593 _IO_FILE *fp;
594 int flags;
596 _IO_no_init (fp, flags, -1, NULL, NULL);
598 INTDEF(_IO_init)
600 void
601 _IO_old_init (fp, flags)
602 _IO_FILE *fp;
603 int flags;
605 fp->_flags = _IO_MAGIC|flags;
606 fp->_flags2 = 0;
607 fp->_IO_buf_base = NULL;
608 fp->_IO_buf_end = NULL;
609 fp->_IO_read_base = NULL;
610 fp->_IO_read_ptr = NULL;
611 fp->_IO_read_end = NULL;
612 fp->_IO_write_base = NULL;
613 fp->_IO_write_ptr = NULL;
614 fp->_IO_write_end = NULL;
615 fp->_chain = NULL; /* Not necessary. */
617 fp->_IO_save_base = NULL;
618 fp->_IO_backup_base = NULL;
619 fp->_IO_save_end = NULL;
620 fp->_markers = NULL;
621 fp->_cur_column = 0;
622 #if _IO_JUMPS_OFFSET
623 fp->_vtable_offset = 0;
624 #endif
625 #ifdef _IO_MTSAFE_IO
626 if (fp->_lock != NULL)
627 _IO_lock_init (*fp->_lock);
628 #endif
631 void
632 _IO_no_init (fp, flags, orientation, wd, jmp)
633 _IO_FILE *fp;
634 int flags;
635 int orientation;
636 struct _IO_wide_data *wd;
637 const struct _IO_jump_t *jmp;
639 _IO_old_init (fp, flags);
640 fp->_mode = orientation;
641 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
642 if (orientation >= 0)
644 fp->_wide_data = wd;
645 fp->_wide_data->_IO_buf_base = NULL;
646 fp->_wide_data->_IO_buf_end = NULL;
647 fp->_wide_data->_IO_read_base = NULL;
648 fp->_wide_data->_IO_read_ptr = NULL;
649 fp->_wide_data->_IO_read_end = NULL;
650 fp->_wide_data->_IO_write_base = NULL;
651 fp->_wide_data->_IO_write_ptr = NULL;
652 fp->_wide_data->_IO_write_end = NULL;
653 fp->_wide_data->_IO_save_base = NULL;
654 fp->_wide_data->_IO_backup_base = NULL;
655 fp->_wide_data->_IO_save_end = NULL;
657 fp->_wide_data->_wide_vtable = jmp;
659 #endif
663 _IO_default_sync (fp)
664 _IO_FILE *fp;
666 return 0;
669 /* The way the C++ classes are mapped into the C functions in the
670 current implementation, this function can get called twice! */
672 void
673 _IO_default_finish (fp, dummy)
674 _IO_FILE *fp;
675 int dummy;
677 struct _IO_marker *mark;
678 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
680 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
681 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
684 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
685 mark->_sbuf = NULL;
687 if (fp->_IO_save_base)
689 free (fp->_IO_save_base);
690 fp->_IO_save_base = NULL;
693 #ifdef _IO_MTSAFE_IO
694 if (fp->_lock != NULL)
695 _IO_lock_fini (*fp->_lock);
696 #endif
698 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
700 INTDEF(_IO_default_finish)
702 _IO_off64_t
703 _IO_default_seekoff (fp, offset, dir, mode)
704 _IO_FILE *fp;
705 _IO_off64_t offset;
706 int dir;
707 int mode;
709 return _IO_pos_BAD;
713 _IO_sputbackc (fp, c)
714 _IO_FILE *fp;
715 int c;
717 int result;
719 if (fp->_IO_read_ptr > fp->_IO_read_base
720 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
722 fp->_IO_read_ptr--;
723 result = (unsigned char) c;
725 else
726 result = _IO_PBACKFAIL (fp, c);
728 if (result != EOF)
729 fp->_flags &= ~_IO_EOF_SEEN;
731 return result;
733 INTDEF(_IO_sputbackc)
736 _IO_sungetc (fp)
737 _IO_FILE *fp;
739 int result;
741 if (fp->_IO_read_ptr > fp->_IO_read_base)
743 fp->_IO_read_ptr--;
744 result = (unsigned char) *fp->_IO_read_ptr;
746 else
747 result = _IO_PBACKFAIL (fp, EOF);
749 if (result != EOF)
750 fp->_flags &= ~_IO_EOF_SEEN;
752 return result;
755 #if 0 /* Work in progress */
756 /* Seems not to be needed. */
757 #if 0
758 void
759 _IO_set_column (fp, c)
760 _IO_FILE *fp;
761 int c;
763 if (c == -1)
764 fp->_column = -1;
765 else
766 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
768 #else
770 _IO_set_column (fp, i)
771 _IO_FILE *fp;
772 int i;
774 fp->_cur_column = i + 1;
775 return 0;
777 #endif
778 #endif
781 unsigned
782 _IO_adjust_column (start, line, count)
783 unsigned start;
784 const char *line;
785 int count;
787 const char *ptr = line + count;
788 while (ptr > line)
789 if (*--ptr == '\n')
790 return line + count - ptr - 1;
791 return start + count;
793 INTDEF(_IO_adjust_column)
795 #if 0
796 /* Seems not to be needed. --drepper */
798 _IO_get_column (fp)
799 _IO_FILE *fp;
801 if (fp->_cur_column)
802 return _IO_adjust_column (fp->_cur_column - 1,
803 fp->_IO_write_base,
804 fp->_IO_write_ptr - fp->_IO_write_base);
805 return -1;
807 #endif
811 _IO_flush_all_lockp (int do_lock)
813 int result = 0;
814 struct _IO_FILE *fp;
815 int last_stamp;
817 #ifdef _IO_MTSAFE_IO
818 _IO_cleanup_region_start_noarg (flush_cleanup);
819 if (do_lock)
820 _IO_lock_lock (list_all_lock);
821 #endif
823 last_stamp = _IO_list_all_stamp;
824 fp = (_IO_FILE *) INTUSE(_IO_list_all);
825 while (fp != NULL)
827 run_fp = fp;
828 if (do_lock)
829 _IO_flockfile (fp);
831 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
832 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
833 || (_IO_vtable_offset (fp) == 0
834 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
835 > fp->_wide_data->_IO_write_base))
836 #endif
838 && _IO_OVERFLOW (fp, EOF) == EOF)
839 result = EOF;
841 if (do_lock)
842 _IO_funlockfile (fp);
843 run_fp = NULL;
845 if (last_stamp != _IO_list_all_stamp)
847 /* Something was added to the list. Start all over again. */
848 fp = (_IO_FILE *) INTUSE(_IO_list_all);
849 last_stamp = _IO_list_all_stamp;
851 else
852 fp = fp->_chain;
855 #ifdef _IO_MTSAFE_IO
856 if (do_lock)
857 _IO_lock_unlock (list_all_lock);
858 _IO_cleanup_region_end (0);
859 #endif
861 return result;
866 _IO_flush_all ()
868 /* We want locking. */
869 return _IO_flush_all_lockp (1);
871 INTDEF(_IO_flush_all)
873 void
874 _IO_flush_all_linebuffered ()
876 struct _IO_FILE *fp;
877 int last_stamp;
879 #ifdef _IO_MTSAFE_IO
880 _IO_cleanup_region_start_noarg (flush_cleanup);
881 _IO_lock_lock (list_all_lock);
882 #endif
884 last_stamp = _IO_list_all_stamp;
885 fp = (_IO_FILE *) INTUSE(_IO_list_all);
886 while (fp != NULL)
888 run_fp = fp;
889 _IO_flockfile (fp);
891 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
892 _IO_OVERFLOW (fp, EOF);
894 _IO_funlockfile (fp);
895 run_fp = NULL;
897 if (last_stamp != _IO_list_all_stamp)
899 /* Something was added to the list. Start all over again. */
900 fp = (_IO_FILE *) INTUSE(_IO_list_all);
901 last_stamp = _IO_list_all_stamp;
903 else
904 fp = fp->_chain;
907 #ifdef _IO_MTSAFE_IO
908 _IO_lock_unlock (list_all_lock);
909 _IO_cleanup_region_end (0);
910 #endif
912 INTDEF(_IO_flush_all_linebuffered)
913 #ifdef _LIBC
914 weak_alias (_IO_flush_all_linebuffered, _flushlbf)
915 #endif
917 static void _IO_unbuffer_write (void);
919 static void
920 _IO_unbuffer_write ()
922 struct _IO_FILE *fp;
923 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain)
925 if (! (fp->_flags & _IO_UNBUFFERED)
926 && (! (fp->_flags & _IO_NO_WRITES)
927 || (fp->_flags & _IO_IS_APPENDING))
928 /* Iff stream is un-orientated, it wasn't used. */
929 && fp->_mode != 0)
930 _IO_SETBUF (fp, NULL, 0);
932 /* Make sure that never again the wide char functions can be
933 used. */
934 fp->_mode = -1;
939 _IO_cleanup ()
941 /* We do *not* want locking. Some threads might use streams but
942 that is there problem, we flush them underneath them. */
943 int result = _IO_flush_all_lockp (0);
945 /* We currently don't have a reliable mechanism for making sure that
946 C++ static destructors are executed in the correct order.
947 So it is possible that other static destructors might want to
948 write to cout - and they're supposed to be able to do so.
950 The following will make the standard streambufs be unbuffered,
951 which forces any output from late destructors to be written out. */
952 _IO_unbuffer_write ();
954 return result;
958 void
959 _IO_init_marker (marker, fp)
960 struct _IO_marker *marker;
961 _IO_FILE *fp;
963 marker->_sbuf = fp;
964 if (_IO_in_put_mode (fp))
965 INTUSE(_IO_switch_to_get_mode) (fp);
966 if (_IO_in_backup (fp))
967 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
968 else
969 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
971 /* Should perhaps sort the chain? */
972 marker->_next = fp->_markers;
973 fp->_markers = marker;
976 void
977 _IO_remove_marker (marker)
978 struct _IO_marker *marker;
980 /* Unlink from sb's chain. */
981 struct _IO_marker **ptr = &marker->_sbuf->_markers;
982 for (; ; ptr = &(*ptr)->_next)
984 if (*ptr == NULL)
985 break;
986 else if (*ptr == marker)
988 *ptr = marker->_next;
989 return;
992 #if 0
993 if _sbuf has a backup area that is no longer needed, should we delete
994 it now, or wait until the next underflow?
995 #endif
998 #define BAD_DELTA EOF
1001 _IO_marker_difference (mark1, mark2)
1002 struct _IO_marker *mark1;
1003 struct _IO_marker *mark2;
1005 return mark1->_pos - mark2->_pos;
1008 /* Return difference between MARK and current position of MARK's stream. */
1010 _IO_marker_delta (mark)
1011 struct _IO_marker *mark;
1013 int cur_pos;
1014 if (mark->_sbuf == NULL)
1015 return BAD_DELTA;
1016 if (_IO_in_backup (mark->_sbuf))
1017 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
1018 else
1019 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
1020 return mark->_pos - cur_pos;
1024 _IO_seekmark (fp, mark, delta)
1025 _IO_FILE *fp;
1026 struct _IO_marker *mark;
1027 int delta;
1029 if (mark->_sbuf != fp)
1030 return EOF;
1031 if (mark->_pos >= 0)
1033 if (_IO_in_backup (fp))
1034 _IO_switch_to_main_get_area (fp);
1035 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
1037 else
1039 if (!_IO_in_backup (fp))
1040 _IO_switch_to_backup_area (fp);
1041 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
1043 return 0;
1046 void
1047 _IO_unsave_markers (fp)
1048 _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 INTUSE(_IO_free_backup_area) (fp);
1073 INTDEF(_IO_unsave_markers)
1075 #if 0
1076 /* Seems not to be needed. --drepper */
1078 _IO_nobackup_pbackfail (fp, c)
1079 _IO_FILE *fp;
1080 int c;
1082 if (fp->_IO_read_ptr > fp->_IO_read_base)
1083 fp->_IO_read_ptr--;
1084 if (c != EOF && *fp->_IO_read_ptr != c)
1085 *fp->_IO_read_ptr = c;
1086 return (unsigned char) c;
1088 #endif
1091 _IO_default_pbackfail (fp, c)
1092 _IO_FILE *fp;
1093 int c;
1095 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
1096 && (unsigned char) fp->_IO_read_ptr[-1] == c)
1097 --fp->_IO_read_ptr;
1098 else
1100 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
1101 if (!_IO_in_backup (fp))
1103 /* We need to keep the invariant that the main get area
1104 logically follows the backup area. */
1105 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
1107 if (save_for_backup (fp, fp->_IO_read_ptr))
1108 return EOF;
1110 else if (!_IO_have_backup (fp))
1112 /* No backup buffer: allocate one. */
1113 /* Use nshort buffer, if unused? (probably not) FIXME */
1114 int backup_size = 128;
1115 char *bbuf = (char *) malloc (backup_size);
1116 if (bbuf == NULL)
1117 return EOF;
1118 fp->_IO_save_base = bbuf;
1119 fp->_IO_save_end = fp->_IO_save_base + backup_size;
1120 fp->_IO_backup_base = fp->_IO_save_end;
1122 fp->_IO_read_base = fp->_IO_read_ptr;
1123 _IO_switch_to_backup_area (fp);
1125 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
1127 /* Increase size of existing backup buffer. */
1128 _IO_size_t new_size;
1129 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
1130 char *new_buf;
1131 new_size = 2 * old_size;
1132 new_buf = (char *) malloc (new_size);
1133 if (new_buf == NULL)
1134 return EOF;
1135 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
1136 old_size);
1137 free (fp->_IO_read_base);
1138 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
1139 new_buf + new_size);
1140 fp->_IO_backup_base = fp->_IO_read_ptr;
1143 *--fp->_IO_read_ptr = c;
1145 return (unsigned char) c;
1147 INTDEF(_IO_default_pbackfail)
1149 _IO_off64_t
1150 _IO_default_seek (fp, offset, dir)
1151 _IO_FILE *fp;
1152 _IO_off64_t offset;
1153 int dir;
1155 return _IO_pos_BAD;
1159 _IO_default_stat (fp, st)
1160 _IO_FILE *fp;
1161 void* st;
1163 return EOF;
1166 _IO_ssize_t
1167 _IO_default_read (fp, data, n)
1168 _IO_FILE* fp;
1169 void *data;
1170 _IO_ssize_t n;
1172 return -1;
1175 _IO_ssize_t
1176 _IO_default_write (fp, data, n)
1177 _IO_FILE *fp;
1178 const void *data;
1179 _IO_ssize_t n;
1181 return 0;
1185 _IO_default_showmanyc (fp)
1186 _IO_FILE *fp;
1188 return -1;
1191 void
1192 _IO_default_imbue (fp, locale)
1193 _IO_FILE *fp;
1194 void *locale;
1198 _IO_ITER
1199 _IO_iter_begin()
1201 return (_IO_ITER) INTUSE(_IO_list_all);
1203 libc_hidden_def (_IO_iter_begin)
1205 _IO_ITER
1206 _IO_iter_end()
1208 return NULL;
1210 libc_hidden_def (_IO_iter_end)
1212 _IO_ITER
1213 _IO_iter_next(iter)
1214 _IO_ITER iter;
1216 return iter->_chain;
1218 libc_hidden_def (_IO_iter_next)
1220 _IO_FILE *
1221 _IO_iter_file(iter)
1222 _IO_ITER iter;
1224 return iter;
1226 libc_hidden_def (_IO_iter_file)
1228 void
1229 _IO_list_lock()
1231 #ifdef _IO_MTSAFE_IO
1232 _IO_lock_lock (list_all_lock);
1233 #endif
1235 libc_hidden_def (_IO_list_lock)
1237 void
1238 _IO_list_unlock()
1240 #ifdef _IO_MTSAFE_IO
1241 _IO_lock_unlock (list_all_lock);
1242 #endif
1244 libc_hidden_def (_IO_list_unlock)
1246 void
1247 _IO_list_resetlock()
1249 #ifdef _IO_MTSAFE_IO
1250 _IO_lock_init (list_all_lock);
1251 #endif
1253 libc_hidden_def (_IO_list_resetlock)
1256 #ifdef TODO
1257 #if defined(linux)
1258 #define IO_CLEANUP ;
1259 #endif
1261 #ifdef IO_CLEANUP
1262 IO_CLEANUP
1263 #else
1264 struct __io_defs {
1265 __io_defs() { }
1266 ~__io_defs() { _IO_cleanup (); }
1268 __io_defs io_defs__;
1269 #endif
1271 #endif /* TODO */
1273 #ifdef text_set_element
1274 text_set_element(__libc_atexit, _IO_cleanup);
1275 #endif