Update.
[glibc.git] / libio / genops.c
blob4286eef6c22ace47f1ae587e60d57db9903ff204
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))
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 #ifdef _LIBC
214 __mempcpy (__mempcpy (new_buffer + avail,
215 fp->_IO_save_end + least_mark,
216 -least_mark),
217 fp->_IO_read_base,
218 fp->_IO_read_end - fp->_IO_read_base);
219 #else
220 memcpy (new_buffer + avail,
221 fp->_IO_save_end + least_mark,
222 -least_mark);
223 memcpy (new_buffer + avail - least_mark,
224 fp->_IO_read_base,
225 fp->_IO_read_end - fp->_IO_read_base);
226 #endif
228 else
229 memcpy (new_buffer + avail,
230 fp->_IO_read_base + least_mark,
231 needed_size);
232 if (fp->_IO_save_base)
233 free (fp->_IO_save_base);
234 fp->_IO_save_base = new_buffer;
235 fp->_IO_save_end = new_buffer + avail + needed_size;
237 else
239 avail = current_Bsize - needed_size;
240 if (least_mark < 0)
242 memmove (fp->_IO_save_base + avail,
243 fp->_IO_save_end + least_mark,
244 -least_mark);
245 memcpy (fp->_IO_save_base + avail - least_mark,
246 fp->_IO_read_base,
247 fp->_IO_read_end - fp->_IO_read_base);
249 else if (needed_size > 0)
250 memcpy (fp->_IO_save_base + avail,
251 fp->_IO_read_base + least_mark,
252 needed_size);
254 /* FIXME: Dubious arithmetic if pointers are NULL */
255 fp->_IO_backup_base = fp->_IO_save_base + avail;
256 /* Adjust all the streammarkers. */
257 delta = fp->_IO_read_end - fp->_IO_read_base;
258 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
259 mark->_pos -= delta;
260 return 0;
264 __underflow (fp)
265 _IO_FILE *fp;
267 if (_IO_in_put_mode (fp))
268 if (_IO_switch_to_get_mode (fp) == EOF)
269 return EOF;
270 if (fp->_IO_read_ptr < fp->_IO_read_end)
271 return *(unsigned char *) fp->_IO_read_ptr;
272 if (_IO_in_backup (fp))
274 _IO_switch_to_main_get_area (fp);
275 if (fp->_IO_read_ptr < fp->_IO_read_end)
276 return *(unsigned char *) fp->_IO_read_ptr;
278 if (_IO_have_markers (fp))
280 if (save_for_backup (fp))
281 return EOF;
283 else if (_IO_have_backup (fp))
284 _IO_free_backup_area (fp);
285 return _IO_UNDERFLOW (fp);
289 __uflow (fp)
290 _IO_FILE *fp;
292 if (_IO_in_put_mode (fp))
293 if (_IO_switch_to_get_mode (fp) == EOF)
294 return EOF;
295 if (fp->_IO_read_ptr < fp->_IO_read_end)
296 return *(unsigned char *) fp->_IO_read_ptr++;
297 if (_IO_in_backup (fp))
299 _IO_switch_to_main_get_area (fp);
300 if (fp->_IO_read_ptr < fp->_IO_read_end)
301 return *(unsigned char *) fp->_IO_read_ptr++;
303 if (_IO_have_markers (fp))
305 if (save_for_backup (fp))
306 return EOF;
308 else if (_IO_have_backup (fp))
309 _IO_free_backup_area (fp);
310 return _IO_UFLOW (fp);
313 void
314 _IO_setb (f, b, eb, a)
315 _IO_FILE *f;
316 char *b;
317 char *eb;
318 int a;
320 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
321 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
322 f->_IO_buf_base = b;
323 f->_IO_buf_end = eb;
324 if (a)
325 f->_flags &= ~_IO_USER_BUF;
326 else
327 f->_flags |= _IO_USER_BUF;
330 void
331 _IO_doallocbuf (fp)
332 _IO_FILE *fp;
334 if (fp->_IO_buf_base)
335 return;
336 if (!(fp->_flags & _IO_UNBUFFERED))
337 if (_IO_DOALLOCATE (fp) != EOF)
338 return;
339 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
343 _IO_default_underflow (fp)
344 _IO_FILE *fp;
346 return EOF;
350 _IO_default_uflow (fp)
351 _IO_FILE *fp;
353 int ch = _IO_UNDERFLOW (fp);
354 if (ch == EOF)
355 return EOF;
356 return *(unsigned char *) fp->_IO_read_ptr++;
359 _IO_size_t
360 _IO_default_xsputn (f, data, n)
361 _IO_FILE *f;
362 const void *data;
363 _IO_size_t n;
365 const char *s = (char *) data;
366 _IO_size_t more = n;
367 if (more <= 0)
368 return 0;
369 for (;;)
371 /* Space available. */
372 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
373 if (count > 0)
375 if ((_IO_size_t) count > more)
376 count = more;
377 if (count > 20)
379 #ifdef _LIBC
380 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
381 #else
382 memcpy (f->_IO_write_ptr, s, count);
383 f->_IO_write_ptr += count;
384 #endif
385 s += count;
387 else if (count <= 0)
388 count = 0;
389 else
391 char *p = f->_IO_write_ptr;
392 _IO_ssize_t i;
393 for (i = count; --i >= 0; )
394 *p++ = *s++;
395 f->_IO_write_ptr = p;
397 more -= count;
399 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
400 break;
401 more--;
403 return n - more;
406 _IO_size_t
407 _IO_sgetn (fp, data, n)
408 _IO_FILE *fp;
409 void *data;
410 _IO_size_t n;
412 /* FIXME handle putback buffer here! */
413 return _IO_XSGETN (fp, data, n);
416 _IO_size_t
417 _IO_default_xsgetn (fp, data, n)
418 _IO_FILE *fp;
419 void *data;
420 _IO_size_t n;
422 _IO_size_t more = n;
423 char *s = (char*) data;
424 for (;;)
426 /* Data available. */
427 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
428 if (count > 0)
430 if ((_IO_size_t) count > more)
431 count = more;
432 if (count > 20)
434 #ifdef _LIBC
435 s = __mempcpy (s, fp->_IO_read_ptr, count);
436 #else
437 memcpy (s, fp->_IO_read_ptr, count);
438 s += count;
439 #endif
440 fp->_IO_read_ptr += count;
442 else if (count <= 0)
443 count = 0;
444 else
446 char *p = fp->_IO_read_ptr;
447 int i = (int) count;
448 while (--i >= 0)
449 *s++ = *p++;
450 fp->_IO_read_ptr = p;
452 more -= count;
454 if (more == 0 || __underflow (fp) == EOF)
455 break;
457 return n - more;
460 #if 0
461 /* Seems not to be needed. --drepper */
463 _IO_sync (fp)
464 _IO_FILE *fp;
466 return 0;
468 #endif
470 _IO_FILE *
471 _IO_default_setbuf (fp, p, len)
472 _IO_FILE *fp;
473 char *p;
474 _IO_ssize_t len;
476 if (_IO_SYNC (fp) == EOF)
477 return NULL;
478 if (p == NULL || len == 0)
480 fp->_flags |= _IO_UNBUFFERED;
481 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
483 else
485 fp->_flags &= ~_IO_UNBUFFERED;
486 _IO_setb (fp, p, p+len, 0);
488 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
489 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
490 return fp;
493 _IO_fpos64_t
494 _IO_default_seekpos (fp, pos, mode)
495 _IO_FILE *fp;
496 _IO_fpos64_t pos;
497 int mode;
499 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
503 _IO_default_doallocate (fp)
504 _IO_FILE *fp;
506 char *buf;
508 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
509 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
510 return 1;
513 void
514 _IO_init (fp, flags)
515 _IO_FILE *fp;
516 int flags;
518 fp->_flags = _IO_MAGIC|flags;
519 fp->_IO_buf_base = NULL;
520 fp->_IO_buf_end = NULL;
521 fp->_IO_read_base = NULL;
522 fp->_IO_read_ptr = NULL;
523 fp->_IO_read_end = NULL;
524 fp->_IO_write_base = NULL;
525 fp->_IO_write_ptr = NULL;
526 fp->_IO_write_end = NULL;
527 fp->_chain = NULL; /* Not necessary. */
529 fp->_IO_save_base = NULL;
530 fp->_IO_backup_base = NULL;
531 fp->_IO_save_end = NULL;
532 fp->_markers = NULL;
533 fp->_cur_column = 0;
534 #if _IO_JUMPS_OFFSET
535 fp->_vtable_offset = 0;
536 #endif
537 #ifdef _IO_MTSAFE_IO
538 _IO_lock_init (*fp->_lock);
539 #endif
543 _IO_default_sync (fp)
544 _IO_FILE *fp;
546 return 0;
549 /* The way the C++ classes are mapped into the C functions in the
550 current implementation, this function can get called twice! */
552 void
553 _IO_default_finish (fp, dummy)
554 _IO_FILE *fp;
555 int dummy;
557 struct _IO_marker *mark;
558 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
560 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
561 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
564 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
565 mark->_sbuf = NULL;
567 if (fp->_IO_save_base)
569 free (fp->_IO_save_base);
570 fp->_IO_save_base = NULL;
573 #ifdef _IO_MTSAFE_IO
574 _IO_lock_fini (*fp->_lock);
575 #endif
577 _IO_un_link (fp);
580 _IO_fpos64_t
581 _IO_default_seekoff (fp, offset, dir, mode)
582 _IO_FILE *fp;
583 _IO_off64_t offset;
584 int dir;
585 int mode;
587 return _IO_pos_BAD;
591 _IO_sputbackc (fp, c)
592 _IO_FILE *fp;
593 int c;
595 int result;
597 if (fp->_IO_read_ptr > fp->_IO_read_base
598 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
600 fp->_IO_read_ptr--;
601 result = (unsigned char) c;
603 else
604 result = _IO_PBACKFAIL (fp, c);
606 if (result != EOF)
607 fp->_flags &= ~_IO_EOF_SEEN;
609 return result;
613 _IO_sungetc (fp)
614 _IO_FILE *fp;
616 int result;
618 if (fp->_IO_read_ptr > fp->_IO_read_base)
620 fp->_IO_read_ptr--;
621 result = (unsigned char) *fp->_IO_read_ptr;
623 else
624 result = _IO_PBACKFAIL (fp, EOF);
626 if (result != EOF)
627 fp->_flags &= ~_IO_EOF_SEEN;
629 return result;
632 #if 0 /* Work in progress */
633 /* Seems not to be needed. */
634 #if 0
635 void
636 _IO_set_column (fp, c)
637 _IO_FILE *fp;
638 int c;
640 if (c == -1)
641 fp->_column = -1;
642 else
643 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
645 #else
647 _IO_set_column (fp, i)
648 _IO_FILE *fp;
649 int i;
651 fp->_cur_column = i + 1;
652 return 0;
654 #endif
655 #endif
658 unsigned
659 _IO_adjust_column (start, line, count)
660 unsigned start;
661 const char *line;
662 int count;
664 const char *ptr = line + count;
665 while (ptr > line)
666 if (*--ptr == '\n')
667 return line + count - ptr - 1;
668 return start + count;
671 #if 0
672 /* Seems not to be needed. --drepper */
674 _IO_get_column (fp)
675 _IO_FILE *fp;
677 if (fp->_cur_column)
678 return _IO_adjust_column (fp->_cur_column - 1,
679 fp->_IO_write_base,
680 fp->_IO_write_ptr - fp->_IO_write_base);
681 return -1;
683 #endif
686 _IO_flush_all ()
688 int result = 0;
689 _IO_FILE *fp;
690 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
691 if (fp->_IO_write_ptr > fp->_IO_write_base
692 && _IO_OVERFLOW (fp, EOF) == EOF)
693 result = EOF;
694 return result;
697 void
698 _IO_flush_all_linebuffered ()
700 _IO_FILE *fp;
701 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
702 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
703 _IO_OVERFLOW (fp, EOF);
706 static void _IO_unbuffer_all __P ((void));
708 static void
709 _IO_unbuffer_all ()
711 _IO_FILE *fp;
712 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
713 if (! (fp->_flags & _IO_UNBUFFERED))
714 _IO_SETBUF (fp, NULL, 0);
718 _IO_cleanup ()
720 int result = _IO_flush_all ();
722 /* We currently don't have a reliable mechanism for making sure that
723 C++ static destructors are executed in the correct order.
724 So it is possible that other static destructors might want to
725 write to cout - and they're supposed to be able to do so.
727 The following will make the standard streambufs be unbuffered,
728 which forces any output from late destructors to be written out. */
729 _IO_unbuffer_all ();
731 return result;
735 void
736 _IO_init_marker (marker, fp)
737 struct _IO_marker *marker;
738 _IO_FILE *fp;
740 marker->_sbuf = fp;
741 if (_IO_in_put_mode (fp))
742 _IO_switch_to_get_mode (fp);
743 if (_IO_in_backup (fp))
744 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
745 else
746 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
748 /* Should perhaps sort the chain? */
749 marker->_next = fp->_markers;
750 fp->_markers = marker;
753 void
754 _IO_remove_marker (marker)
755 struct _IO_marker *marker;
757 /* Unlink from sb's chain. */
758 struct _IO_marker **ptr = &marker->_sbuf->_markers;
759 for (; ; ptr = &(*ptr)->_next)
761 if (*ptr == NULL)
762 break;
763 else if (*ptr == marker)
765 *ptr = marker->_next;
766 return;
769 #if 0
770 if _sbuf has a backup area that is no longer needed, should we delete
771 it now, or wait until the next underflow?
772 #endif
775 #define BAD_DELTA EOF
778 _IO_marker_difference (mark1, mark2)
779 struct _IO_marker *mark1;
780 struct _IO_marker *mark2;
782 return mark1->_pos - mark2->_pos;
785 /* Return difference between MARK and current position of MARK's stream. */
787 _IO_marker_delta (mark)
788 struct _IO_marker *mark;
790 int cur_pos;
791 if (mark->_sbuf == NULL)
792 return BAD_DELTA;
793 if (_IO_in_backup (mark->_sbuf))
794 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
795 else
796 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
797 return mark->_pos - cur_pos;
801 _IO_seekmark (fp, mark, delta)
802 _IO_FILE *fp;
803 struct _IO_marker *mark;
804 int delta;
806 if (mark->_sbuf != fp)
807 return EOF;
808 if (mark->_pos >= 0)
810 if (_IO_in_backup (fp))
811 _IO_switch_to_main_get_area (fp);
812 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
814 else
816 if (!_IO_in_backup (fp))
817 _IO_switch_to_backup_area (fp);
818 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
820 return 0;
823 void
824 _IO_unsave_markers (fp)
825 _IO_FILE *fp;
827 struct _IO_marker *mark = fp->_markers;
828 if (mark)
830 #ifdef TODO
831 streampos offset = seekoff (0, ios::cur, ios::in);
832 if (offset != EOF)
834 offset += eGptr () - Gbase ();
835 for ( ; mark != NULL; mark = mark->_next)
836 mark->set_streampos (mark->_pos + offset);
838 else
840 for ( ; mark != NULL; mark = mark->_next)
841 mark->set_streampos (EOF);
843 #endif
844 fp->_markers = 0;
847 if (_IO_have_backup (fp))
848 _IO_free_backup_area (fp);
851 #if 0
852 /* Seems not to be needed. --drepper */
854 _IO_nobackup_pbackfail (fp, c)
855 _IO_FILE *fp;
856 int c;
858 if (fp->_IO_read_ptr > fp->_IO_read_base)
859 fp->_IO_read_ptr--;
860 if (c != EOF && *fp->_IO_read_ptr != c)
861 *fp->_IO_read_ptr = c;
862 return (unsigned char) c;
864 #endif
867 _IO_default_pbackfail (fp, c)
868 _IO_FILE *fp;
869 int c;
871 if (fp->_IO_read_ptr <= fp->_IO_read_base)
873 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
874 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
875 _IO_switch_to_backup_area (fp);
877 if (!_IO_have_backup (fp))
879 /* No backup buffer: allocate one. */
880 /* Use nshort buffer, if unused? (probably not) FIXME */
881 int backup_size = 128;
882 char *bbuf = (char *) malloc (backup_size);
883 if (bbuf == NULL)
884 return EOF;
885 fp->_IO_save_base = bbuf;
886 fp->_IO_save_end = fp->_IO_save_base + backup_size;
887 fp->_IO_backup_base = fp->_IO_save_end;
888 _IO_switch_to_backup_area (fp);
890 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
892 /* Increase size of existing backup buffer. */
893 _IO_size_t new_size;
894 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
895 char *new_buf;
896 new_size = 2 * old_size;
897 new_buf = (char *) malloc (new_size);
898 if (new_buf == NULL)
899 return EOF;
900 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
901 old_size);
902 free (fp->_IO_read_base);
903 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
904 new_buf + new_size);
905 fp->_IO_backup_base = fp->_IO_read_ptr;
908 --fp->_IO_read_ptr;
909 if (c != EOF && *fp->_IO_read_ptr != c)
910 *fp->_IO_read_ptr = c;
911 return (unsigned char) *fp->_IO_read_ptr;
914 _IO_fpos64_t
915 _IO_default_seek (fp, offset, dir)
916 _IO_FILE *fp;
917 _IO_off64_t offset;
918 int dir;
920 return _IO_pos_BAD;
924 _IO_default_stat (fp, st)
925 _IO_FILE *fp;
926 void* st;
928 return EOF;
931 _IO_ssize_t
932 _IO_default_read (fp, data, n)
933 _IO_FILE* fp;
934 void *data;
935 _IO_ssize_t n;
937 return -1;
940 _IO_ssize_t
941 _IO_default_write (fp, data, n)
942 _IO_FILE *fp;
943 const void *data;
944 _IO_ssize_t n;
946 return 0;
950 _IO_default_showmanyc (fp)
951 _IO_FILE *fp;
953 return -1;
956 void
957 _IO_default_imbue (fp, locale)
958 _IO_FILE *fp;
959 void *locale;
964 #ifdef TODO
965 #if defined(linux)
966 #define IO_CLEANUP ;
967 #endif
969 #ifdef IO_CLEANUP
970 IO_CLEANUP
971 #else
972 struct __io_defs {
973 __io_defs() { }
974 ~__io_defs() { _IO_cleanup (); }
976 __io_defs io_defs__;
977 #endif
979 #endif /* TODO */
981 #ifdef weak_alias
982 weak_alias (_IO_cleanup, _cleanup)
983 #endif
985 #ifdef text_set_element
986 text_set_element(__libc_atexit, _cleanup);
987 #endif