Update.
[glibc.git] / libio / genops.c
blobbdbde0ce4b11ff2de271c25feef59ccf62c84d68
1 /* Copyright (C) 1993, 1995, 1997-1999, 2000 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 #ifdef _IO_MTSAFE_IO
35 static _IO_lock_t list_all_lock = _IO_lock_initializer;
36 #endif
38 void
39 _IO_un_link (fp)
40 _IO_FILE *fp;
42 if (fp->_flags & _IO_LINKED)
44 _IO_FILE **f;
45 #ifdef _IO_MTSAFE_IO
46 _IO_lock_lock (list_all_lock);
47 #endif
48 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
50 if (*f == fp)
52 *f = fp->_chain;
53 break;
56 #ifdef _IO_MTSAFE_IO
57 _IO_lock_unlock (list_all_lock);
58 #endif
59 fp->_flags &= ~_IO_LINKED;
63 void
64 _IO_link_in (fp)
65 _IO_FILE *fp;
67 if ((fp->_flags & _IO_LINKED) == 0)
69 fp->_flags |= _IO_LINKED;
70 #ifdef _IO_MTSAFE_IO
71 _IO_lock_lock (list_all_lock);
72 #endif
73 fp->_chain = _IO_list_all;
74 _IO_list_all = fp;
75 #ifdef _IO_MTSAFE_IO
76 _IO_lock_unlock (list_all_lock);
77 #endif
81 /* Return minimum _pos markers
82 Assumes the current get area is the main get area. */
83 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
85 _IO_ssize_t
86 _IO_least_marker (fp, end_p)
87 _IO_FILE *fp;
88 char *end_p;
90 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
91 struct _IO_marker *mark;
92 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
93 if (mark->_pos < least_so_far)
94 least_so_far = mark->_pos;
95 return least_so_far;
98 /* Switch current get area from backup buffer to (start of) main get area. */
100 void
101 _IO_switch_to_main_get_area (fp)
102 _IO_FILE *fp;
104 char *tmp;
105 fp->_flags &= ~_IO_IN_BACKUP;
106 /* Swap _IO_read_end and _IO_save_end. */
107 tmp = fp->_IO_read_end;
108 fp->_IO_read_end = fp->_IO_save_end;
109 fp->_IO_save_end= tmp;
110 /* Swap _IO_read_base and _IO_save_base. */
111 tmp = fp->_IO_read_base;
112 fp->_IO_read_base = fp->_IO_save_base;
113 fp->_IO_save_base = tmp;
114 /* Set _IO_read_ptr. */
115 fp->_IO_read_ptr = fp->_IO_read_base;
118 /* Switch current get area from main get area to (end of) backup area. */
120 void
121 _IO_switch_to_backup_area (fp)
122 _IO_FILE *fp;
124 char *tmp;
125 fp->_flags |= _IO_IN_BACKUP;
126 /* Swap _IO_read_end and _IO_save_end. */
127 tmp = fp->_IO_read_end;
128 fp->_IO_read_end = fp->_IO_save_end;
129 fp->_IO_save_end = tmp;
130 /* Swap _IO_read_base and _IO_save_base. */
131 tmp = fp->_IO_read_base;
132 fp->_IO_read_base = fp->_IO_save_base;
133 fp->_IO_save_base = tmp;
134 /* Set _IO_read_ptr. */
135 fp->_IO_read_ptr = fp->_IO_read_end;
139 _IO_switch_to_get_mode (fp)
140 _IO_FILE *fp;
142 if (fp->_IO_write_ptr > fp->_IO_write_base)
143 if (_IO_OVERFLOW (fp, EOF) == EOF)
144 return EOF;
145 if (_IO_in_backup (fp))
146 fp->_IO_read_base = fp->_IO_backup_base;
147 else
149 fp->_IO_read_base = fp->_IO_buf_base;
150 if (fp->_IO_write_ptr > fp->_IO_read_end)
151 fp->_IO_read_end = fp->_IO_write_ptr;
153 fp->_IO_read_ptr = fp->_IO_write_ptr;
155 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
157 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
158 return 0;
161 void
162 _IO_free_backup_area (fp)
163 _IO_FILE *fp;
165 if (_IO_in_backup (fp))
166 _IO_switch_to_main_get_area (fp); /* Just in case. */
167 free (fp->_IO_save_base);
168 fp->_IO_save_base = NULL;
169 fp->_IO_save_end = NULL;
170 fp->_IO_backup_base = NULL;
173 #if 0
175 _IO_switch_to_put_mode (fp)
176 _IO_FILE *fp;
178 fp->_IO_write_base = fp->_IO_read_ptr;
179 fp->_IO_write_ptr = fp->_IO_read_ptr;
180 /* Following is wrong if line- or un-buffered? */
181 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
182 ? fp->_IO_read_end : fp->_IO_buf_end);
184 fp->_IO_read_ptr = fp->_IO_read_end;
185 fp->_IO_read_base = fp->_IO_read_end;
187 fp->_flags |= _IO_CURRENTLY_PUTTING;
188 return 0;
190 #endif
193 __overflow (f, ch)
194 _IO_FILE *f;
195 int ch;
197 return _IO_OVERFLOW (f, ch);
200 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
201 #ifdef _LIBC
202 internal_function
203 #endif
206 static int
207 #ifdef _LIBC
208 internal_function
209 #endif
210 save_for_backup (fp, end_p)
211 _IO_FILE *fp;
212 char *end_p;
214 /* Append [_IO_read_base..end_p] to backup area. */
215 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
216 /* needed_size is how much space we need in the backup area. */
217 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
218 /* FIXME: Dubious arithmetic if pointers are NULL */
219 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
220 _IO_size_t avail; /* Extra space available for future expansion. */
221 _IO_ssize_t delta;
222 struct _IO_marker *mark;
223 if (needed_size > current_Bsize)
225 char *new_buffer;
226 avail = 100;
227 new_buffer = (char *) malloc (avail + needed_size);
228 if (new_buffer == NULL)
229 return EOF; /* FIXME */
230 if (least_mark < 0)
232 #ifdef _LIBC
233 __mempcpy (__mempcpy (new_buffer + avail,
234 fp->_IO_save_end + least_mark,
235 -least_mark),
236 fp->_IO_read_base,
237 end_p - fp->_IO_read_base);
238 #else
239 memcpy (new_buffer + avail,
240 fp->_IO_save_end + least_mark,
241 -least_mark);
242 memcpy (new_buffer + avail - least_mark,
243 fp->_IO_read_base,
244 end_p - fp->_IO_read_base);
245 #endif
247 else
248 memcpy (new_buffer + avail,
249 fp->_IO_read_base + least_mark,
250 needed_size);
251 if (fp->_IO_save_base)
252 free (fp->_IO_save_base);
253 fp->_IO_save_base = new_buffer;
254 fp->_IO_save_end = new_buffer + avail + needed_size;
256 else
258 avail = current_Bsize - needed_size;
259 if (least_mark < 0)
261 memmove (fp->_IO_save_base + avail,
262 fp->_IO_save_end + least_mark,
263 -least_mark);
264 memcpy (fp->_IO_save_base + avail - least_mark,
265 fp->_IO_read_base,
266 end_p - fp->_IO_read_base);
268 else if (needed_size > 0)
269 memcpy (fp->_IO_save_base + avail,
270 fp->_IO_read_base + least_mark,
271 needed_size);
273 fp->_IO_backup_base = fp->_IO_save_base + avail;
274 /* Adjust all the streammarkers. */
275 delta = end_p - fp->_IO_read_base;
276 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
277 mark->_pos -= delta;
278 return 0;
282 __underflow (fp)
283 _IO_FILE *fp;
285 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
286 return EOF;
288 if (_IO_in_put_mode (fp))
289 if (_IO_switch_to_get_mode (fp) == EOF)
290 return EOF;
291 if (fp->_IO_read_ptr < fp->_IO_read_end)
292 return *(unsigned char *) fp->_IO_read_ptr;
293 if (_IO_in_backup (fp))
295 _IO_switch_to_main_get_area (fp);
296 if (fp->_IO_read_ptr < fp->_IO_read_end)
297 return *(unsigned char *) fp->_IO_read_ptr;
299 if (_IO_have_markers (fp))
301 if (save_for_backup (fp, fp->_IO_read_end))
302 return EOF;
304 else if (_IO_have_backup (fp))
305 _IO_free_backup_area (fp);
306 return _IO_UNDERFLOW (fp);
310 __uflow (fp)
311 _IO_FILE *fp;
313 if (fp->_vtable_offset == 0 && _IO_fwide (fp, -1) != -1)
314 return EOF;
316 if (_IO_in_put_mode (fp))
317 if (_IO_switch_to_get_mode (fp) == EOF)
318 return EOF;
319 if (fp->_IO_read_ptr < fp->_IO_read_end)
320 return *(unsigned char *) fp->_IO_read_ptr++;
321 if (_IO_in_backup (fp))
323 _IO_switch_to_main_get_area (fp);
324 if (fp->_IO_read_ptr < fp->_IO_read_end)
325 return *(unsigned char *) fp->_IO_read_ptr++;
327 if (_IO_have_markers (fp))
329 if (save_for_backup (fp, fp->_IO_read_end))
330 return EOF;
332 else if (_IO_have_backup (fp))
333 _IO_free_backup_area (fp);
334 return _IO_UFLOW (fp);
337 void
338 _IO_setb (f, b, eb, a)
339 _IO_FILE *f;
340 char *b;
341 char *eb;
342 int a;
344 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
345 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
346 f->_IO_buf_base = b;
347 f->_IO_buf_end = eb;
348 if (a)
349 f->_flags &= ~_IO_USER_BUF;
350 else
351 f->_flags |= _IO_USER_BUF;
354 void
355 _IO_doallocbuf (fp)
356 _IO_FILE *fp;
358 if (fp->_IO_buf_base)
359 return;
360 if (!(fp->_flags & _IO_UNBUFFERED))
361 if (_IO_DOALLOCATE (fp) != EOF)
362 return;
363 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
367 _IO_default_underflow (fp)
368 _IO_FILE *fp;
370 return EOF;
374 _IO_default_uflow (fp)
375 _IO_FILE *fp;
377 int ch = _IO_UNDERFLOW (fp);
378 if (ch == EOF)
379 return EOF;
380 return *(unsigned char *) fp->_IO_read_ptr++;
383 _IO_size_t
384 _IO_default_xsputn (f, data, n)
385 _IO_FILE *f;
386 const void *data;
387 _IO_size_t n;
389 const char *s = (char *) data;
390 _IO_size_t more = n;
391 if (more <= 0)
392 return 0;
393 for (;;)
395 /* Space available. */
396 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
397 if (count > 0)
399 if ((_IO_size_t) count > more)
400 count = more;
401 if (count > 20)
403 #ifdef _LIBC
404 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
405 #else
406 memcpy (f->_IO_write_ptr, s, count);
407 f->_IO_write_ptr += count;
408 #endif
409 s += count;
411 else if (count <= 0)
412 count = 0;
413 else
415 char *p = f->_IO_write_ptr;
416 _IO_ssize_t i;
417 for (i = count; --i >= 0; )
418 *p++ = *s++;
419 f->_IO_write_ptr = p;
421 more -= count;
423 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
424 break;
425 more--;
427 return n - more;
430 _IO_size_t
431 _IO_sgetn (fp, data, n)
432 _IO_FILE *fp;
433 void *data;
434 _IO_size_t n;
436 /* FIXME handle putback buffer here! */
437 return _IO_XSGETN (fp, data, n);
440 _IO_size_t
441 _IO_default_xsgetn (fp, data, n)
442 _IO_FILE *fp;
443 void *data;
444 _IO_size_t n;
446 _IO_size_t more = n;
447 char *s = (char*) data;
448 for (;;)
450 /* Data available. */
451 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
452 if (count > 0)
454 if ((_IO_size_t) count > more)
455 count = more;
456 if (count > 20)
458 #ifdef _LIBC
459 s = __mempcpy (s, fp->_IO_read_ptr, count);
460 #else
461 memcpy (s, fp->_IO_read_ptr, count);
462 s += count;
463 #endif
464 fp->_IO_read_ptr += count;
466 else if (count <= 0)
467 count = 0;
468 else
470 char *p = fp->_IO_read_ptr;
471 int i = (int) count;
472 while (--i >= 0)
473 *s++ = *p++;
474 fp->_IO_read_ptr = p;
476 more -= count;
478 if (more == 0 || __underflow (fp) == EOF)
479 break;
481 return n - more;
484 #if 0
485 /* Seems not to be needed. --drepper */
487 _IO_sync (fp)
488 _IO_FILE *fp;
490 return 0;
492 #endif
494 _IO_FILE *
495 _IO_default_setbuf (fp, p, len)
496 _IO_FILE *fp;
497 char *p;
498 _IO_ssize_t len;
500 if (_IO_SYNC (fp) == EOF)
501 return NULL;
502 if (p == NULL || len == 0)
504 fp->_flags |= _IO_UNBUFFERED;
505 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
507 else
509 fp->_flags &= ~_IO_UNBUFFERED;
510 _IO_setb (fp, p, p+len, 0);
512 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
513 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
514 return fp;
517 _IO_off64_t
518 _IO_default_seekpos (fp, pos, mode)
519 _IO_FILE *fp;
520 _IO_off64_t pos;
521 int mode;
523 return _IO_SEEKOFF (fp, pos, 0, mode);
527 _IO_default_doallocate (fp)
528 _IO_FILE *fp;
530 char *buf;
532 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
533 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
534 return 1;
537 void
538 _IO_init (fp, flags)
539 _IO_FILE *fp;
540 int flags;
542 _IO_no_init (fp, flags, -1, NULL, NULL);
545 void
546 _IO_no_init (fp, flags, orientation, wd, jmp)
547 _IO_FILE *fp;
548 int flags;
549 int orientation;
550 struct _IO_wide_data *wd;
551 struct _IO_jump_t *jmp;
553 fp->_flags = _IO_MAGIC|flags;
554 fp->_IO_buf_base = NULL;
555 fp->_IO_buf_end = NULL;
556 fp->_IO_read_base = NULL;
557 fp->_IO_read_ptr = NULL;
558 fp->_IO_read_end = NULL;
559 fp->_IO_write_base = NULL;
560 fp->_IO_write_ptr = NULL;
561 fp->_IO_write_end = NULL;
562 fp->_chain = NULL; /* Not necessary. */
564 fp->_IO_save_base = NULL;
565 fp->_IO_backup_base = NULL;
566 fp->_IO_save_end = NULL;
567 fp->_markers = NULL;
568 fp->_cur_column = 0;
569 #if _IO_JUMPS_OFFSET
570 fp->_vtable_offset = 0;
571 #endif
572 #ifdef _IO_MTSAFE_IO
573 _IO_lock_init (*fp->_lock);
574 #endif
575 fp->_mode = orientation;
576 if (orientation >= 0)
578 fp->_wide_data = wd;
579 fp->_wide_data->_IO_buf_base = NULL;
580 fp->_wide_data->_IO_buf_end = NULL;
581 fp->_wide_data->_IO_read_base = NULL;
582 fp->_wide_data->_IO_read_ptr = NULL;
583 fp->_wide_data->_IO_read_end = NULL;
584 fp->_wide_data->_IO_write_base = NULL;
585 fp->_wide_data->_IO_write_ptr = NULL;
586 fp->_wide_data->_IO_write_end = NULL;
587 fp->_wide_data->_IO_save_base = NULL;
588 fp->_wide_data->_IO_backup_base = NULL;
589 fp->_wide_data->_IO_save_end = NULL;
591 fp->_wide_data->_wide_vtable = jmp;
596 _IO_default_sync (fp)
597 _IO_FILE *fp;
599 return 0;
602 /* The way the C++ classes are mapped into the C functions in the
603 current implementation, this function can get called twice! */
605 void
606 _IO_default_finish (fp, dummy)
607 _IO_FILE *fp;
608 int dummy;
610 struct _IO_marker *mark;
611 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
613 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
614 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
617 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
618 mark->_sbuf = NULL;
620 if (fp->_IO_save_base)
622 free (fp->_IO_save_base);
623 fp->_IO_save_base = NULL;
626 #ifdef _IO_MTSAFE_IO
627 _IO_lock_fini (*fp->_lock);
628 #endif
630 _IO_un_link (fp);
633 _IO_off64_t
634 _IO_default_seekoff (fp, offset, dir, mode)
635 _IO_FILE *fp;
636 _IO_off64_t offset;
637 int dir;
638 int mode;
640 return _IO_pos_BAD;
644 _IO_sputbackc (fp, c)
645 _IO_FILE *fp;
646 int c;
648 int result;
650 if (fp->_IO_read_ptr > fp->_IO_read_base
651 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
653 fp->_IO_read_ptr--;
654 result = (unsigned char) c;
656 else
657 result = _IO_PBACKFAIL (fp, c);
659 if (result != EOF)
660 fp->_flags &= ~_IO_EOF_SEEN;
662 return result;
666 _IO_sungetc (fp)
667 _IO_FILE *fp;
669 int result;
671 if (fp->_IO_read_ptr > fp->_IO_read_base)
673 fp->_IO_read_ptr--;
674 result = (unsigned char) *fp->_IO_read_ptr;
676 else
677 result = _IO_PBACKFAIL (fp, EOF);
679 if (result != EOF)
680 fp->_flags &= ~_IO_EOF_SEEN;
682 return result;
685 #if 0 /* Work in progress */
686 /* Seems not to be needed. */
687 #if 0
688 void
689 _IO_set_column (fp, c)
690 _IO_FILE *fp;
691 int c;
693 if (c == -1)
694 fp->_column = -1;
695 else
696 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
698 #else
700 _IO_set_column (fp, i)
701 _IO_FILE *fp;
702 int i;
704 fp->_cur_column = i + 1;
705 return 0;
707 #endif
708 #endif
711 unsigned
712 _IO_adjust_column (start, line, count)
713 unsigned start;
714 const char *line;
715 int count;
717 const char *ptr = line + count;
718 while (ptr > line)
719 if (*--ptr == '\n')
720 return line + count - ptr - 1;
721 return start + count;
724 #if 0
725 /* Seems not to be needed. --drepper */
727 _IO_get_column (fp)
728 _IO_FILE *fp;
730 if (fp->_cur_column)
731 return _IO_adjust_column (fp->_cur_column - 1,
732 fp->_IO_write_base,
733 fp->_IO_write_ptr - fp->_IO_write_base);
734 return -1;
736 #endif
739 _IO_flush_all ()
741 int result = 0;
742 _IO_FILE *fp;
743 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
744 if (((fp->_mode < 0 && fp->_IO_write_ptr > fp->_IO_write_base)
745 || (fp->_vtable_offset == 0
746 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
747 > fp->_wide_data->_IO_write_base)))
748 && _IO_OVERFLOW (fp, EOF) == EOF)
749 result = EOF;
750 return result;
753 void
754 _IO_flush_all_linebuffered ()
756 _IO_FILE *fp;
757 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
758 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
759 _IO_OVERFLOW (fp, EOF);
762 static void _IO_unbuffer_write __P ((void));
764 static void
765 _IO_unbuffer_write ()
767 _IO_FILE *fp;
768 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
769 if (! (fp->_flags & _IO_UNBUFFERED)
770 && (! (fp->_flags & _IO_NO_WRITES)
771 || (fp->_flags & _IO_IS_APPENDING)))
772 _IO_SETBUF (fp, NULL, 0);
776 _IO_cleanup ()
778 int result = _IO_flush_all ();
780 /* We currently don't have a reliable mechanism for making sure that
781 C++ static destructors are executed in the correct order.
782 So it is possible that other static destructors might want to
783 write to cout - and they're supposed to be able to do so.
785 The following will make the standard streambufs be unbuffered,
786 which forces any output from late destructors to be written out. */
787 _IO_unbuffer_write ();
789 return result;
793 void
794 _IO_init_marker (marker, fp)
795 struct _IO_marker *marker;
796 _IO_FILE *fp;
798 marker->_sbuf = fp;
799 if (_IO_in_put_mode (fp))
800 _IO_switch_to_get_mode (fp);
801 if (_IO_in_backup (fp))
802 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
803 else
804 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
806 /* Should perhaps sort the chain? */
807 marker->_next = fp->_markers;
808 fp->_markers = marker;
811 void
812 _IO_remove_marker (marker)
813 struct _IO_marker *marker;
815 /* Unlink from sb's chain. */
816 struct _IO_marker **ptr = &marker->_sbuf->_markers;
817 for (; ; ptr = &(*ptr)->_next)
819 if (*ptr == NULL)
820 break;
821 else if (*ptr == marker)
823 *ptr = marker->_next;
824 return;
827 #if 0
828 if _sbuf has a backup area that is no longer needed, should we delete
829 it now, or wait until the next underflow?
830 #endif
833 #define BAD_DELTA EOF
836 _IO_marker_difference (mark1, mark2)
837 struct _IO_marker *mark1;
838 struct _IO_marker *mark2;
840 return mark1->_pos - mark2->_pos;
843 /* Return difference between MARK and current position of MARK's stream. */
845 _IO_marker_delta (mark)
846 struct _IO_marker *mark;
848 int cur_pos;
849 if (mark->_sbuf == NULL)
850 return BAD_DELTA;
851 if (_IO_in_backup (mark->_sbuf))
852 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
853 else
854 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
855 return mark->_pos - cur_pos;
859 _IO_seekmark (fp, mark, delta)
860 _IO_FILE *fp;
861 struct _IO_marker *mark;
862 int delta;
864 if (mark->_sbuf != fp)
865 return EOF;
866 if (mark->_pos >= 0)
868 if (_IO_in_backup (fp))
869 _IO_switch_to_main_get_area (fp);
870 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
872 else
874 if (!_IO_in_backup (fp))
875 _IO_switch_to_backup_area (fp);
876 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
878 return 0;
881 void
882 _IO_unsave_markers (fp)
883 _IO_FILE *fp;
885 struct _IO_marker *mark = fp->_markers;
886 if (mark)
888 #ifdef TODO
889 streampos offset = seekoff (0, ios::cur, ios::in);
890 if (offset != EOF)
892 offset += eGptr () - Gbase ();
893 for ( ; mark != NULL; mark = mark->_next)
894 mark->set_streampos (mark->_pos + offset);
896 else
898 for ( ; mark != NULL; mark = mark->_next)
899 mark->set_streampos (EOF);
901 #endif
902 fp->_markers = 0;
905 if (_IO_have_backup (fp))
906 _IO_free_backup_area (fp);
909 #if 0
910 /* Seems not to be needed. --drepper */
912 _IO_nobackup_pbackfail (fp, c)
913 _IO_FILE *fp;
914 int c;
916 if (fp->_IO_read_ptr > fp->_IO_read_base)
917 fp->_IO_read_ptr--;
918 if (c != EOF && *fp->_IO_read_ptr != c)
919 *fp->_IO_read_ptr = c;
920 return (unsigned char) c;
922 #endif
925 _IO_default_pbackfail (fp, c)
926 _IO_FILE *fp;
927 int c;
929 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
930 && (unsigned char) fp->_IO_read_ptr[-1] == c)
931 --fp->_IO_read_ptr;
932 else
934 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
935 if (!_IO_in_backup (fp))
937 /* We need to keep the invariant that the main get area
938 logically follows the backup area. */
939 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
941 if (save_for_backup (fp, fp->_IO_read_ptr))
942 return EOF;
944 else if (!_IO_have_backup (fp))
946 /* No backup buffer: allocate one. */
947 /* Use nshort buffer, if unused? (probably not) FIXME */
948 int backup_size = 128;
949 char *bbuf = (char *) malloc (backup_size);
950 if (bbuf == NULL)
951 return EOF;
952 fp->_IO_save_base = bbuf;
953 fp->_IO_save_end = fp->_IO_save_base + backup_size;
954 fp->_IO_backup_base = fp->_IO_save_end;
956 fp->_IO_read_base = fp->_IO_read_ptr;
957 _IO_switch_to_backup_area (fp);
959 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
961 /* Increase size of existing backup buffer. */
962 _IO_size_t new_size;
963 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
964 char *new_buf;
965 new_size = 2 * old_size;
966 new_buf = (char *) malloc (new_size);
967 if (new_buf == NULL)
968 return EOF;
969 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
970 old_size);
971 free (fp->_IO_read_base);
972 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
973 new_buf + new_size);
974 fp->_IO_backup_base = fp->_IO_read_ptr;
977 *--fp->_IO_read_ptr = c;
979 return (unsigned char) c;
982 _IO_off64_t
983 _IO_default_seek (fp, offset, dir)
984 _IO_FILE *fp;
985 _IO_off64_t offset;
986 int dir;
988 return _IO_pos_BAD;
992 _IO_default_stat (fp, st)
993 _IO_FILE *fp;
994 void* st;
996 return EOF;
999 _IO_ssize_t
1000 _IO_default_read (fp, data, n)
1001 _IO_FILE* fp;
1002 void *data;
1003 _IO_ssize_t n;
1005 return -1;
1008 _IO_ssize_t
1009 _IO_default_write (fp, data, n)
1010 _IO_FILE *fp;
1011 const void *data;
1012 _IO_ssize_t n;
1014 return 0;
1018 _IO_default_showmanyc (fp)
1019 _IO_FILE *fp;
1021 return -1;
1024 void
1025 _IO_default_imbue (fp, locale)
1026 _IO_FILE *fp;
1027 void *locale;
1031 _IO_ITER
1032 _IO_iter_begin()
1034 return _IO_list_all;
1037 _IO_ITER
1038 _IO_iter_end()
1040 return NULL;
1043 _IO_ITER
1044 _IO_iter_next(iter)
1045 _IO_ITER iter;
1047 return iter->_chain;
1050 _IO_FILE *
1051 _IO_iter_file(iter)
1052 _IO_ITER iter;
1054 return iter;
1057 void
1058 _IO_list_lock()
1060 #ifdef _IO_MTSAFE_IO
1061 _IO_lock_lock (list_all_lock);
1062 #endif
1065 void
1066 _IO_list_unlock()
1068 #ifdef _IO_MTSAFE_IO
1069 _IO_lock_unlock (list_all_lock);
1070 #endif
1073 void
1074 _IO_list_resetlock()
1076 #ifdef _IO_MTSAFE_IO
1077 _IO_lock_init (list_all_lock);
1078 #endif
1082 #ifdef TODO
1083 #if defined(linux)
1084 #define IO_CLEANUP ;
1085 #endif
1087 #ifdef IO_CLEANUP
1088 IO_CLEANUP
1089 #else
1090 struct __io_defs {
1091 __io_defs() { }
1092 ~__io_defs() { _IO_cleanup (); }
1094 __io_defs io_defs__;
1095 #endif
1097 #endif /* TODO */
1099 #ifdef weak_alias
1100 weak_alias (_IO_cleanup, _cleanup)
1101 #endif
1103 #ifdef text_set_element
1104 text_set_element(__libc_atexit, _cleanup);
1105 #endif