Update.
[glibc.git] / libio / genops.c
blob85d42face4de4dd9d6fe5e0089fb78e8b1424d06
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 static _IO_lock_t list_all_lock = _IO_lock_initializer;
36 void
37 _IO_un_link (fp)
38 _IO_FILE *fp;
40 if (fp->_flags & _IO_LINKED)
42 _IO_FILE **f;
43 _IO_lock_lock (list_all_lock);
44 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
46 if (*f == fp)
48 *f = fp->_chain;
49 break;
52 _IO_lock_unlock (list_all_lock);
53 fp->_flags &= ~_IO_LINKED;
57 void
58 _IO_link_in (fp)
59 _IO_FILE *fp;
61 if ((fp->_flags & _IO_LINKED) == 0)
63 fp->_flags |= _IO_LINKED;
64 _IO_lock_lock (list_all_lock);
65 fp->_chain = _IO_list_all;
66 _IO_list_all = fp;
67 _IO_lock_unlock (list_all_lock);
71 /* Return minimum _pos markers
72 Assumes the current get area is the main get area. */
73 static _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
75 static _IO_ssize_t
76 _IO_least_marker (fp, end_p)
77 _IO_FILE *fp;
78 char *end_p;
80 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
81 struct _IO_marker *mark;
82 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
83 if (mark->_pos < least_so_far)
84 least_so_far = mark->_pos;
85 return least_so_far;
88 /* Switch current get area from backup buffer to (start of) main get area. */
90 void
91 _IO_switch_to_main_get_area (fp)
92 _IO_FILE *fp;
94 char *tmp;
95 fp->_flags &= ~_IO_IN_BACKUP;
96 /* Swap _IO_read_end and _IO_save_end. */
97 tmp = fp->_IO_read_end;
98 fp->_IO_read_end = fp->_IO_save_end;
99 fp->_IO_save_end= tmp;
100 /* Swap _IO_read_base and _IO_save_base. */
101 tmp = fp->_IO_read_base;
102 fp->_IO_read_base = fp->_IO_save_base;
103 fp->_IO_save_base = tmp;
104 /* Set _IO_read_ptr. */
105 fp->_IO_read_ptr = fp->_IO_read_base;
108 /* Switch current get area from main get area to (end of) backup area. */
110 void
111 _IO_switch_to_backup_area (fp)
112 _IO_FILE *fp;
114 char *tmp;
115 fp->_flags |= _IO_IN_BACKUP;
116 /* Swap _IO_read_end and _IO_save_end. */
117 tmp = fp->_IO_read_end;
118 fp->_IO_read_end = fp->_IO_save_end;
119 fp->_IO_save_end = tmp;
120 /* Swap _IO_read_base and _IO_save_base. */
121 tmp = fp->_IO_read_base;
122 fp->_IO_read_base = fp->_IO_save_base;
123 fp->_IO_save_base = tmp;
124 /* Set _IO_read_ptr. */
125 fp->_IO_read_ptr = fp->_IO_read_end;
129 _IO_switch_to_get_mode (fp)
130 _IO_FILE *fp;
132 if (fp->_IO_write_ptr > fp->_IO_write_base)
133 if (_IO_OVERFLOW (fp, EOF) == EOF)
134 return EOF;
135 if (_IO_in_backup (fp))
136 fp->_IO_read_base = fp->_IO_backup_base;
137 else
139 fp->_IO_read_base = fp->_IO_buf_base;
140 if (fp->_IO_write_ptr > fp->_IO_read_end)
141 fp->_IO_read_end = fp->_IO_write_ptr;
143 fp->_IO_read_ptr = fp->_IO_write_ptr;
145 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
147 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
148 return 0;
151 void
152 _IO_free_backup_area (fp)
153 _IO_FILE *fp;
155 if (_IO_in_backup (fp))
156 _IO_switch_to_main_get_area (fp); /* Just in case. */
157 free (fp->_IO_save_base);
158 fp->_IO_save_base = NULL;
159 fp->_IO_save_end = NULL;
160 fp->_IO_backup_base = NULL;
163 #if 0
165 _IO_switch_to_put_mode (fp)
166 _IO_FILE *fp;
168 fp->_IO_write_base = fp->_IO_read_ptr;
169 fp->_IO_write_ptr = fp->_IO_read_ptr;
170 /* Following is wrong if line- or un-buffered? */
171 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
172 ? fp->_IO_read_end : fp->_IO_buf_end);
174 fp->_IO_read_ptr = fp->_IO_read_end;
175 fp->_IO_read_base = fp->_IO_read_end;
177 fp->_flags |= _IO_CURRENTLY_PUTTING;
178 return 0;
180 #endif
183 __overflow (f, ch)
184 _IO_FILE *f;
185 int ch;
187 return _IO_OVERFLOW (f, ch);
190 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
191 #ifdef _LIBC
192 internal_function
193 #endif
196 static int
197 #ifdef _LIBC
198 internal_function
199 #endif
200 save_for_backup (fp, end_p)
201 _IO_FILE *fp;
202 char *end_p;
204 /* Append [_IO_read_base..end_p] to backup area. */
205 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
206 /* needed_size is how much space we need in the backup area. */
207 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
208 /* FIXME: Dubious arithmetic if pointers are NULL */
209 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
210 _IO_size_t avail; /* Extra space available for future expansion. */
211 _IO_ssize_t delta;
212 struct _IO_marker *mark;
213 if (needed_size > current_Bsize)
215 char *new_buffer;
216 avail = 100;
217 new_buffer = (char *) malloc (avail + needed_size);
218 if (new_buffer == NULL)
219 return EOF; /* FIXME */
220 if (least_mark < 0)
222 #ifdef _LIBC
223 __mempcpy (__mempcpy (new_buffer + avail,
224 fp->_IO_save_end + least_mark,
225 -least_mark),
226 fp->_IO_read_base,
227 end_p - fp->_IO_read_base);
228 #else
229 memcpy (new_buffer + avail,
230 fp->_IO_save_end + least_mark,
231 -least_mark);
232 memcpy (new_buffer + avail - least_mark,
233 fp->_IO_read_base,
234 end_p - fp->_IO_read_base);
235 #endif
237 else
238 memcpy (new_buffer + avail,
239 fp->_IO_read_base + least_mark,
240 needed_size);
241 if (fp->_IO_save_base)
242 free (fp->_IO_save_base);
243 fp->_IO_save_base = new_buffer;
244 fp->_IO_save_end = new_buffer + avail + needed_size;
246 else
248 avail = current_Bsize - needed_size;
249 if (least_mark < 0)
251 memmove (fp->_IO_save_base + avail,
252 fp->_IO_save_end + least_mark,
253 -least_mark);
254 memcpy (fp->_IO_save_base + avail - least_mark,
255 fp->_IO_read_base,
256 end_p - fp->_IO_read_base);
258 else if (needed_size > 0)
259 memcpy (fp->_IO_save_base + avail,
260 fp->_IO_read_base + least_mark,
261 needed_size);
263 fp->_IO_backup_base = fp->_IO_save_base + avail;
264 /* Adjust all the streammarkers. */
265 delta = end_p - fp->_IO_read_base;
266 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
267 mark->_pos -= delta;
268 return 0;
272 __underflow (fp)
273 _IO_FILE *fp;
275 if (_IO_in_put_mode (fp))
276 if (_IO_switch_to_get_mode (fp) == EOF)
277 return EOF;
278 if (fp->_IO_read_ptr < fp->_IO_read_end)
279 return *(unsigned char *) fp->_IO_read_ptr;
280 if (_IO_in_backup (fp))
282 _IO_switch_to_main_get_area (fp);
283 if (fp->_IO_read_ptr < fp->_IO_read_end)
284 return *(unsigned char *) fp->_IO_read_ptr;
286 if (_IO_have_markers (fp))
288 if (save_for_backup (fp, fp->_IO_read_end))
289 return EOF;
291 else if (_IO_have_backup (fp))
292 _IO_free_backup_area (fp);
293 return _IO_UNDERFLOW (fp);
297 __uflow (fp)
298 _IO_FILE *fp;
300 if (_IO_in_put_mode (fp))
301 if (_IO_switch_to_get_mode (fp) == EOF)
302 return EOF;
303 if (fp->_IO_read_ptr < fp->_IO_read_end)
304 return *(unsigned char *) fp->_IO_read_ptr++;
305 if (_IO_in_backup (fp))
307 _IO_switch_to_main_get_area (fp);
308 if (fp->_IO_read_ptr < fp->_IO_read_end)
309 return *(unsigned char *) fp->_IO_read_ptr++;
311 if (_IO_have_markers (fp))
313 if (save_for_backup (fp, fp->_IO_read_end))
314 return EOF;
316 else if (_IO_have_backup (fp))
317 _IO_free_backup_area (fp);
318 return _IO_UFLOW (fp);
321 void
322 _IO_setb (f, b, eb, a)
323 _IO_FILE *f;
324 char *b;
325 char *eb;
326 int a;
328 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
329 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
330 f->_IO_buf_base = b;
331 f->_IO_buf_end = eb;
332 if (a)
333 f->_flags &= ~_IO_USER_BUF;
334 else
335 f->_flags |= _IO_USER_BUF;
338 void
339 _IO_doallocbuf (fp)
340 _IO_FILE *fp;
342 if (fp->_IO_buf_base)
343 return;
344 if (!(fp->_flags & _IO_UNBUFFERED))
345 if (_IO_DOALLOCATE (fp) != EOF)
346 return;
347 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
351 _IO_default_underflow (fp)
352 _IO_FILE *fp;
354 return EOF;
358 _IO_default_uflow (fp)
359 _IO_FILE *fp;
361 int ch = _IO_UNDERFLOW (fp);
362 if (ch == EOF)
363 return EOF;
364 return *(unsigned char *) fp->_IO_read_ptr++;
367 _IO_size_t
368 _IO_default_xsputn (f, data, n)
369 _IO_FILE *f;
370 const void *data;
371 _IO_size_t n;
373 const char *s = (char *) data;
374 _IO_size_t more = n;
375 if (more <= 0)
376 return 0;
377 for (;;)
379 /* Space available. */
380 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
381 if (count > 0)
383 if ((_IO_size_t) count > more)
384 count = more;
385 if (count > 20)
387 #ifdef _LIBC
388 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
389 #else
390 memcpy (f->_IO_write_ptr, s, count);
391 f->_IO_write_ptr += count;
392 #endif
393 s += count;
395 else if (count <= 0)
396 count = 0;
397 else
399 char *p = f->_IO_write_ptr;
400 _IO_ssize_t i;
401 for (i = count; --i >= 0; )
402 *p++ = *s++;
403 f->_IO_write_ptr = p;
405 more -= count;
407 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
408 break;
409 more--;
411 return n - more;
414 _IO_size_t
415 _IO_sgetn (fp, data, n)
416 _IO_FILE *fp;
417 void *data;
418 _IO_size_t n;
420 /* FIXME handle putback buffer here! */
421 return _IO_XSGETN (fp, data, n);
424 _IO_size_t
425 _IO_default_xsgetn (fp, data, n)
426 _IO_FILE *fp;
427 void *data;
428 _IO_size_t n;
430 _IO_size_t more = n;
431 char *s = (char*) data;
432 for (;;)
434 /* Data available. */
435 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
436 if (count > 0)
438 if ((_IO_size_t) count > more)
439 count = more;
440 if (count > 20)
442 #ifdef _LIBC
443 s = __mempcpy (s, fp->_IO_read_ptr, count);
444 #else
445 memcpy (s, fp->_IO_read_ptr, count);
446 s += count;
447 #endif
448 fp->_IO_read_ptr += count;
450 else if (count <= 0)
451 count = 0;
452 else
454 char *p = fp->_IO_read_ptr;
455 int i = (int) count;
456 while (--i >= 0)
457 *s++ = *p++;
458 fp->_IO_read_ptr = p;
460 more -= count;
462 if (more == 0 || __underflow (fp) == EOF)
463 break;
465 return n - more;
468 #if 0
469 /* Seems not to be needed. --drepper */
471 _IO_sync (fp)
472 _IO_FILE *fp;
474 return 0;
476 #endif
478 _IO_FILE *
479 _IO_default_setbuf (fp, p, len)
480 _IO_FILE *fp;
481 char *p;
482 _IO_ssize_t len;
484 if (_IO_SYNC (fp) == EOF)
485 return NULL;
486 if (p == NULL || len == 0)
488 fp->_flags |= _IO_UNBUFFERED;
489 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
491 else
493 fp->_flags &= ~_IO_UNBUFFERED;
494 _IO_setb (fp, p, p+len, 0);
496 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
497 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
498 return fp;
501 _IO_fpos64_t
502 _IO_default_seekpos (fp, pos, mode)
503 _IO_FILE *fp;
504 _IO_fpos64_t pos;
505 int mode;
507 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
511 _IO_default_doallocate (fp)
512 _IO_FILE *fp;
514 char *buf;
516 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
517 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
518 return 1;
521 void
522 _IO_init (fp, flags)
523 _IO_FILE *fp;
524 int flags;
526 fp->_flags = _IO_MAGIC|flags;
527 fp->_IO_buf_base = NULL;
528 fp->_IO_buf_end = NULL;
529 fp->_IO_read_base = NULL;
530 fp->_IO_read_ptr = NULL;
531 fp->_IO_read_end = NULL;
532 fp->_IO_write_base = NULL;
533 fp->_IO_write_ptr = NULL;
534 fp->_IO_write_end = NULL;
535 fp->_chain = NULL; /* Not necessary. */
537 fp->_IO_save_base = NULL;
538 fp->_IO_backup_base = NULL;
539 fp->_IO_save_end = NULL;
540 fp->_markers = NULL;
541 fp->_cur_column = 0;
542 #if _IO_JUMPS_OFFSET
543 fp->_vtable_offset = 0;
544 #endif
545 #ifdef _IO_MTSAFE_IO
546 _IO_lock_init (*fp->_lock);
547 #endif
551 _IO_default_sync (fp)
552 _IO_FILE *fp;
554 return 0;
557 /* The way the C++ classes are mapped into the C functions in the
558 current implementation, this function can get called twice! */
560 void
561 _IO_default_finish (fp, dummy)
562 _IO_FILE *fp;
563 int dummy;
565 struct _IO_marker *mark;
566 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
568 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
569 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
572 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
573 mark->_sbuf = NULL;
575 if (fp->_IO_save_base)
577 free (fp->_IO_save_base);
578 fp->_IO_save_base = NULL;
581 #ifdef _IO_MTSAFE_IO
582 _IO_lock_fini (*fp->_lock);
583 #endif
585 _IO_un_link (fp);
588 _IO_fpos64_t
589 _IO_default_seekoff (fp, offset, dir, mode)
590 _IO_FILE *fp;
591 _IO_off64_t offset;
592 int dir;
593 int mode;
595 return _IO_pos_BAD;
599 _IO_sputbackc (fp, c)
600 _IO_FILE *fp;
601 int c;
603 int result;
605 if (fp->_IO_read_ptr > fp->_IO_read_base
606 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
608 fp->_IO_read_ptr--;
609 result = (unsigned char) c;
611 else
612 result = _IO_PBACKFAIL (fp, c);
614 if (result != EOF)
615 fp->_flags &= ~_IO_EOF_SEEN;
617 return result;
621 _IO_sungetc (fp)
622 _IO_FILE *fp;
624 int result;
626 if (fp->_IO_read_ptr > fp->_IO_read_base)
628 fp->_IO_read_ptr--;
629 result = (unsigned char) *fp->_IO_read_ptr;
631 else
632 result = _IO_PBACKFAIL (fp, EOF);
634 if (result != EOF)
635 fp->_flags &= ~_IO_EOF_SEEN;
637 return result;
640 #if 0 /* Work in progress */
641 /* Seems not to be needed. */
642 #if 0
643 void
644 _IO_set_column (fp, c)
645 _IO_FILE *fp;
646 int c;
648 if (c == -1)
649 fp->_column = -1;
650 else
651 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
653 #else
655 _IO_set_column (fp, i)
656 _IO_FILE *fp;
657 int i;
659 fp->_cur_column = i + 1;
660 return 0;
662 #endif
663 #endif
666 unsigned
667 _IO_adjust_column (start, line, count)
668 unsigned start;
669 const char *line;
670 int count;
672 const char *ptr = line + count;
673 while (ptr > line)
674 if (*--ptr == '\n')
675 return line + count - ptr - 1;
676 return start + count;
679 #if 0
680 /* Seems not to be needed. --drepper */
682 _IO_get_column (fp)
683 _IO_FILE *fp;
685 if (fp->_cur_column)
686 return _IO_adjust_column (fp->_cur_column - 1,
687 fp->_IO_write_base,
688 fp->_IO_write_ptr - fp->_IO_write_base);
689 return -1;
691 #endif
694 _IO_flush_all ()
696 int result = 0;
697 _IO_FILE *fp;
698 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
699 if (fp->_IO_write_ptr > fp->_IO_write_base
700 && _IO_OVERFLOW (fp, EOF) == EOF)
701 result = EOF;
702 return result;
705 void
706 _IO_flush_all_linebuffered ()
708 _IO_FILE *fp;
709 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
710 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
711 _IO_OVERFLOW (fp, EOF);
714 static void _IO_unbuffer_write __P ((void));
716 static void
717 _IO_unbuffer_write ()
719 _IO_FILE *fp;
720 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
721 if (! (fp->_flags & _IO_UNBUFFERED)
722 && (! (fp->_flags & _IO_NO_WRITES)
723 || (fp->_flags & _IO_IS_APPENDING)))
724 _IO_SETBUF (fp, NULL, 0);
728 _IO_cleanup ()
730 int result = _IO_flush_all ();
732 /* We currently don't have a reliable mechanism for making sure that
733 C++ static destructors are executed in the correct order.
734 So it is possible that other static destructors might want to
735 write to cout - and they're supposed to be able to do so.
737 The following will make the standard streambufs be unbuffered,
738 which forces any output from late destructors to be written out. */
739 _IO_unbuffer_write ();
741 return result;
745 void
746 _IO_init_marker (marker, fp)
747 struct _IO_marker *marker;
748 _IO_FILE *fp;
750 marker->_sbuf = fp;
751 if (_IO_in_put_mode (fp))
752 _IO_switch_to_get_mode (fp);
753 if (_IO_in_backup (fp))
754 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
755 else
756 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
758 /* Should perhaps sort the chain? */
759 marker->_next = fp->_markers;
760 fp->_markers = marker;
763 void
764 _IO_remove_marker (marker)
765 struct _IO_marker *marker;
767 /* Unlink from sb's chain. */
768 struct _IO_marker **ptr = &marker->_sbuf->_markers;
769 for (; ; ptr = &(*ptr)->_next)
771 if (*ptr == NULL)
772 break;
773 else if (*ptr == marker)
775 *ptr = marker->_next;
776 return;
779 #if 0
780 if _sbuf has a backup area that is no longer needed, should we delete
781 it now, or wait until the next underflow?
782 #endif
785 #define BAD_DELTA EOF
788 _IO_marker_difference (mark1, mark2)
789 struct _IO_marker *mark1;
790 struct _IO_marker *mark2;
792 return mark1->_pos - mark2->_pos;
795 /* Return difference between MARK and current position of MARK's stream. */
797 _IO_marker_delta (mark)
798 struct _IO_marker *mark;
800 int cur_pos;
801 if (mark->_sbuf == NULL)
802 return BAD_DELTA;
803 if (_IO_in_backup (mark->_sbuf))
804 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
805 else
806 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
807 return mark->_pos - cur_pos;
811 _IO_seekmark (fp, mark, delta)
812 _IO_FILE *fp;
813 struct _IO_marker *mark;
814 int delta;
816 if (mark->_sbuf != fp)
817 return EOF;
818 if (mark->_pos >= 0)
820 if (_IO_in_backup (fp))
821 _IO_switch_to_main_get_area (fp);
822 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
824 else
826 if (!_IO_in_backup (fp))
827 _IO_switch_to_backup_area (fp);
828 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
830 return 0;
833 void
834 _IO_unsave_markers (fp)
835 _IO_FILE *fp;
837 struct _IO_marker *mark = fp->_markers;
838 if (mark)
840 #ifdef TODO
841 streampos offset = seekoff (0, ios::cur, ios::in);
842 if (offset != EOF)
844 offset += eGptr () - Gbase ();
845 for ( ; mark != NULL; mark = mark->_next)
846 mark->set_streampos (mark->_pos + offset);
848 else
850 for ( ; mark != NULL; mark = mark->_next)
851 mark->set_streampos (EOF);
853 #endif
854 fp->_markers = 0;
857 if (_IO_have_backup (fp))
858 _IO_free_backup_area (fp);
861 #if 0
862 /* Seems not to be needed. --drepper */
864 _IO_nobackup_pbackfail (fp, c)
865 _IO_FILE *fp;
866 int c;
868 if (fp->_IO_read_ptr > fp->_IO_read_base)
869 fp->_IO_read_ptr--;
870 if (c != EOF && *fp->_IO_read_ptr != c)
871 *fp->_IO_read_ptr = c;
872 return (unsigned char) c;
874 #endif
877 _IO_default_pbackfail (fp, c)
878 _IO_FILE *fp;
879 int c;
881 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
882 && (unsigned char) fp->_IO_read_ptr[-1] == c)
883 --fp->_IO_read_ptr;
884 else
886 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
887 if (!_IO_in_backup (fp))
889 /* We need to keep the invariant that the main get area
890 logically follows the backup area. */
891 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
893 if (save_for_backup (fp, fp->_IO_read_ptr))
894 return EOF;
896 else if (!_IO_have_backup (fp))
898 /* No backup buffer: allocate one. */
899 /* Use nshort buffer, if unused? (probably not) FIXME */
900 int backup_size = 128;
901 char *bbuf = (char *) malloc (backup_size);
902 if (bbuf == NULL)
903 return EOF;
904 fp->_IO_save_base = bbuf;
905 fp->_IO_save_end = fp->_IO_save_base + backup_size;
906 fp->_IO_backup_base = fp->_IO_save_end;
908 fp->_IO_read_base = fp->_IO_read_ptr;
909 _IO_switch_to_backup_area (fp);
911 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
913 /* Increase size of existing backup buffer. */
914 _IO_size_t new_size;
915 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
916 char *new_buf;
917 new_size = 2 * old_size;
918 new_buf = (char *) malloc (new_size);
919 if (new_buf == NULL)
920 return EOF;
921 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
922 old_size);
923 free (fp->_IO_read_base);
924 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
925 new_buf + new_size);
926 fp->_IO_backup_base = fp->_IO_read_ptr;
929 *--fp->_IO_read_ptr = c;
931 return (unsigned char) c;
934 _IO_fpos64_t
935 _IO_default_seek (fp, offset, dir)
936 _IO_FILE *fp;
937 _IO_off64_t offset;
938 int dir;
940 return _IO_pos_BAD;
944 _IO_default_stat (fp, st)
945 _IO_FILE *fp;
946 void* st;
948 return EOF;
951 _IO_ssize_t
952 _IO_default_read (fp, data, n)
953 _IO_FILE* fp;
954 void *data;
955 _IO_ssize_t n;
957 return -1;
960 _IO_ssize_t
961 _IO_default_write (fp, data, n)
962 _IO_FILE *fp;
963 const void *data;
964 _IO_ssize_t n;
966 return 0;
970 _IO_default_showmanyc (fp)
971 _IO_FILE *fp;
973 return -1;
976 void
977 _IO_default_imbue (fp, locale)
978 _IO_FILE *fp;
979 void *locale;
984 #ifdef TODO
985 #if defined(linux)
986 #define IO_CLEANUP ;
987 #endif
989 #ifdef IO_CLEANUP
990 IO_CLEANUP
991 #else
992 struct __io_defs {
993 __io_defs() { }
994 ~__io_defs() { _IO_cleanup (); }
996 __io_defs io_defs__;
997 #endif
999 #endif /* TODO */
1001 #ifdef weak_alias
1002 weak_alias (_IO_cleanup, _cleanup)
1003 #endif
1005 #ifdef text_set_element
1006 text_set_element(__libc_atexit, _cleanup);
1007 #endif