Update.
[glibc.git] / libio / genops.c
blob71275da28c2511d3e2b04613b737418e22907354
1 /* Copyright (C) 1993, 1995, 1997 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))
184 #ifdef _LIBC
185 internal_function
186 #endif
189 static int
190 #ifdef _LIBC
191 internal_function
192 #endif
193 save_for_backup (fp)
194 _IO_FILE *fp;
196 /* Append [_IO_read_base.._IO_read_end] to backup area. */
197 int least_mark = _IO_least_marker (fp);
198 /* needed_size is how much space we need in the backup area. */
199 int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
200 int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
201 int avail; /* Extra space available for future expansion. */
202 int delta;
203 struct _IO_marker *mark;
204 if (needed_size > current_Bsize)
206 char *new_buffer;
207 avail = 100;
208 new_buffer = (char *) malloc (avail + needed_size);
209 if (new_buffer == NULL)
210 return EOF; /* FIXME */
211 if (least_mark < 0)
213 memcpy (new_buffer + avail,
214 fp->_IO_save_end + least_mark,
215 -least_mark);
216 memcpy (new_buffer + avail - least_mark,
217 fp->_IO_read_base,
218 fp->_IO_read_end - fp->_IO_read_base);
220 else
221 memcpy (new_buffer + avail,
222 fp->_IO_read_base + least_mark,
223 needed_size);
224 if (fp->_IO_save_base)
225 free (fp->_IO_save_base);
226 fp->_IO_save_base = new_buffer;
227 fp->_IO_save_end = new_buffer + avail + needed_size;
229 else
231 avail = current_Bsize - needed_size;
232 if (least_mark < 0)
234 memmove (fp->_IO_save_base + avail,
235 fp->_IO_save_end + least_mark,
236 -least_mark);
237 memcpy (fp->_IO_save_base + avail - least_mark,
238 fp->_IO_read_base,
239 fp->_IO_read_end - fp->_IO_read_base);
241 else if (needed_size > 0)
242 memcpy (fp->_IO_save_base + avail,
243 fp->_IO_read_base + least_mark,
244 needed_size);
246 /* FIXME: Dubious arithmetic if pointers are NULL */
247 fp->_IO_backup_base = fp->_IO_save_base + avail;
248 /* Adjust all the streammarkers. */
249 delta = fp->_IO_read_end - fp->_IO_read_base;
250 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
251 mark->_pos -= delta;
252 return 0;
256 __underflow (fp)
257 _IO_FILE *fp;
259 if (_IO_in_put_mode (fp))
260 if (_IO_switch_to_get_mode (fp) == EOF)
261 return EOF;
262 if (fp->_IO_read_ptr < fp->_IO_read_end)
263 return *(unsigned char *) fp->_IO_read_ptr;
264 if (_IO_in_backup (fp))
266 _IO_switch_to_main_get_area (fp);
267 if (fp->_IO_read_ptr < fp->_IO_read_end)
268 return *fp->_IO_read_ptr;
270 if (_IO_have_markers (fp))
272 if (save_for_backup (fp))
273 return EOF;
275 else if (_IO_have_backup (fp))
276 _IO_free_backup_area (fp);
277 return _IO_UNDERFLOW (fp);
281 __uflow (fp)
282 _IO_FILE *fp;
284 if (_IO_in_put_mode (fp))
285 if (_IO_switch_to_get_mode (fp) == EOF)
286 return EOF;
287 if (fp->_IO_read_ptr < fp->_IO_read_end)
288 return *(unsigned char *) fp->_IO_read_ptr++;
289 if (_IO_in_backup (fp))
291 _IO_switch_to_main_get_area (fp);
292 if (fp->_IO_read_ptr < fp->_IO_read_end)
293 return *fp->_IO_read_ptr++;
295 if (_IO_have_markers (fp))
297 if (save_for_backup (fp))
298 return EOF;
300 else if (_IO_have_backup (fp))
301 _IO_free_backup_area (fp);
302 return _IO_UFLOW (fp);
305 void
306 _IO_setb (f, b, eb, a)
307 _IO_FILE *f;
308 char *b;
309 char *eb;
310 int a;
312 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
313 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
314 f->_IO_buf_base = b;
315 f->_IO_buf_end = eb;
316 if (a)
317 f->_flags &= ~_IO_USER_BUF;
318 else
319 f->_flags |= _IO_USER_BUF;
322 void
323 _IO_doallocbuf (fp)
324 _IO_FILE *fp;
326 if (fp->_IO_buf_base)
327 return;
328 if (!(fp->_flags & _IO_UNBUFFERED))
329 if (_IO_DOALLOCATE (fp) != EOF)
330 return;
331 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
335 _IO_default_underflow (fp)
336 _IO_FILE *fp;
338 return EOF;
342 _IO_default_uflow (fp)
343 _IO_FILE *fp;
345 int ch = _IO_UNDERFLOW (fp);
346 if (ch == EOF)
347 return EOF;
348 return *(unsigned char *) fp->_IO_read_ptr++;
351 _IO_size_t
352 _IO_default_xsputn (f, data, n)
353 _IO_FILE *f;
354 const void *data;
355 _IO_size_t n;
357 const char *s = (char *) data;
358 _IO_size_t more = n;
359 if (more <= 0)
360 return 0;
361 for (;;)
363 /* Space available. */
364 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
365 if (count > 0)
367 if ((_IO_size_t) count > more)
368 count = more;
369 if (count > 20)
371 memcpy (f->_IO_write_ptr, s, count);
372 s += count;
373 f->_IO_write_ptr += count;
375 else if (count <= 0)
376 count = 0;
377 else
379 char *p = f->_IO_write_ptr;
380 _IO_ssize_t i;
381 for (i = count; --i >= 0; )
382 *p++ = *s++;
383 f->_IO_write_ptr = p;
385 more -= count;
387 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
388 break;
389 more--;
391 return n - more;
394 _IO_size_t
395 _IO_sgetn (fp, data, n)
396 _IO_FILE *fp;
397 void *data;
398 _IO_size_t n;
400 /* FIXME handle putback buffer here! */
401 return _IO_XSGETN (fp, data, n);
404 _IO_size_t
405 _IO_default_xsgetn (fp, data, n)
406 _IO_FILE *fp;
407 void *data;
408 _IO_size_t n;
410 _IO_size_t more = n;
411 char *s = (char*) data;
412 for (;;)
414 /* Data available. */
415 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
416 if (count > 0)
418 if ((_IO_size_t) count > more)
419 count = more;
420 if (count > 20)
422 memcpy (s, fp->_IO_read_ptr, count);
423 s += count;
424 fp->_IO_read_ptr += count;
426 else if (count <= 0)
427 count = 0;
428 else
430 char *p = fp->_IO_read_ptr;
431 int i = (int) count;
432 while (--i >= 0)
433 *s++ = *p++;
434 fp->_IO_read_ptr = p;
436 more -= count;
438 if (more == 0 || __underflow (fp) == EOF)
439 break;
441 return n - more;
444 #if 0
445 /* Seems not to be needed. --drepper */
447 _IO_sync (fp)
448 _IO_FILE *fp;
450 return 0;
452 #endif
454 _IO_FILE *
455 _IO_default_setbuf (fp, p, len)
456 _IO_FILE *fp;
457 char *p;
458 _IO_ssize_t len;
460 if (_IO_SYNC (fp) == EOF)
461 return NULL;
462 if (p == NULL || len == 0)
464 fp->_flags |= _IO_UNBUFFERED;
465 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
467 else
469 fp->_flags &= ~_IO_UNBUFFERED;
470 _IO_setb (fp, p, p+len, 0);
472 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
473 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
474 return fp;
477 _IO_fpos64_t
478 _IO_default_seekpos (fp, pos, mode)
479 _IO_FILE *fp;
480 _IO_fpos64_t pos;
481 int mode;
483 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
487 _IO_default_doallocate (fp)
488 _IO_FILE *fp;
490 char *buf;
492 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
493 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
494 return 1;
497 void
498 _IO_init (fp, flags)
499 _IO_FILE *fp;
500 int flags;
502 fp->_flags = _IO_MAGIC|flags;
503 fp->_IO_buf_base = NULL;
504 fp->_IO_buf_end = NULL;
505 fp->_IO_read_base = NULL;
506 fp->_IO_read_ptr = NULL;
507 fp->_IO_read_end = NULL;
508 fp->_IO_write_base = NULL;
509 fp->_IO_write_ptr = NULL;
510 fp->_IO_write_end = NULL;
511 fp->_chain = NULL; /* Not necessary. */
513 fp->_IO_save_base = NULL;
514 fp->_IO_backup_base = NULL;
515 fp->_IO_save_end = NULL;
516 fp->_markers = NULL;
517 fp->_cur_column = 0;
518 #ifdef _IO_MTSAFE_IO
519 _IO_lock_init (*fp->_lock);
520 #endif
524 _IO_default_sync (fp)
525 _IO_FILE *fp;
527 return 0;
530 /* The way the C++ classes are mapped into the C functions in the
531 current implementation, this function can get called twice! */
533 void
534 _IO_default_finish (fp, dummy)
535 _IO_FILE *fp;
536 int dummy;
538 struct _IO_marker *mark;
539 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
541 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
542 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
545 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
546 mark->_sbuf = NULL;
548 if (fp->_IO_save_base)
550 free (fp->_IO_save_base);
551 fp->_IO_save_base = NULL;
554 #ifdef _IO_MTSAFE_IO
555 _IO_lock_fini (*fp->_lock);
556 #endif
558 _IO_un_link (fp);
561 _IO_fpos64_t
562 _IO_default_seekoff (fp, offset, dir, mode)
563 _IO_FILE *fp;
564 _IO_off64_t offset;
565 int dir;
566 int mode;
568 return _IO_pos_BAD;
572 _IO_sputbackc (fp, c)
573 _IO_FILE *fp;
574 int c;
576 int result;
578 if (fp->_IO_read_ptr > fp->_IO_read_base
579 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
581 fp->_IO_read_ptr--;
582 result = (unsigned char) c;
584 else
585 result = _IO_PBACKFAIL (fp, c);
587 if (result != EOF)
588 fp->_flags &= ~_IO_EOF_SEEN;
590 return result;
594 _IO_sungetc (fp)
595 _IO_FILE *fp;
597 int result;
599 if (fp->_IO_read_ptr > fp->_IO_read_base)
601 fp->_IO_read_ptr--;
602 result = (unsigned char) *fp->_IO_read_ptr;
604 else
605 result = _IO_PBACKFAIL (fp, EOF);
607 if (result != EOF)
608 fp->_flags &= ~_IO_EOF_SEEN;
610 return result;
613 #if 0 /* Work in progress */
614 /* Seems not to be needed. */
615 #if 0
616 void
617 _IO_set_column (fp, c)
618 _IO_FILE *fp;
619 int c;
621 if (c == -1)
622 fp->_column = -1;
623 else
624 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
626 #else
628 _IO_set_column (fp, i)
629 _IO_FILE *fp;
630 int i;
632 fp->_cur_column = i + 1;
633 return 0;
635 #endif
636 #endif
639 unsigned
640 _IO_adjust_column (start, line, count)
641 unsigned start;
642 const char *line;
643 int count;
645 const char *ptr = line + count;
646 while (ptr > line)
647 if (*--ptr == '\n')
648 return line + count - ptr - 1;
649 return start + count;
652 #if 0
653 /* Seems not to be needed. --drepper */
655 _IO_get_column (fp)
656 _IO_FILE *fp;
658 if (fp->_cur_column)
659 return _IO_adjust_column (fp->_cur_column - 1,
660 fp->_IO_write_base,
661 fp->_IO_write_ptr - fp->_IO_write_base);
662 return -1;
664 #endif
667 _IO_flush_all ()
669 int result = 0;
670 _IO_FILE *fp;
671 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
672 if (fp->_IO_write_ptr > fp->_IO_write_base
673 && _IO_OVERFLOW (fp, EOF) == EOF)
674 result = EOF;
675 return result;
678 void
679 _IO_flush_all_linebuffered ()
681 _IO_FILE *fp;
682 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
683 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
684 _IO_OVERFLOW (fp, EOF);
687 static void _IO_unbuffer_all __P ((void));
689 static void
690 _IO_unbuffer_all ()
692 _IO_FILE *fp;
693 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
694 if (! (fp->_flags & _IO_UNBUFFERED))
695 _IO_SETBUF (fp, NULL, 0);
698 void
699 _IO_cleanup ()
701 _IO_flush_all ();
703 /* We currently don't have a reliable mechanism for making sure that
704 C++ static destructors are executed in the correct order.
705 So it is possible that other static destructors might want to
706 write to cout - and they're supposed to be able to do so.
708 The following will make the standard streambufs be unbuffered,
709 which forces any output from late destructors to be written out. */
710 _IO_unbuffer_all ();
713 void
714 _IO_init_marker (marker, fp)
715 struct _IO_marker *marker;
716 _IO_FILE *fp;
718 marker->_sbuf = fp;
719 if (_IO_in_put_mode (fp))
720 _IO_switch_to_get_mode (fp);
721 if (_IO_in_backup (fp))
722 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
723 else
724 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
726 /* Should perhaps sort the chain? */
727 marker->_next = fp->_markers;
728 fp->_markers = marker;
731 void
732 _IO_remove_marker (marker)
733 struct _IO_marker *marker;
735 /* Unlink from sb's chain. */
736 struct _IO_marker **ptr = &marker->_sbuf->_markers;
737 for (; ; ptr = &(*ptr)->_next)
739 if (*ptr == NULL)
740 break;
741 else if (*ptr == marker)
743 *ptr = marker->_next;
744 return;
747 #if 0
748 if _sbuf has a backup area that is no longer needed, should we delete
749 it now, or wait until the next underflow?
750 #endif
753 #define BAD_DELTA EOF
756 _IO_marker_difference (mark1, mark2)
757 struct _IO_marker *mark1;
758 struct _IO_marker *mark2;
760 return mark1->_pos - mark2->_pos;
763 /* Return difference between MARK and current position of MARK's stream. */
765 _IO_marker_delta (mark)
766 struct _IO_marker *mark;
768 int cur_pos;
769 if (mark->_sbuf == NULL)
770 return BAD_DELTA;
771 if (_IO_in_backup (mark->_sbuf))
772 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
773 else
774 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
775 return mark->_pos - cur_pos;
779 _IO_seekmark (fp, mark, delta)
780 _IO_FILE *fp;
781 struct _IO_marker *mark;
782 int delta;
784 if (mark->_sbuf != fp)
785 return EOF;
786 if (mark->_pos >= 0)
788 if (_IO_in_backup (fp))
789 _IO_switch_to_main_get_area (fp);
790 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
792 else
794 if (!_IO_in_backup (fp))
795 _IO_switch_to_backup_area (fp);
796 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
798 return 0;
801 void
802 _IO_unsave_markers (fp)
803 _IO_FILE *fp;
805 struct _IO_marker *mark = fp->_markers;
806 if (mark)
808 #ifdef TODO
809 streampos offset = seekoff (0, ios::cur, ios::in);
810 if (offset != EOF)
812 offset += eGptr () - Gbase ();
813 for ( ; mark != NULL; mark = mark->_next)
814 mark->set_streampos (mark->_pos + offset);
816 else
818 for ( ; mark != NULL; mark = mark->_next)
819 mark->set_streampos (EOF);
821 #endif
822 fp->_markers = 0;
825 if (_IO_have_backup (fp))
826 _IO_free_backup_area (fp);
829 #if 0
830 /* Seems not to be needed. --drepper */
832 _IO_nobackup_pbackfail (fp, c)
833 _IO_FILE *fp;
834 int c;
836 if (fp->_IO_read_ptr > fp->_IO_read_base)
837 fp->_IO_read_ptr--;
838 if (c != EOF && *fp->_IO_read_ptr != c)
839 *fp->_IO_read_ptr = c;
840 return (unsigned char) c;
842 #endif
845 _IO_default_pbackfail (fp, c)
846 _IO_FILE *fp;
847 int c;
849 if (fp->_IO_read_ptr <= fp->_IO_read_base)
851 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
852 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
853 _IO_switch_to_backup_area (fp);
855 if (!_IO_have_backup (fp))
857 /* No backup buffer: allocate one. */
858 /* Use nshort buffer, if unused? (probably not) FIXME */
859 int backup_size = 128;
860 char *bbuf = (char *) malloc (backup_size);
861 if (bbuf == NULL)
862 return EOF;
863 fp->_IO_save_base = bbuf;
864 fp->_IO_save_end = fp->_IO_save_base + backup_size;
865 fp->_IO_backup_base = fp->_IO_save_end;
866 _IO_switch_to_backup_area (fp);
868 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
870 /* Increase size of existing backup buffer. */
871 _IO_size_t new_size;
872 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
873 char *new_buf;
874 new_size = 2 * old_size;
875 new_buf = (char *) malloc (new_size);
876 if (new_buf == NULL)
877 return EOF;
878 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
879 old_size);
880 free (fp->_IO_read_base);
881 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
882 new_buf + new_size);
883 fp->_IO_backup_base = fp->_IO_read_ptr;
886 --fp->_IO_read_ptr;
887 if (c != EOF && *fp->_IO_read_ptr != c)
888 *fp->_IO_read_ptr = c;
889 return (unsigned char) *fp->_IO_read_ptr;
892 _IO_fpos64_t
893 _IO_default_seek (fp, offset, dir)
894 _IO_FILE *fp;
895 _IO_off64_t offset;
896 int dir;
898 return _IO_pos_BAD;
902 _IO_default_stat (fp, st)
903 _IO_FILE *fp;
904 void* st;
906 return EOF;
909 _IO_ssize_t
910 _IO_default_read (fp, data, n)
911 _IO_FILE* fp;
912 void *data;
913 _IO_ssize_t n;
915 return -1;
918 _IO_ssize_t
919 _IO_default_write (fp, data, n)
920 _IO_FILE *fp;
921 const void *data;
922 _IO_ssize_t n;
924 return 0;
928 _IO_default_showmanyc (fp)
929 _IO_FILE *fp;
931 return -1;
934 void
935 _IO_default_imbue (fp, locale)
936 _IO_FILE *fp;
937 void *locale;
942 #ifdef TODO
943 #if defined(linux)
944 #define IO_CLEANUP ;
945 #endif
947 #ifdef IO_CLEANUP
948 IO_CLEANUP
949 #else
950 struct __io_defs {
951 __io_defs() { }
952 ~__io_defs() { _IO_cleanup (); }
954 __io_defs io_defs__;
955 #endif
957 #endif /* TODO */
959 #ifdef weak_alias
960 weak_alias (_IO_cleanup, _cleanup)
961 #endif
963 #ifdef text_set_element
964 text_set_element(__libc_atexit, _cleanup);
965 #endif