Update.
[glibc.git] / libio / genops.c
blobc75be6234b84273f759e0fe1b071c2414674cbdb
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;
97 /* Swap _IO_read_base and _IO_save_ptr. */
98 tmp = fp->_IO_read_ptr;
99 fp->_IO_read_ptr = fp->_IO_save_ptr;
100 fp->_IO_save_ptr = tmp;
103 /* Switch current get area from main get area to (end of) backup area. */
105 void
106 _IO_switch_to_backup_area (fp)
107 _IO_FILE *fp;
109 char *tmp;
110 fp->_flags |= _IO_IN_BACKUP;
111 /* Swap _IO_read_end and _IO_save_end. */
112 tmp = fp->_IO_read_end;
113 fp->_IO_read_end = fp->_IO_save_end;
114 fp->_IO_save_end = tmp;
115 /* Swap _gbase and _IO_save_base. */
116 tmp = fp->_IO_read_base;
117 fp->_IO_read_base = fp->_IO_save_base;
118 fp->_IO_save_base = tmp;
119 /* read _IO_read_ptr. */
120 fp->_IO_save_ptr = fp->_IO_read_ptr;
121 fp->_IO_read_ptr = fp->_IO_read_end;
125 _IO_switch_to_get_mode (fp)
126 _IO_FILE *fp;
128 if (fp->_IO_write_ptr > fp->_IO_write_base)
129 if (_IO_OVERFLOW (fp, EOF) == EOF)
130 return EOF;
131 if (_IO_in_backup (fp))
132 fp->_IO_read_base = fp->_IO_backup_base;
133 else
135 fp->_IO_read_base = fp->_IO_buf_base;
136 if (fp->_IO_write_ptr > fp->_IO_read_end)
137 fp->_IO_read_end = fp->_IO_write_ptr;
139 fp->_IO_read_ptr = fp->_IO_write_ptr;
141 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
143 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
144 return 0;
147 void
148 _IO_free_backup_area (fp)
149 _IO_FILE *fp;
151 if (_IO_in_backup (fp))
152 _IO_switch_to_main_get_area (fp); /* Just in case. */
153 free (fp->_IO_save_base);
154 fp->_IO_save_base = NULL;
155 fp->_IO_save_end = NULL;
156 fp->_IO_backup_base = NULL;
159 #if 0
161 _IO_switch_to_put_mode (fp)
162 _IO_FILE *fp;
164 fp->_IO_write_base = fp->_IO_read_ptr;
165 fp->_IO_write_ptr = fp->_IO_read_ptr;
166 /* Following is wrong if line- or un-buffered? */
167 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
168 ? fp->_IO_read_end : fp->_IO_buf_end);
170 fp->_IO_read_ptr = fp->_IO_read_end;
171 fp->_IO_read_base = fp->_IO_read_end;
173 fp->_flags |= _IO_CURRENTLY_PUTTING;
174 return 0;
176 #endif
179 __overflow (f, ch)
180 _IO_FILE *f;
181 int ch;
183 return _IO_OVERFLOW (f, ch);
186 static int save_for_backup __P ((_IO_FILE *fp))
187 #ifdef _LIBC
188 internal_function
189 #endif
192 static int
193 #ifdef _LIBC
194 internal_function
195 #endif
196 save_for_backup (fp)
197 _IO_FILE *fp;
199 /* Append [_IO_read_base.._IO_read_end] to backup area. */
200 int least_mark = _IO_least_marker (fp);
201 /* needed_size is how much space we need in the backup area. */
202 int needed_size = (fp->_IO_read_end - fp->_IO_read_base) - least_mark;
203 int current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
204 int avail; /* Extra space available for future expansion. */
205 int 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 fp->_IO_read_end - 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 fp->_IO_read_end - 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 fp->_IO_read_end - 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 /* FIXME: Dubious arithmetic if pointers are NULL */
258 fp->_IO_backup_base = fp->_IO_save_base + avail;
259 /* Adjust all the streammarkers. */
260 delta = fp->_IO_read_end - fp->_IO_read_base;
261 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
262 mark->_pos -= delta;
263 return 0;
267 __underflow (fp)
268 _IO_FILE *fp;
270 if (_IO_in_put_mode (fp))
271 if (_IO_switch_to_get_mode (fp) == EOF)
272 return EOF;
273 if (fp->_IO_read_ptr < fp->_IO_read_end)
274 return *(unsigned char *) fp->_IO_read_ptr;
275 if (_IO_in_backup (fp))
277 _IO_switch_to_main_get_area (fp);
278 if (fp->_IO_read_ptr < fp->_IO_read_end)
279 return *(unsigned char *) fp->_IO_read_ptr;
281 if (_IO_have_markers (fp))
283 if (save_for_backup (fp))
284 return EOF;
286 else if (_IO_have_backup (fp))
287 _IO_free_backup_area (fp);
288 return _IO_UNDERFLOW (fp);
292 __uflow (fp)
293 _IO_FILE *fp;
295 if (_IO_in_put_mode (fp))
296 if (_IO_switch_to_get_mode (fp) == EOF)
297 return EOF;
298 if (fp->_IO_read_ptr < fp->_IO_read_end)
299 return *(unsigned char *) fp->_IO_read_ptr++;
300 if (_IO_in_backup (fp))
302 _IO_switch_to_main_get_area (fp);
303 if (fp->_IO_read_ptr < fp->_IO_read_end)
304 return *(unsigned char *) fp->_IO_read_ptr++;
306 if (_IO_have_markers (fp))
308 if (save_for_backup (fp))
309 return EOF;
311 else if (_IO_have_backup (fp))
312 _IO_free_backup_area (fp);
313 return _IO_UFLOW (fp);
316 void
317 _IO_setb (f, b, eb, a)
318 _IO_FILE *f;
319 char *b;
320 char *eb;
321 int a;
323 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
324 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
325 f->_IO_buf_base = b;
326 f->_IO_buf_end = eb;
327 if (a)
328 f->_flags &= ~_IO_USER_BUF;
329 else
330 f->_flags |= _IO_USER_BUF;
333 void
334 _IO_doallocbuf (fp)
335 _IO_FILE *fp;
337 if (fp->_IO_buf_base)
338 return;
339 if (!(fp->_flags & _IO_UNBUFFERED))
340 if (_IO_DOALLOCATE (fp) != EOF)
341 return;
342 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
346 _IO_default_underflow (fp)
347 _IO_FILE *fp;
349 return EOF;
353 _IO_default_uflow (fp)
354 _IO_FILE *fp;
356 int ch = _IO_UNDERFLOW (fp);
357 if (ch == EOF)
358 return EOF;
359 return *(unsigned char *) fp->_IO_read_ptr++;
362 _IO_size_t
363 _IO_default_xsputn (f, data, n)
364 _IO_FILE *f;
365 const void *data;
366 _IO_size_t n;
368 const char *s = (char *) data;
369 _IO_size_t more = n;
370 if (more <= 0)
371 return 0;
372 for (;;)
374 /* Space available. */
375 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
376 if (count > 0)
378 if ((_IO_size_t) count > more)
379 count = more;
380 if (count > 20)
382 #ifdef _LIBC
383 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
384 #else
385 memcpy (f->_IO_write_ptr, s, count);
386 f->_IO_write_ptr += count;
387 #endif
388 s += count;
390 else if (count <= 0)
391 count = 0;
392 else
394 char *p = f->_IO_write_ptr;
395 _IO_ssize_t i;
396 for (i = count; --i >= 0; )
397 *p++ = *s++;
398 f->_IO_write_ptr = p;
400 more -= count;
402 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
403 break;
404 more--;
406 return n - more;
409 _IO_size_t
410 _IO_sgetn (fp, data, n)
411 _IO_FILE *fp;
412 void *data;
413 _IO_size_t n;
415 /* FIXME handle putback buffer here! */
416 return _IO_XSGETN (fp, data, n);
419 _IO_size_t
420 _IO_default_xsgetn (fp, data, n)
421 _IO_FILE *fp;
422 void *data;
423 _IO_size_t n;
425 _IO_size_t more = n;
426 char *s = (char*) data;
427 for (;;)
429 /* Data available. */
430 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
431 if (count > 0)
433 if ((_IO_size_t) count > more)
434 count = more;
435 if (count > 20)
437 #ifdef _LIBC
438 s = __mempcpy (s, fp->_IO_read_ptr, count);
439 #else
440 memcpy (s, fp->_IO_read_ptr, count);
441 s += count;
442 #endif
443 fp->_IO_read_ptr += count;
445 else if (count <= 0)
446 count = 0;
447 else
449 char *p = fp->_IO_read_ptr;
450 int i = (int) count;
451 while (--i >= 0)
452 *s++ = *p++;
453 fp->_IO_read_ptr = p;
455 more -= count;
457 if (more == 0 || __underflow (fp) == EOF)
458 break;
460 return n - more;
463 #if 0
464 /* Seems not to be needed. --drepper */
466 _IO_sync (fp)
467 _IO_FILE *fp;
469 return 0;
471 #endif
473 _IO_FILE *
474 _IO_default_setbuf (fp, p, len)
475 _IO_FILE *fp;
476 char *p;
477 _IO_ssize_t len;
479 if (_IO_SYNC (fp) == EOF)
480 return NULL;
481 if (p == NULL || len == 0)
483 fp->_flags |= _IO_UNBUFFERED;
484 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
486 else
488 fp->_flags &= ~_IO_UNBUFFERED;
489 _IO_setb (fp, p, p+len, 0);
491 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
492 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
493 return fp;
496 _IO_fpos64_t
497 _IO_default_seekpos (fp, pos, mode)
498 _IO_FILE *fp;
499 _IO_fpos64_t pos;
500 int mode;
502 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
506 _IO_default_doallocate (fp)
507 _IO_FILE *fp;
509 char *buf;
511 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
512 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
513 return 1;
516 void
517 _IO_init (fp, flags)
518 _IO_FILE *fp;
519 int flags;
521 fp->_flags = _IO_MAGIC|flags;
522 fp->_IO_buf_base = NULL;
523 fp->_IO_buf_end = NULL;
524 fp->_IO_read_base = NULL;
525 fp->_IO_read_ptr = NULL;
526 fp->_IO_read_end = NULL;
527 fp->_IO_write_base = NULL;
528 fp->_IO_write_ptr = NULL;
529 fp->_IO_write_end = NULL;
530 fp->_chain = NULL; /* Not necessary. */
532 fp->_IO_save_base = NULL;
533 fp->_IO_backup_base = NULL;
534 fp->_IO_save_end = NULL;
535 fp->_markers = NULL;
536 fp->_cur_column = 0;
537 #if _IO_JUMPS_OFFSET
538 fp->_vtable_offset = 0;
539 #endif
540 #ifdef _IO_MTSAFE_IO
541 _IO_lock_init (*fp->_lock);
542 #endif
546 _IO_default_sync (fp)
547 _IO_FILE *fp;
549 return 0;
552 /* The way the C++ classes are mapped into the C functions in the
553 current implementation, this function can get called twice! */
555 void
556 _IO_default_finish (fp, dummy)
557 _IO_FILE *fp;
558 int dummy;
560 struct _IO_marker *mark;
561 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
563 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
564 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
567 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
568 mark->_sbuf = NULL;
570 if (fp->_IO_save_base)
572 free (fp->_IO_save_base);
573 fp->_IO_save_base = NULL;
576 #ifdef _IO_MTSAFE_IO
577 _IO_lock_fini (*fp->_lock);
578 #endif
580 _IO_un_link (fp);
583 _IO_fpos64_t
584 _IO_default_seekoff (fp, offset, dir, mode)
585 _IO_FILE *fp;
586 _IO_off64_t offset;
587 int dir;
588 int mode;
590 return _IO_pos_BAD;
594 _IO_sputbackc (fp, c)
595 _IO_FILE *fp;
596 int c;
598 int result;
600 if (fp->_IO_read_ptr > fp->_IO_read_base
601 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
603 fp->_IO_read_ptr--;
604 result = (unsigned char) c;
606 else
607 result = _IO_PBACKFAIL (fp, c);
609 if (result != EOF)
610 fp->_flags &= ~_IO_EOF_SEEN;
612 return result;
616 _IO_sungetc (fp)
617 _IO_FILE *fp;
619 int result;
621 if (fp->_IO_read_ptr > fp->_IO_read_base)
623 fp->_IO_read_ptr--;
624 result = (unsigned char) *fp->_IO_read_ptr;
626 else
627 result = _IO_PBACKFAIL (fp, EOF);
629 if (result != EOF)
630 fp->_flags &= ~_IO_EOF_SEEN;
632 return result;
635 #if 0 /* Work in progress */
636 /* Seems not to be needed. */
637 #if 0
638 void
639 _IO_set_column (fp, c)
640 _IO_FILE *fp;
641 int c;
643 if (c == -1)
644 fp->_column = -1;
645 else
646 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
648 #else
650 _IO_set_column (fp, i)
651 _IO_FILE *fp;
652 int i;
654 fp->_cur_column = i + 1;
655 return 0;
657 #endif
658 #endif
661 unsigned
662 _IO_adjust_column (start, line, count)
663 unsigned start;
664 const char *line;
665 int count;
667 const char *ptr = line + count;
668 while (ptr > line)
669 if (*--ptr == '\n')
670 return line + count - ptr - 1;
671 return start + count;
674 #if 0
675 /* Seems not to be needed. --drepper */
677 _IO_get_column (fp)
678 _IO_FILE *fp;
680 if (fp->_cur_column)
681 return _IO_adjust_column (fp->_cur_column - 1,
682 fp->_IO_write_base,
683 fp->_IO_write_ptr - fp->_IO_write_base);
684 return -1;
686 #endif
689 _IO_flush_all ()
691 int result = 0;
692 _IO_FILE *fp;
693 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
694 if (fp->_IO_write_ptr > fp->_IO_write_base
695 && _IO_OVERFLOW (fp, EOF) == EOF)
696 result = EOF;
697 return result;
700 void
701 _IO_flush_all_linebuffered ()
703 _IO_FILE *fp;
704 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
705 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
706 _IO_OVERFLOW (fp, EOF);
709 static void _IO_unbuffer_all __P ((void));
711 static void
712 _IO_unbuffer_all ()
714 _IO_FILE *fp;
715 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
716 if (! (fp->_flags & _IO_UNBUFFERED))
717 _IO_SETBUF (fp, NULL, 0);
721 _IO_cleanup ()
723 int result = _IO_flush_all ();
725 /* We currently don't have a reliable mechanism for making sure that
726 C++ static destructors are executed in the correct order.
727 So it is possible that other static destructors might want to
728 write to cout - and they're supposed to be able to do so.
730 The following will make the standard streambufs be unbuffered,
731 which forces any output from late destructors to be written out. */
732 _IO_unbuffer_all ();
734 return result;
738 void
739 _IO_init_marker (marker, fp)
740 struct _IO_marker *marker;
741 _IO_FILE *fp;
743 marker->_sbuf = fp;
744 if (_IO_in_put_mode (fp))
745 _IO_switch_to_get_mode (fp);
746 if (_IO_in_backup (fp))
747 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
748 else
749 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
751 /* Should perhaps sort the chain? */
752 marker->_next = fp->_markers;
753 fp->_markers = marker;
756 void
757 _IO_remove_marker (marker)
758 struct _IO_marker *marker;
760 /* Unlink from sb's chain. */
761 struct _IO_marker **ptr = &marker->_sbuf->_markers;
762 for (; ; ptr = &(*ptr)->_next)
764 if (*ptr == NULL)
765 break;
766 else if (*ptr == marker)
768 *ptr = marker->_next;
769 return;
772 #if 0
773 if _sbuf has a backup area that is no longer needed, should we delete
774 it now, or wait until the next underflow?
775 #endif
778 #define BAD_DELTA EOF
781 _IO_marker_difference (mark1, mark2)
782 struct _IO_marker *mark1;
783 struct _IO_marker *mark2;
785 return mark1->_pos - mark2->_pos;
788 /* Return difference between MARK and current position of MARK's stream. */
790 _IO_marker_delta (mark)
791 struct _IO_marker *mark;
793 int cur_pos;
794 if (mark->_sbuf == NULL)
795 return BAD_DELTA;
796 if (_IO_in_backup (mark->_sbuf))
797 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
798 else
799 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
800 return mark->_pos - cur_pos;
804 _IO_seekmark (fp, mark, delta)
805 _IO_FILE *fp;
806 struct _IO_marker *mark;
807 int delta;
809 if (mark->_sbuf != fp)
810 return EOF;
811 if (mark->_pos >= 0)
813 if (_IO_in_backup (fp))
814 _IO_switch_to_main_get_area (fp);
815 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
817 else
819 if (!_IO_in_backup (fp))
820 _IO_switch_to_backup_area (fp);
821 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
823 return 0;
826 void
827 _IO_unsave_markers (fp)
828 _IO_FILE *fp;
830 struct _IO_marker *mark = fp->_markers;
831 if (mark)
833 #ifdef TODO
834 streampos offset = seekoff (0, ios::cur, ios::in);
835 if (offset != EOF)
837 offset += eGptr () - Gbase ();
838 for ( ; mark != NULL; mark = mark->_next)
839 mark->set_streampos (mark->_pos + offset);
841 else
843 for ( ; mark != NULL; mark = mark->_next)
844 mark->set_streampos (EOF);
846 #endif
847 fp->_markers = 0;
850 if (_IO_have_backup (fp))
851 _IO_free_backup_area (fp);
854 #if 0
855 /* Seems not to be needed. --drepper */
857 _IO_nobackup_pbackfail (fp, c)
858 _IO_FILE *fp;
859 int c;
861 if (fp->_IO_read_ptr > fp->_IO_read_base)
862 fp->_IO_read_ptr--;
863 if (c != EOF && *fp->_IO_read_ptr != c)
864 *fp->_IO_read_ptr = c;
865 return (unsigned char) c;
867 #endif
870 _IO_default_pbackfail (fp, c)
871 _IO_FILE *fp;
872 int c;
874 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
875 && (unsigned char) fp->_IO_read_ptr[-1] == c)
876 --fp->_IO_read_ptr;
877 else
879 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
880 if (_IO_have_backup (fp) && !_IO_in_backup (fp))
881 _IO_switch_to_backup_area (fp);
883 if (!_IO_have_backup (fp))
885 /* No backup buffer: allocate one. */
886 /* Use nshort buffer, if unused? (probably not) FIXME */
887 int backup_size = 128;
888 char *bbuf = (char *) malloc (backup_size);
889 if (bbuf == NULL)
890 return EOF;
891 fp->_IO_save_base = bbuf;
892 fp->_IO_save_end = fp->_IO_save_base + backup_size;
893 fp->_IO_backup_base = fp->_IO_save_end;
894 _IO_switch_to_backup_area (fp);
896 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
898 /* Increase size of existing backup buffer. */
899 _IO_size_t new_size;
900 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
901 char *new_buf;
902 new_size = 2 * old_size;
903 new_buf = (char *) malloc (new_size);
904 if (new_buf == NULL)
905 return EOF;
906 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
907 old_size);
908 free (fp->_IO_read_base);
909 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
910 new_buf + new_size);
911 fp->_IO_backup_base = fp->_IO_read_ptr;
914 *--fp->_IO_read_ptr = c;
916 return (unsigned char) c;
919 _IO_fpos64_t
920 _IO_default_seek (fp, offset, dir)
921 _IO_FILE *fp;
922 _IO_off64_t offset;
923 int dir;
925 return _IO_pos_BAD;
929 _IO_default_stat (fp, st)
930 _IO_FILE *fp;
931 void* st;
933 return EOF;
936 _IO_ssize_t
937 _IO_default_read (fp, data, n)
938 _IO_FILE* fp;
939 void *data;
940 _IO_ssize_t n;
942 return -1;
945 _IO_ssize_t
946 _IO_default_write (fp, data, n)
947 _IO_FILE *fp;
948 const void *data;
949 _IO_ssize_t n;
951 return 0;
955 _IO_default_showmanyc (fp)
956 _IO_FILE *fp;
958 return -1;
961 void
962 _IO_default_imbue (fp, locale)
963 _IO_FILE *fp;
964 void *locale;
969 #ifdef TODO
970 #if defined(linux)
971 #define IO_CLEANUP ;
972 #endif
974 #ifdef IO_CLEANUP
975 IO_CLEANUP
976 #else
977 struct __io_defs {
978 __io_defs() { }
979 ~__io_defs() { _IO_cleanup (); }
981 __io_defs io_defs__;
982 #endif
984 #endif /* TODO */
986 #ifdef weak_alias
987 weak_alias (_IO_cleanup, _cleanup)
988 #endif
990 #ifdef text_set_element
991 text_set_element(__libc_atexit, _cleanup);
992 #endif