Update.
[glibc.git] / libio / genops.c
blob30bceb62749f1502ec7433061d48dc428d368a51
1 /* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2, or (at
7 your option) any later version.
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this library; see the file COPYING. If not, write to
16 the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
17 MA 02111-1307, USA.
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does
21 not cause the resulting executable to be covered by the GNU General
22 Public License. This exception does not however invalidate any
23 other reasons why the executable file might be covered by the GNU
24 General Public License. */
26 /* Generic or default I/O operations. */
28 #include "libioP.h"
29 #ifdef __STDC__
30 #include <stdlib.h>
31 #endif
32 #include <string.h>
34 void
35 _IO_un_link (fp)
36 _IO_FILE *fp;
38 if (fp->_flags & _IO_LINKED)
40 _IO_FILE **f;
41 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
43 if (*f == fp)
45 *f = fp->_chain;
46 break;
49 fp->_flags &= ~_IO_LINKED;
53 void
54 _IO_link_in (fp)
55 _IO_FILE *fp;
57 if ((fp->_flags & _IO_LINKED) == 0)
59 fp->_flags |= _IO_LINKED;
60 fp->_chain = _IO_list_all;
61 _IO_list_all = fp;
65 /* Return minimum _pos markers
66 Assumes the current get area is the main get area. */
67 static _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
69 static _IO_ssize_t
70 _IO_least_marker (fp, end_p)
71 _IO_FILE *fp;
72 char *end_p;
74 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
75 struct _IO_marker *mark;
76 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
77 if (mark->_pos < least_so_far)
78 least_so_far = mark->_pos;
79 return least_so_far;
82 /* Switch current get area from backup buffer to (start of) main get area. */
84 void
85 _IO_switch_to_main_get_area (fp)
86 _IO_FILE *fp;
88 char *tmp;
89 fp->_flags &= ~_IO_IN_BACKUP;
90 /* Swap _IO_read_end and _IO_save_end. */
91 tmp = fp->_IO_read_end;
92 fp->_IO_read_end = fp->_IO_save_end;
93 fp->_IO_save_end= tmp;
94 /* Swap _IO_read_base and _IO_save_base. */
95 tmp = fp->_IO_read_base;
96 fp->_IO_read_base = fp->_IO_save_base;
97 fp->_IO_save_base = tmp;
98 /* Set _IO_read_ptr. */
99 fp->_IO_read_ptr = fp->_IO_read_base;
102 /* Switch current get area from main get area to (end of) backup area. */
104 void
105 _IO_switch_to_backup_area (fp)
106 _IO_FILE *fp;
108 char *tmp;
109 fp->_flags |= _IO_IN_BACKUP;
110 /* Swap _IO_read_end and _IO_save_end. */
111 tmp = fp->_IO_read_end;
112 fp->_IO_read_end = fp->_IO_save_end;
113 fp->_IO_save_end = tmp;
114 /* Swap _IO_read_base and _IO_save_base. */
115 tmp = fp->_IO_read_base;
116 fp->_IO_read_base = fp->_IO_save_base;
117 fp->_IO_save_base = tmp;
118 /* Set _IO_read_ptr. */
119 fp->_IO_read_ptr = fp->_IO_read_end;
123 _IO_switch_to_get_mode (fp)
124 _IO_FILE *fp;
126 if (fp->_IO_write_ptr > fp->_IO_write_base)
127 if (_IO_OVERFLOW (fp, EOF) == EOF)
128 return EOF;
129 if (_IO_in_backup (fp))
130 fp->_IO_read_base = fp->_IO_backup_base;
131 else
133 fp->_IO_read_base = fp->_IO_buf_base;
134 if (fp->_IO_write_ptr > fp->_IO_read_end)
135 fp->_IO_read_end = fp->_IO_write_ptr;
137 fp->_IO_read_ptr = fp->_IO_write_ptr;
139 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
141 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
142 return 0;
145 void
146 _IO_free_backup_area (fp)
147 _IO_FILE *fp;
149 if (_IO_in_backup (fp))
150 _IO_switch_to_main_get_area (fp); /* Just in case. */
151 free (fp->_IO_save_base);
152 fp->_IO_save_base = NULL;
153 fp->_IO_save_end = NULL;
154 fp->_IO_backup_base = NULL;
157 #if 0
159 _IO_switch_to_put_mode (fp)
160 _IO_FILE *fp;
162 fp->_IO_write_base = fp->_IO_read_ptr;
163 fp->_IO_write_ptr = fp->_IO_read_ptr;
164 /* Following is wrong if line- or un-buffered? */
165 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
166 ? fp->_IO_read_end : fp->_IO_buf_end);
168 fp->_IO_read_ptr = fp->_IO_read_end;
169 fp->_IO_read_base = fp->_IO_read_end;
171 fp->_flags |= _IO_CURRENTLY_PUTTING;
172 return 0;
174 #endif
177 __overflow (f, ch)
178 _IO_FILE *f;
179 int ch;
181 return _IO_OVERFLOW (f, ch);
184 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
185 #ifdef _LIBC
186 internal_function
187 #endif
190 static int
191 #ifdef _LIBC
192 internal_function
193 #endif
194 save_for_backup (fp, end_p)
195 _IO_FILE *fp;
196 char *end_p;
198 /* Append [_IO_read_base..end_p] to backup area. */
199 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
200 /* needed_size is how much space we need in the backup area. */
201 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
202 /* FIXME: Dubious arithmetic if pointers are NULL */
203 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
204 _IO_size_t avail; /* Extra space available for future expansion. */
205 _IO_ssize_t delta;
206 struct _IO_marker *mark;
207 if (needed_size > current_Bsize)
209 char *new_buffer;
210 avail = 100;
211 new_buffer = (char *) malloc (avail + needed_size);
212 if (new_buffer == NULL)
213 return EOF; /* FIXME */
214 if (least_mark < 0)
216 #ifdef _LIBC
217 __mempcpy (__mempcpy (new_buffer + avail,
218 fp->_IO_save_end + least_mark,
219 -least_mark),
220 fp->_IO_read_base,
221 end_p - fp->_IO_read_base);
222 #else
223 memcpy (new_buffer + avail,
224 fp->_IO_save_end + least_mark,
225 -least_mark);
226 memcpy (new_buffer + avail - least_mark,
227 fp->_IO_read_base,
228 end_p - fp->_IO_read_base);
229 #endif
231 else
232 memcpy (new_buffer + avail,
233 fp->_IO_read_base + least_mark,
234 needed_size);
235 if (fp->_IO_save_base)
236 free (fp->_IO_save_base);
237 fp->_IO_save_base = new_buffer;
238 fp->_IO_save_end = new_buffer + avail + needed_size;
240 else
242 avail = current_Bsize - needed_size;
243 if (least_mark < 0)
245 memmove (fp->_IO_save_base + avail,
246 fp->_IO_save_end + least_mark,
247 -least_mark);
248 memcpy (fp->_IO_save_base + avail - least_mark,
249 fp->_IO_read_base,
250 end_p - fp->_IO_read_base);
252 else if (needed_size > 0)
253 memcpy (fp->_IO_save_base + avail,
254 fp->_IO_read_base + least_mark,
255 needed_size);
257 fp->_IO_backup_base = fp->_IO_save_base + avail;
258 /* Adjust all the streammarkers. */
259 delta = end_p - fp->_IO_read_base;
260 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
261 mark->_pos -= delta;
262 return 0;
266 __underflow (fp)
267 _IO_FILE *fp;
269 if (_IO_in_put_mode (fp))
270 if (_IO_switch_to_get_mode (fp) == EOF)
271 return EOF;
272 if (fp->_IO_read_ptr < fp->_IO_read_end)
273 return *(unsigned char *) fp->_IO_read_ptr;
274 if (_IO_in_backup (fp))
276 _IO_switch_to_main_get_area (fp);
277 if (fp->_IO_read_ptr < fp->_IO_read_end)
278 return *(unsigned char *) fp->_IO_read_ptr;
280 if (_IO_have_markers (fp))
282 if (save_for_backup (fp, fp->_IO_read_end))
283 return EOF;
285 else if (_IO_have_backup (fp))
286 _IO_free_backup_area (fp);
287 return _IO_UNDERFLOW (fp);
291 __uflow (fp)
292 _IO_FILE *fp;
294 if (_IO_in_put_mode (fp))
295 if (_IO_switch_to_get_mode (fp) == EOF)
296 return EOF;
297 if (fp->_IO_read_ptr < fp->_IO_read_end)
298 return *(unsigned char *) fp->_IO_read_ptr++;
299 if (_IO_in_backup (fp))
301 _IO_switch_to_main_get_area (fp);
302 if (fp->_IO_read_ptr < fp->_IO_read_end)
303 return *(unsigned char *) fp->_IO_read_ptr++;
305 if (_IO_have_markers (fp))
307 if (save_for_backup (fp, fp->_IO_read_end))
308 return EOF;
310 else if (_IO_have_backup (fp))
311 _IO_free_backup_area (fp);
312 return _IO_UFLOW (fp);
315 void
316 _IO_setb (f, b, eb, a)
317 _IO_FILE *f;
318 char *b;
319 char *eb;
320 int a;
322 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
323 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
324 f->_IO_buf_base = b;
325 f->_IO_buf_end = eb;
326 if (a)
327 f->_flags &= ~_IO_USER_BUF;
328 else
329 f->_flags |= _IO_USER_BUF;
332 void
333 _IO_doallocbuf (fp)
334 _IO_FILE *fp;
336 if (fp->_IO_buf_base)
337 return;
338 if (!(fp->_flags & _IO_UNBUFFERED))
339 if (_IO_DOALLOCATE (fp) != EOF)
340 return;
341 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
345 _IO_default_underflow (fp)
346 _IO_FILE *fp;
348 return EOF;
352 _IO_default_uflow (fp)
353 _IO_FILE *fp;
355 int ch = _IO_UNDERFLOW (fp);
356 if (ch == EOF)
357 return EOF;
358 return *(unsigned char *) fp->_IO_read_ptr++;
361 _IO_size_t
362 _IO_default_xsputn (f, data, n)
363 _IO_FILE *f;
364 const void *data;
365 _IO_size_t n;
367 const char *s = (char *) data;
368 _IO_size_t more = n;
369 if (more <= 0)
370 return 0;
371 for (;;)
373 /* Space available. */
374 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
375 if (count > 0)
377 if ((_IO_size_t) count > more)
378 count = more;
379 if (count > 20)
381 #ifdef _LIBC
382 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
383 #else
384 memcpy (f->_IO_write_ptr, s, count);
385 f->_IO_write_ptr += count;
386 #endif
387 s += count;
389 else if (count <= 0)
390 count = 0;
391 else
393 char *p = f->_IO_write_ptr;
394 _IO_ssize_t i;
395 for (i = count; --i >= 0; )
396 *p++ = *s++;
397 f->_IO_write_ptr = p;
399 more -= count;
401 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
402 break;
403 more--;
405 return n - more;
408 _IO_size_t
409 _IO_sgetn (fp, data, n)
410 _IO_FILE *fp;
411 void *data;
412 _IO_size_t n;
414 /* FIXME handle putback buffer here! */
415 return _IO_XSGETN (fp, data, n);
418 _IO_size_t
419 _IO_default_xsgetn (fp, data, n)
420 _IO_FILE *fp;
421 void *data;
422 _IO_size_t n;
424 _IO_size_t more = n;
425 char *s = (char*) data;
426 for (;;)
428 /* Data available. */
429 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
430 if (count > 0)
432 if ((_IO_size_t) count > more)
433 count = more;
434 if (count > 20)
436 #ifdef _LIBC
437 s = __mempcpy (s, fp->_IO_read_ptr, count);
438 #else
439 memcpy (s, fp->_IO_read_ptr, count);
440 s += count;
441 #endif
442 fp->_IO_read_ptr += count;
444 else if (count <= 0)
445 count = 0;
446 else
448 char *p = fp->_IO_read_ptr;
449 int i = (int) count;
450 while (--i >= 0)
451 *s++ = *p++;
452 fp->_IO_read_ptr = p;
454 more -= count;
456 if (more == 0 || __underflow (fp) == EOF)
457 break;
459 return n - more;
462 #if 0
463 /* Seems not to be needed. --drepper */
465 _IO_sync (fp)
466 _IO_FILE *fp;
468 return 0;
470 #endif
472 _IO_FILE *
473 _IO_default_setbuf (fp, p, len)
474 _IO_FILE *fp;
475 char *p;
476 _IO_ssize_t len;
478 if (_IO_SYNC (fp) == EOF)
479 return NULL;
480 if (p == NULL || len == 0)
482 fp->_flags |= _IO_UNBUFFERED;
483 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
485 else
487 fp->_flags &= ~_IO_UNBUFFERED;
488 _IO_setb (fp, p, p+len, 0);
490 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
491 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
492 return fp;
495 _IO_fpos64_t
496 _IO_default_seekpos (fp, pos, mode)
497 _IO_FILE *fp;
498 _IO_fpos64_t pos;
499 int mode;
501 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
505 _IO_default_doallocate (fp)
506 _IO_FILE *fp;
508 char *buf;
510 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
511 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
512 return 1;
515 void
516 _IO_init (fp, flags)
517 _IO_FILE *fp;
518 int flags;
520 fp->_flags = _IO_MAGIC|flags;
521 fp->_IO_buf_base = NULL;
522 fp->_IO_buf_end = NULL;
523 fp->_IO_read_base = NULL;
524 fp->_IO_read_ptr = NULL;
525 fp->_IO_read_end = NULL;
526 fp->_IO_write_base = NULL;
527 fp->_IO_write_ptr = NULL;
528 fp->_IO_write_end = NULL;
529 fp->_chain = NULL; /* Not necessary. */
531 fp->_IO_save_base = NULL;
532 fp->_IO_backup_base = NULL;
533 fp->_IO_save_end = NULL;
534 fp->_markers = NULL;
535 fp->_cur_column = 0;
536 #if _IO_JUMPS_OFFSET
537 fp->_vtable_offset = 0;
538 #endif
539 #ifdef _IO_MTSAFE_IO
540 _IO_lock_init (*fp->_lock);
541 #endif
545 _IO_default_sync (fp)
546 _IO_FILE *fp;
548 return 0;
551 /* The way the C++ classes are mapped into the C functions in the
552 current implementation, this function can get called twice! */
554 void
555 _IO_default_finish (fp, dummy)
556 _IO_FILE *fp;
557 int dummy;
559 struct _IO_marker *mark;
560 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
562 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
563 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
566 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
567 mark->_sbuf = NULL;
569 if (fp->_IO_save_base)
571 free (fp->_IO_save_base);
572 fp->_IO_save_base = NULL;
575 #ifdef _IO_MTSAFE_IO
576 _IO_lock_fini (*fp->_lock);
577 #endif
579 _IO_un_link (fp);
582 _IO_fpos64_t
583 _IO_default_seekoff (fp, offset, dir, mode)
584 _IO_FILE *fp;
585 _IO_off64_t offset;
586 int dir;
587 int mode;
589 return _IO_pos_BAD;
593 _IO_sputbackc (fp, c)
594 _IO_FILE *fp;
595 int c;
597 int result;
599 if (fp->_IO_read_ptr > fp->_IO_read_base
600 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
602 fp->_IO_read_ptr--;
603 result = (unsigned char) c;
605 else
606 result = _IO_PBACKFAIL (fp, c);
608 if (result != EOF)
609 fp->_flags &= ~_IO_EOF_SEEN;
611 return result;
615 _IO_sungetc (fp)
616 _IO_FILE *fp;
618 int result;
620 if (fp->_IO_read_ptr > fp->_IO_read_base)
622 fp->_IO_read_ptr--;
623 result = (unsigned char) *fp->_IO_read_ptr;
625 else
626 result = _IO_PBACKFAIL (fp, EOF);
628 if (result != EOF)
629 fp->_flags &= ~_IO_EOF_SEEN;
631 return result;
634 #if 0 /* Work in progress */
635 /* Seems not to be needed. */
636 #if 0
637 void
638 _IO_set_column (fp, c)
639 _IO_FILE *fp;
640 int c;
642 if (c == -1)
643 fp->_column = -1;
644 else
645 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
647 #else
649 _IO_set_column (fp, i)
650 _IO_FILE *fp;
651 int i;
653 fp->_cur_column = i + 1;
654 return 0;
656 #endif
657 #endif
660 unsigned
661 _IO_adjust_column (start, line, count)
662 unsigned start;
663 const char *line;
664 int count;
666 const char *ptr = line + count;
667 while (ptr > line)
668 if (*--ptr == '\n')
669 return line + count - ptr - 1;
670 return start + count;
673 #if 0
674 /* Seems not to be needed. --drepper */
676 _IO_get_column (fp)
677 _IO_FILE *fp;
679 if (fp->_cur_column)
680 return _IO_adjust_column (fp->_cur_column - 1,
681 fp->_IO_write_base,
682 fp->_IO_write_ptr - fp->_IO_write_base);
683 return -1;
685 #endif
688 _IO_flush_all ()
690 int result = 0;
691 _IO_FILE *fp;
692 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
693 if (fp->_IO_write_ptr > fp->_IO_write_base
694 && _IO_OVERFLOW (fp, EOF) == EOF)
695 result = EOF;
696 return result;
699 void
700 _IO_flush_all_linebuffered ()
702 _IO_FILE *fp;
703 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
704 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
705 _IO_OVERFLOW (fp, EOF);
708 static void _IO_unbuffer_write __P ((void));
710 static void
711 _IO_unbuffer_write ()
713 _IO_FILE *fp;
714 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
715 if (! (fp->_flags & _IO_UNBUFFERED)
716 && (! (fp->_flags & _IO_NO_WRITES)
717 || (fp->_flags & _IO_IS_APPENDING)))
718 _IO_SETBUF (fp, NULL, 0);
722 _IO_cleanup ()
724 int result = _IO_flush_all ();
726 /* We currently don't have a reliable mechanism for making sure that
727 C++ static destructors are executed in the correct order.
728 So it is possible that other static destructors might want to
729 write to cout - and they're supposed to be able to do so.
731 The following will make the standard streambufs be unbuffered,
732 which forces any output from late destructors to be written out. */
733 _IO_unbuffer_write ();
735 return result;
739 void
740 _IO_init_marker (marker, fp)
741 struct _IO_marker *marker;
742 _IO_FILE *fp;
744 marker->_sbuf = fp;
745 if (_IO_in_put_mode (fp))
746 _IO_switch_to_get_mode (fp);
747 if (_IO_in_backup (fp))
748 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
749 else
750 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
752 /* Should perhaps sort the chain? */
753 marker->_next = fp->_markers;
754 fp->_markers = marker;
757 void
758 _IO_remove_marker (marker)
759 struct _IO_marker *marker;
761 /* Unlink from sb's chain. */
762 struct _IO_marker **ptr = &marker->_sbuf->_markers;
763 for (; ; ptr = &(*ptr)->_next)
765 if (*ptr == NULL)
766 break;
767 else if (*ptr == marker)
769 *ptr = marker->_next;
770 return;
773 #if 0
774 if _sbuf has a backup area that is no longer needed, should we delete
775 it now, or wait until the next underflow?
776 #endif
779 #define BAD_DELTA EOF
782 _IO_marker_difference (mark1, mark2)
783 struct _IO_marker *mark1;
784 struct _IO_marker *mark2;
786 return mark1->_pos - mark2->_pos;
789 /* Return difference between MARK and current position of MARK's stream. */
791 _IO_marker_delta (mark)
792 struct _IO_marker *mark;
794 int cur_pos;
795 if (mark->_sbuf == NULL)
796 return BAD_DELTA;
797 if (_IO_in_backup (mark->_sbuf))
798 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
799 else
800 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
801 return mark->_pos - cur_pos;
805 _IO_seekmark (fp, mark, delta)
806 _IO_FILE *fp;
807 struct _IO_marker *mark;
808 int delta;
810 if (mark->_sbuf != fp)
811 return EOF;
812 if (mark->_pos >= 0)
814 if (_IO_in_backup (fp))
815 _IO_switch_to_main_get_area (fp);
816 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
818 else
820 if (!_IO_in_backup (fp))
821 _IO_switch_to_backup_area (fp);
822 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
824 return 0;
827 void
828 _IO_unsave_markers (fp)
829 _IO_FILE *fp;
831 struct _IO_marker *mark = fp->_markers;
832 if (mark)
834 #ifdef TODO
835 streampos offset = seekoff (0, ios::cur, ios::in);
836 if (offset != EOF)
838 offset += eGptr () - Gbase ();
839 for ( ; mark != NULL; mark = mark->_next)
840 mark->set_streampos (mark->_pos + offset);
842 else
844 for ( ; mark != NULL; mark = mark->_next)
845 mark->set_streampos (EOF);
847 #endif
848 fp->_markers = 0;
851 if (_IO_have_backup (fp))
852 _IO_free_backup_area (fp);
855 #if 0
856 /* Seems not to be needed. --drepper */
858 _IO_nobackup_pbackfail (fp, c)
859 _IO_FILE *fp;
860 int c;
862 if (fp->_IO_read_ptr > fp->_IO_read_base)
863 fp->_IO_read_ptr--;
864 if (c != EOF && *fp->_IO_read_ptr != c)
865 *fp->_IO_read_ptr = c;
866 return (unsigned char) c;
868 #endif
871 _IO_default_pbackfail (fp, c)
872 _IO_FILE *fp;
873 int c;
875 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
876 && (unsigned char) fp->_IO_read_ptr[-1] == c)
877 --fp->_IO_read_ptr;
878 else
880 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
881 if (!_IO_in_backup (fp))
883 /* We need to keep the invariant that the main get area
884 logically follows the backup area. */
885 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
887 if (save_for_backup (fp, fp->_IO_read_ptr))
888 return EOF;
890 else if (!_IO_have_backup (fp))
892 /* No backup buffer: allocate one. */
893 /* Use nshort buffer, if unused? (probably not) FIXME */
894 int backup_size = 128;
895 char *bbuf = (char *) malloc (backup_size);
896 if (bbuf == NULL)
897 return EOF;
898 fp->_IO_save_base = bbuf;
899 fp->_IO_save_end = fp->_IO_save_base + backup_size;
900 fp->_IO_backup_base = fp->_IO_save_end;
902 fp->_IO_read_base = fp->_IO_read_ptr;
903 _IO_switch_to_backup_area (fp);
905 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
907 /* Increase size of existing backup buffer. */
908 _IO_size_t new_size;
909 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
910 char *new_buf;
911 new_size = 2 * old_size;
912 new_buf = (char *) malloc (new_size);
913 if (new_buf == NULL)
914 return EOF;
915 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
916 old_size);
917 free (fp->_IO_read_base);
918 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
919 new_buf + new_size);
920 fp->_IO_backup_base = fp->_IO_read_ptr;
923 *--fp->_IO_read_ptr = c;
925 return (unsigned char) c;
928 _IO_fpos64_t
929 _IO_default_seek (fp, offset, dir)
930 _IO_FILE *fp;
931 _IO_off64_t offset;
932 int dir;
934 return _IO_pos_BAD;
938 _IO_default_stat (fp, st)
939 _IO_FILE *fp;
940 void* st;
942 return EOF;
945 _IO_ssize_t
946 _IO_default_read (fp, data, n)
947 _IO_FILE* fp;
948 void *data;
949 _IO_ssize_t n;
951 return -1;
954 _IO_ssize_t
955 _IO_default_write (fp, data, n)
956 _IO_FILE *fp;
957 const void *data;
958 _IO_ssize_t n;
960 return 0;
964 _IO_default_showmanyc (fp)
965 _IO_FILE *fp;
967 return -1;
970 void
971 _IO_default_imbue (fp, locale)
972 _IO_FILE *fp;
973 void *locale;
978 #ifdef TODO
979 #if defined(linux)
980 #define IO_CLEANUP ;
981 #endif
983 #ifdef IO_CLEANUP
984 IO_CLEANUP
985 #else
986 struct __io_defs {
987 __io_defs() { }
988 ~__io_defs() { _IO_cleanup (); }
990 __io_defs io_defs__;
991 #endif
993 #endif /* TODO */
995 #ifdef weak_alias
996 weak_alias (_IO_cleanup, _cleanup)
997 #endif
999 #ifdef text_set_element
1000 text_set_element(__libc_atexit, _cleanup);
1001 #endif