Update.
[glibc.git] / libio / genops.c
blobea602eda3931f48868f28cb9095edadf33bb45a8
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 #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 *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 *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);
717 void
718 _IO_cleanup ()
720 _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 ();
733 void
734 _IO_init_marker (marker, fp)
735 struct _IO_marker *marker;
736 _IO_FILE *fp;
738 marker->_sbuf = fp;
739 if (_IO_in_put_mode (fp))
740 _IO_switch_to_get_mode (fp);
741 if (_IO_in_backup (fp))
742 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
743 else
744 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
746 /* Should perhaps sort the chain? */
747 marker->_next = fp->_markers;
748 fp->_markers = marker;
751 void
752 _IO_remove_marker (marker)
753 struct _IO_marker *marker;
755 /* Unlink from sb's chain. */
756 struct _IO_marker **ptr = &marker->_sbuf->_markers;
757 for (; ; ptr = &(*ptr)->_next)
759 if (*ptr == NULL)
760 break;
761 else if (*ptr == marker)
763 *ptr = marker->_next;
764 return;
767 #if 0
768 if _sbuf has a backup area that is no longer needed, should we delete
769 it now, or wait until the next underflow?
770 #endif
773 #define BAD_DELTA EOF
776 _IO_marker_difference (mark1, mark2)
777 struct _IO_marker *mark1;
778 struct _IO_marker *mark2;
780 return mark1->_pos - mark2->_pos;
783 /* Return difference between MARK and current position of MARK's stream. */
785 _IO_marker_delta (mark)
786 struct _IO_marker *mark;
788 int cur_pos;
789 if (mark->_sbuf == NULL)
790 return BAD_DELTA;
791 if (_IO_in_backup (mark->_sbuf))
792 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
793 else
794 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
795 return mark->_pos - cur_pos;
799 _IO_seekmark (fp, mark, delta)
800 _IO_FILE *fp;
801 struct _IO_marker *mark;
802 int delta;
804 if (mark->_sbuf != fp)
805 return EOF;
806 if (mark->_pos >= 0)
808 if (_IO_in_backup (fp))
809 _IO_switch_to_main_get_area (fp);
810 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
812 else
814 if (!_IO_in_backup (fp))
815 _IO_switch_to_backup_area (fp);
816 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
818 return 0;
821 void
822 _IO_unsave_markers (fp)
823 _IO_FILE *fp;
825 struct _IO_marker *mark = fp->_markers;
826 if (mark)
828 #ifdef TODO
829 streampos offset = seekoff (0, ios::cur, ios::in);
830 if (offset != EOF)
832 offset += eGptr () - Gbase ();
833 for ( ; mark != NULL; mark = mark->_next)
834 mark->set_streampos (mark->_pos + offset);
836 else
838 for ( ; mark != NULL; mark = mark->_next)
839 mark->set_streampos (EOF);
841 #endif
842 fp->_markers = 0;
845 if (_IO_have_backup (fp))
846 _IO_free_backup_area (fp);
849 #if 0
850 /* Seems not to be needed. --drepper */
852 _IO_nobackup_pbackfail (fp, c)
853 _IO_FILE *fp;
854 int c;
856 if (fp->_IO_read_ptr > fp->_IO_read_base)
857 fp->_IO_read_ptr--;
858 if (c != EOF && *fp->_IO_read_ptr != c)
859 *fp->_IO_read_ptr = c;
860 return (unsigned char) c;
862 #endif
865 _IO_default_pbackfail (fp, c)
866 _IO_FILE *fp;
867 int c;
869 if (fp->_IO_read_ptr <= fp->_IO_read_base)
871 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
872 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
873 _IO_switch_to_backup_area (fp);
875 if (!_IO_have_backup (fp))
877 /* No backup buffer: allocate one. */
878 /* Use nshort buffer, if unused? (probably not) FIXME */
879 int backup_size = 128;
880 char *bbuf = (char *) malloc (backup_size);
881 if (bbuf == NULL)
882 return EOF;
883 fp->_IO_save_base = bbuf;
884 fp->_IO_save_end = fp->_IO_save_base + backup_size;
885 fp->_IO_backup_base = fp->_IO_save_end;
886 _IO_switch_to_backup_area (fp);
888 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
890 /* Increase size of existing backup buffer. */
891 _IO_size_t new_size;
892 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
893 char *new_buf;
894 new_size = 2 * old_size;
895 new_buf = (char *) malloc (new_size);
896 if (new_buf == NULL)
897 return EOF;
898 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
899 old_size);
900 free (fp->_IO_read_base);
901 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
902 new_buf + new_size);
903 fp->_IO_backup_base = fp->_IO_read_ptr;
906 --fp->_IO_read_ptr;
907 if (c != EOF && *fp->_IO_read_ptr != c)
908 *fp->_IO_read_ptr = c;
909 return (unsigned char) *fp->_IO_read_ptr;
912 _IO_fpos64_t
913 _IO_default_seek (fp, offset, dir)
914 _IO_FILE *fp;
915 _IO_off64_t offset;
916 int dir;
918 return _IO_pos_BAD;
922 _IO_default_stat (fp, st)
923 _IO_FILE *fp;
924 void* st;
926 return EOF;
929 _IO_ssize_t
930 _IO_default_read (fp, data, n)
931 _IO_FILE* fp;
932 void *data;
933 _IO_ssize_t n;
935 return -1;
938 _IO_ssize_t
939 _IO_default_write (fp, data, n)
940 _IO_FILE *fp;
941 const void *data;
942 _IO_ssize_t n;
944 return 0;
948 _IO_default_showmanyc (fp)
949 _IO_FILE *fp;
951 return -1;
954 void
955 _IO_default_imbue (fp, locale)
956 _IO_FILE *fp;
957 void *locale;
962 #ifdef TODO
963 #if defined(linux)
964 #define IO_CLEANUP ;
965 #endif
967 #ifdef IO_CLEANUP
968 IO_CLEANUP
969 #else
970 struct __io_defs {
971 __io_defs() { }
972 ~__io_defs() { _IO_cleanup (); }
974 __io_defs io_defs__;
975 #endif
977 #endif /* TODO */
979 #ifdef weak_alias
980 weak_alias (_IO_cleanup, _cleanup)
981 #endif
983 #ifdef text_set_element
984 text_set_element(__libc_atexit, _cleanup);
985 #endif