2000-12-19 Mark Kettenis <kettenis@gnu.org>
[official-gcc.git] / libio / genops.c
blobb899e150afabf483e32ebd24b8dc4d033e62fcde
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_size_t _IO_least_marker __P ((_IO_FILE *fp));
69 static _IO_size_t
70 _IO_least_marker (fp)
71 _IO_FILE *fp;
73 _IO_ssize_t least_so_far = fp->_IO_read_end - fp->_IO_read_base;
74 struct _IO_marker *mark;
75 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
76 if (mark->_pos < least_so_far)
77 least_so_far = mark->_pos;
78 return least_so_far;
81 /* Switch current get area from backup buffer to (start of) main get area. */
83 void
84 _IO_switch_to_main_get_area (fp)
85 _IO_FILE *fp;
87 char *tmp;
88 fp->_flags &= ~_IO_IN_BACKUP;
89 /* Swap _IO_read_end and _IO_save_end. */
90 tmp = fp->_IO_read_end;
91 fp->_IO_read_end = fp->_IO_save_end;
92 fp->_IO_save_end= tmp;
93 /* Swap _IO_read_base and _IO_save_base. */
94 tmp = fp->_IO_read_base;
95 fp->_IO_read_base = fp->_IO_save_base;
96 fp->_IO_save_base = tmp;
98 fp->_IO_read_ptr = fp->_IO_read_base;
101 /* Switch current get area from main get area to (end of) backup area. */
103 void
104 _IO_switch_to_backup_area (fp)
105 _IO_FILE *fp;
107 char *tmp;
108 fp->_flags |= _IO_IN_BACKUP;
109 /* Swap _IO_read_end and _IO_save_end. */
110 tmp = fp->_IO_read_end;
111 fp->_IO_read_end = fp->_IO_save_end;
112 fp->_IO_save_end = tmp;
113 /* Swap _gbase and _IO_save_base. */
114 tmp = fp->_IO_read_base;
115 fp->_IO_read_base = fp->_IO_save_base;
116 fp->_IO_save_base = tmp;
118 fp->_IO_read_ptr = fp->_IO_read_end;
122 _IO_switch_to_get_mode (fp)
123 _IO_FILE *fp;
125 if (fp->_IO_write_ptr > fp->_IO_write_base)
126 if (_IO_OVERFLOW (fp, EOF) == EOF)
127 return EOF;
128 if (_IO_in_backup (fp))
129 fp->_IO_read_base = fp->_IO_backup_base;
130 else
132 fp->_IO_read_base = fp->_IO_buf_base;
133 if (fp->_IO_write_ptr > fp->_IO_read_end)
134 fp->_IO_read_end = fp->_IO_write_ptr;
136 fp->_IO_read_ptr = fp->_IO_write_ptr;
138 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
140 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
141 return 0;
144 void
145 _IO_free_backup_area (fp)
146 _IO_FILE *fp;
148 if (_IO_in_backup (fp))
149 _IO_switch_to_main_get_area (fp); /* Just in case. */
150 free (fp->_IO_save_base);
151 fp->_IO_save_base = NULL;
152 fp->_IO_save_end = NULL;
153 fp->_IO_backup_base = NULL;
156 #if 0
158 _IO_switch_to_put_mode (fp)
159 _IO_FILE *fp;
161 fp->_IO_write_base = fp->_IO_read_ptr;
162 fp->_IO_write_ptr = fp->_IO_read_ptr;
163 /* Following is wrong if line- or un-buffered? */
164 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
165 ? fp->_IO_read_end : fp->_IO_buf_end);
167 fp->_IO_read_ptr = fp->_IO_read_end;
168 fp->_IO_read_base = fp->_IO_read_end;
170 fp->_flags |= _IO_CURRENTLY_PUTTING;
171 return 0;
173 #endif
176 __overflow (f, ch)
177 _IO_FILE *f;
178 int ch;
180 return _IO_OVERFLOW (f, ch);
183 static int save_for_backup __P ((_IO_FILE *fp));
185 static int
186 save_for_backup (fp)
187 _IO_FILE *fp;
189 /* Append [_IO_read_base.._IO_read_end] to backup area. */
190 int least_mark = _IO_least_marker (fp);
191 /* needed_size is how much space we need in the backup area. */
192 int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
193 int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
194 int avail; /* Extra space available for future expansion. */
195 int delta;
196 struct _IO_marker *mark;
197 if (needed_size > current_Bsize)
199 char *new_buffer;
200 avail = 100;
201 new_buffer = (char *) malloc (avail + needed_size);
202 if (new_buffer == NULL)
203 return EOF; /* FIXME */
204 if (least_mark < 0)
206 memcpy (new_buffer + avail,
207 fp->_IO_save_end + least_mark,
208 -least_mark);
209 memcpy (new_buffer + avail - least_mark,
210 fp->_IO_read_base,
211 fp->_IO_read_end - fp->_IO_read_base);
213 else
214 memcpy (new_buffer + avail,
215 fp->_IO_read_base + least_mark,
216 needed_size);
217 if (fp->_IO_save_base)
218 free (fp->_IO_save_base);
219 fp->_IO_save_base = new_buffer;
220 fp->_IO_save_end = new_buffer + avail + needed_size;
222 else
224 avail = current_Bsize - needed_size;
225 if (least_mark < 0)
227 memmove (fp->_IO_save_base + avail,
228 fp->_IO_save_end + least_mark,
229 -least_mark);
230 memcpy (fp->_IO_save_base + avail - least_mark,
231 fp->_IO_read_base,
232 fp->_IO_read_end - fp->_IO_read_base);
234 else if (needed_size > 0)
235 memcpy (fp->_IO_save_base + avail,
236 fp->_IO_read_base + least_mark,
237 needed_size);
239 /* FIXME: Dubious arithmetic if pointers are NULL */
240 fp->_IO_backup_base = fp->_IO_save_base + avail;
241 /* Adjust all the streammarkers. */
242 delta = fp->_IO_read_end - fp->_IO_read_base;
243 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
244 mark->_pos -= delta;
245 return 0;
249 __underflow (fp)
250 _IO_FILE *fp;
252 if (_IO_in_put_mode (fp))
253 if (_IO_switch_to_get_mode (fp) == EOF)
254 return EOF;
255 if (fp->_IO_read_ptr < fp->_IO_read_end)
256 return *(unsigned char *) fp->_IO_read_ptr;
257 if (_IO_in_backup (fp))
259 _IO_switch_to_main_get_area (fp);
260 if (fp->_IO_read_ptr < fp->_IO_read_end)
261 return *(unsigned char *) fp->_IO_read_ptr;
263 if (_IO_have_markers (fp))
265 if (save_for_backup (fp))
266 return EOF;
268 else if (_IO_have_backup (fp))
269 _IO_free_backup_area (fp);
270 return _IO_UNDERFLOW (fp);
274 __uflow (fp)
275 _IO_FILE *fp;
277 if (_IO_in_put_mode (fp))
278 if (_IO_switch_to_get_mode (fp) == EOF)
279 return EOF;
280 if (fp->_IO_read_ptr < fp->_IO_read_end)
281 return *(unsigned char *) fp->_IO_read_ptr++;
282 if (_IO_in_backup (fp))
284 _IO_switch_to_main_get_area (fp);
285 if (fp->_IO_read_ptr < fp->_IO_read_end)
286 return *(unsigned char *) fp->_IO_read_ptr++;
288 if (_IO_have_markers (fp))
290 if (save_for_backup (fp))
291 return EOF;
293 else if (_IO_have_backup (fp))
294 _IO_free_backup_area (fp);
295 return _IO_UFLOW (fp);
298 void
299 _IO_setb (f, b, eb, a)
300 _IO_FILE *f;
301 char *b;
302 char *eb;
303 int a;
305 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
306 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
307 f->_IO_buf_base = b;
308 f->_IO_buf_end = eb;
309 if (a)
310 f->_flags &= ~_IO_USER_BUF;
311 else
312 f->_flags |= _IO_USER_BUF;
315 void
316 _IO_doallocbuf (fp)
317 _IO_FILE *fp;
319 if (fp->_IO_buf_base)
320 return;
321 if (!(fp->_flags & _IO_UNBUFFERED))
322 if (_IO_DOALLOCATE (fp) != EOF)
323 return;
324 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
328 _IO_default_underflow (fp)
329 _IO_FILE *fp;
331 return EOF;
335 _IO_default_uflow (fp)
336 _IO_FILE *fp;
338 int ch = _IO_UNDERFLOW (fp);
339 if (ch == EOF)
340 return EOF;
341 return *(unsigned char *) fp->_IO_read_ptr++;
344 _IO_size_t
345 _IO_default_xsputn (f, data, n)
346 _IO_FILE *f;
347 const void *data;
348 _IO_size_t n;
350 const char *s = (char *) data;
351 _IO_size_t more = n;
352 if (more <= 0)
353 return 0;
354 for (;;)
356 /* Space available. */
357 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
358 if (count > 0)
360 if ((_IO_size_t) count > more)
361 count = more;
362 if (count > 20)
364 memcpy (f->_IO_write_ptr, s, count);
365 s += count;
366 f->_IO_write_ptr += count;
368 else if (count <= 0)
369 count = 0;
370 else
372 char *p = f->_IO_write_ptr;
373 _IO_ssize_t i;
374 for (i = count; --i >= 0; )
375 *p++ = *s++;
376 f->_IO_write_ptr = p;
378 more -= count;
380 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
381 break;
382 more--;
384 return n - more;
387 _IO_size_t
388 _IO_sgetn (fp, data, n)
389 _IO_FILE *fp;
390 void *data;
391 _IO_size_t n;
393 /* FIXME handle putback buffer here! */
394 return _IO_XSGETN (fp, data, n);
397 _IO_size_t
398 _IO_default_xsgetn (fp, data, n)
399 _IO_FILE *fp;
400 void *data;
401 _IO_size_t n;
403 _IO_size_t more = n;
404 char *s = (char*) data;
405 for (;;)
407 /* Data available. */
408 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
409 if (count > 0)
411 if ((_IO_size_t) count > more)
412 count = more;
413 if (count > 20)
415 memcpy (s, fp->_IO_read_ptr, count);
416 s += count;
417 fp->_IO_read_ptr += count;
419 else if (count <= 0)
420 count = 0;
421 else
423 char *p = fp->_IO_read_ptr;
424 int i = (int) count;
425 while (--i >= 0)
426 *s++ = *p++;
427 fp->_IO_read_ptr = p;
429 more -= count;
431 if (more == 0 || __underflow (fp) == EOF)
432 break;
434 return n - more;
437 #if 0
438 /* Seems not to be needed. --drepper */
440 _IO_sync (fp)
441 _IO_FILE *fp;
443 return 0;
445 #endif
447 _IO_FILE *
448 _IO_default_setbuf (fp, p, len)
449 _IO_FILE *fp;
450 char *p;
451 _IO_ssize_t len;
453 if (_IO_SYNC (fp) == EOF)
454 return NULL;
455 if (p == NULL || len == 0)
457 fp->_flags |= _IO_UNBUFFERED;
458 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
460 else
462 fp->_flags &= ~_IO_UNBUFFERED;
463 _IO_setb (fp, p, p+len, 0);
465 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
466 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
467 return fp;
470 _IO_pos_t
471 _IO_default_seekpos (fp, pos, mode)
472 _IO_FILE *fp;
473 _IO_pos_t pos;
474 int mode;
476 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
480 _IO_default_doallocate (fp)
481 _IO_FILE *fp;
483 char *buf;
485 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
486 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
487 return 1;
490 void
491 _IO_init (fp, flags)
492 _IO_FILE *fp;
493 int flags;
495 fp->_flags = _IO_MAGIC|flags;
496 fp->_IO_buf_base = NULL;
497 fp->_IO_buf_end = NULL;
498 fp->_IO_read_base = NULL;
499 fp->_IO_read_ptr = NULL;
500 fp->_IO_read_end = NULL;
501 fp->_IO_write_base = NULL;
502 fp->_IO_write_ptr = NULL;
503 fp->_IO_write_end = NULL;
504 fp->_chain = NULL; /* Not necessary. */
506 fp->_IO_save_base = NULL;
507 fp->_IO_backup_base = NULL;
508 fp->_IO_save_end = NULL;
509 fp->_markers = NULL;
510 fp->_cur_column = 0;
511 #ifdef _IO_MTSAFE_IO
512 _IO_lock_init (*fp->_lock);
513 #endif
517 _IO_default_sync (fp)
518 _IO_FILE *fp;
520 return 0;
523 /* The way the C++ classes are mapped into the C functions in the
524 current implementation, this function can get called twice! */
526 void
527 _IO_default_finish (fp, dummy)
528 _IO_FILE *fp;
529 int dummy;
531 struct _IO_marker *mark;
532 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
534 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
535 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
538 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
539 mark->_sbuf = NULL;
541 if (fp->_IO_save_base)
543 free (fp->_IO_save_base);
544 fp->_IO_save_base = NULL;
547 #ifdef _IO_MTSAFE_IO
548 _IO_lock_fini (*fp->_lock);
549 #endif
551 _IO_un_link (fp);
554 _IO_pos_t
555 _IO_default_seekoff (fp, offset, dir, mode)
556 _IO_FILE *fp;
557 _IO_off_t offset;
558 int dir;
559 int mode;
561 return _IO_pos_BAD;
565 _IO_sputbackc (fp, c)
566 _IO_FILE *fp;
567 int c;
569 int result;
571 if (fp->_IO_read_ptr > fp->_IO_read_base
572 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
574 fp->_IO_read_ptr--;
575 result = (unsigned char) c;
577 else
578 result = _IO_PBACKFAIL (fp, c);
580 if (result != EOF)
581 fp->_flags &= ~_IO_EOF_SEEN;
583 return result;
587 _IO_sungetc (fp)
588 _IO_FILE *fp;
590 int result;
592 if (fp->_IO_read_ptr > fp->_IO_read_base)
594 fp->_IO_read_ptr--;
595 result = (unsigned char) *fp->_IO_read_ptr;
597 else
598 result = _IO_PBACKFAIL (fp, EOF);
600 if (result != EOF)
601 fp->_flags &= ~_IO_EOF_SEEN;
603 return result;
606 #if 0 /* Work in progress */
607 /* Seems not to be needed. */
608 #if 0
609 void
610 _IO_set_column (fp, c)
611 _IO_FILE *fp;
612 int c;
614 if (c == -1)
615 fp->_column = -1;
616 else
617 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
619 #else
621 _IO_set_column (fp, i)
622 _IO_FILE *fp;
623 int i;
625 fp->_cur_column = i + 1;
626 return 0;
628 #endif
629 #endif
632 unsigned
633 _IO_adjust_column (start, line, count)
634 unsigned start;
635 const char *line;
636 int count;
638 const char *ptr = line + count;
639 while (ptr > line)
640 if (*--ptr == '\n')
641 return line + count - ptr - 1;
642 return start + count;
645 #if 0
646 /* Seems not to be needed. --drepper */
648 _IO_get_column (fp)
649 _IO_FILE *fp;
651 if (fp->_cur_column)
652 return _IO_adjust_column (fp->_cur_column - 1,
653 fp->_IO_write_base,
654 fp->_IO_write_ptr - fp->_IO_write_base);
655 return -1;
657 #endif
660 _IO_flush_all ()
662 int result = 0;
663 _IO_FILE *fp;
664 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
665 if (fp->_IO_write_ptr > fp->_IO_write_base
666 && _IO_OVERFLOW (fp, EOF) == EOF)
667 result = EOF;
668 return result;
671 void
672 _IO_flush_all_linebuffered ()
674 _IO_FILE *fp;
675 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
676 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
677 _IO_OVERFLOW (fp, EOF);
680 static void _IO_unbuffer_all __P ((void));
682 static void
683 _IO_unbuffer_all ()
685 _IO_FILE *fp;
686 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
687 if (! (fp->_flags & _IO_UNBUFFERED))
688 _IO_SETBUF (fp, NULL, 0);
691 void
692 _IO_cleanup ()
694 _IO_flush_all ();
696 /* We currently don't have a reliable mechanism for making sure that
697 C++ static destructors are executed in the correct order.
698 So it is possible that other static destructors might want to
699 write to cout - and they're supposed to be able to do so.
701 The following will make the standard streambufs be unbuffered,
702 which forces any output from late destructors to be written out. */
703 _IO_unbuffer_all ();
706 void
707 _IO_init_marker (marker, fp)
708 struct _IO_marker *marker;
709 _IO_FILE *fp;
711 marker->_sbuf = fp;
712 if (_IO_in_put_mode (fp))
713 _IO_switch_to_get_mode (fp);
714 if (_IO_in_backup (fp))
715 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
716 else
717 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
719 /* Should perhaps sort the chain? */
720 marker->_next = fp->_markers;
721 fp->_markers = marker;
724 void
725 _IO_remove_marker (marker)
726 struct _IO_marker *marker;
728 /* Unlink from sb's chain. */
729 struct _IO_marker **ptr = &marker->_sbuf->_markers;
730 for (; ; ptr = &(*ptr)->_next)
732 if (*ptr == NULL)
733 break;
734 else if (*ptr == marker)
736 *ptr = marker->_next;
737 return;
740 #if 0
741 if _sbuf has a backup area that is no longer needed, should we delete
742 it now, or wait until the next underflow?
743 #endif
746 #define BAD_DELTA EOF
749 _IO_marker_difference (mark1, mark2)
750 struct _IO_marker *mark1;
751 struct _IO_marker *mark2;
753 return mark1->_pos - mark2->_pos;
756 /* Return difference between MARK and current position of MARK's stream. */
758 _IO_marker_delta (mark)
759 struct _IO_marker *mark;
761 int cur_pos;
762 if (mark->_sbuf == NULL)
763 return BAD_DELTA;
764 if (_IO_in_backup (mark->_sbuf))
765 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
766 else
767 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
768 return mark->_pos - cur_pos;
772 _IO_seekmark (fp, mark, delta)
773 _IO_FILE *fp;
774 struct _IO_marker *mark;
775 int delta;
777 if (mark->_sbuf != fp)
778 return EOF;
779 if (mark->_pos >= 0)
781 if (_IO_in_backup (fp))
782 _IO_switch_to_main_get_area (fp);
783 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
785 else
787 if (!_IO_in_backup (fp))
788 _IO_switch_to_backup_area (fp);
789 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
791 return 0;
794 void
795 _IO_unsave_markers (fp)
796 _IO_FILE *fp;
798 struct _IO_marker *mark = fp->_markers;
799 if (mark)
801 #ifdef TODO
802 streampos offset = seekoff (0, ios::cur, ios::in);
803 if (offset != EOF)
805 offset += eGptr () - Gbase ();
806 for ( ; mark != NULL; mark = mark->_next)
807 mark->set_streampos (mark->_pos + offset);
809 else
811 for ( ; mark != NULL; mark = mark->_next)
812 mark->set_streampos (EOF);
814 #endif
815 fp->_markers = 0;
818 if (_IO_have_backup (fp))
819 _IO_free_backup_area (fp);
822 #if 0
823 /* Seems not to be needed. --drepper */
825 _IO_nobackup_pbackfail (fp, c)
826 _IO_FILE *fp;
827 int c;
829 if (fp->_IO_read_ptr > fp->_IO_read_base)
830 fp->_IO_read_ptr--;
831 if (c != EOF && *fp->_IO_read_ptr != c)
832 *fp->_IO_read_ptr = c;
833 return (unsigned char) c;
835 #endif
838 _IO_default_pbackfail (fp, c)
839 _IO_FILE *fp;
840 int c;
842 if (fp->_IO_read_ptr <= fp->_IO_read_base)
844 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
845 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
846 _IO_switch_to_backup_area (fp);
848 if (!_IO_have_backup (fp))
850 /* No backup buffer: allocate one. */
851 /* Use nshort buffer, if unused? (probably not) FIXME */
852 int backup_size = 128;
853 char *bbuf = (char *) malloc (backup_size);
854 if (bbuf == NULL)
855 return EOF;
856 fp->_IO_save_base = bbuf;
857 fp->_IO_save_end = fp->_IO_save_base + backup_size;
858 fp->_IO_backup_base = fp->_IO_save_end;
859 _IO_switch_to_backup_area (fp);
861 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
863 /* Increase size of existing backup buffer. */
864 _IO_size_t new_size;
865 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
866 char *new_buf;
867 new_size = 2 * old_size;
868 new_buf = (char *) malloc (new_size);
869 if (new_buf == NULL)
870 return EOF;
871 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
872 old_size);
873 free (fp->_IO_read_base);
874 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
875 new_buf + new_size);
876 fp->_IO_backup_base = fp->_IO_read_ptr;
879 --fp->_IO_read_ptr;
880 if (c != EOF && *fp->_IO_read_ptr != c)
881 *fp->_IO_read_ptr = c;
882 return (unsigned char) *fp->_IO_read_ptr;
885 _IO_pos_t
886 _IO_default_seek (fp, offset, dir)
887 _IO_FILE *fp;
888 _IO_off_t offset;
889 int dir;
891 return _IO_pos_BAD;
895 _IO_default_stat (fp, st)
896 _IO_FILE *fp;
897 void* st;
899 return EOF;
902 _IO_ssize_t
903 _IO_default_read (fp, data, n)
904 _IO_FILE* fp;
905 void *data;
906 _IO_ssize_t n;
908 return -1;
911 _IO_ssize_t
912 _IO_default_write (fp, data, n)
913 _IO_FILE *fp;
914 const void *data;
915 _IO_ssize_t n;
917 return 0;
921 #ifdef TODO
922 #if defined(linux)
923 #define IO_CLEANUP ;
924 #endif
926 #ifdef IO_CLEANUP
927 IO_CLEANUP
928 #else
929 struct __io_defs {
930 __io_defs() { }
931 ~__io_defs() { _IO_cleanup (); }
933 __io_defs io_defs__;
934 #endif
936 #endif /* TODO */
938 #ifdef weak_alias
939 weak_alias (_IO_cleanup, _cleanup)
940 #elif defined(_G_STDIO_USES_LIBIO) && defined(_G_HAVE_WEAK_SYMBOL)
941 void _cleanup () __attribute__ ((weak, alias ("_IO_cleanup")));
942 #endif
944 #ifdef text_set_element
945 text_set_element(__libc_atexit, _cleanup);
946 #endif