]> git.ipfire.org Git - thirdparty/glibc.git/blob - libio/genops.c
Update.
[thirdparty/glibc.git] / libio / genops.c
1 /* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
2 This file is part of the GNU IO Library.
3
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.
8
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.
13
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.
18
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. */
25
26 /* Generic or default I/O operations. */
27
28 #include "libioP.h"
29 #ifdef __STDC__
30 #include <stdlib.h>
31 #endif
32 #include <string.h>
33
34 void
35 _IO_un_link (fp)
36 _IO_FILE *fp;
37 {
38 if (fp->_flags & _IO_LINKED)
39 {
40 _IO_FILE **f;
41 for (f = &_IO_list_all; *f != NULL; f = &(*f)->_chain)
42 {
43 if (*f == fp)
44 {
45 *f = fp->_chain;
46 break;
47 }
48 }
49 fp->_flags &= ~_IO_LINKED;
50 }
51 }
52
53 void
54 _IO_link_in (fp)
55 _IO_FILE *fp;
56 {
57 if ((fp->_flags & _IO_LINKED) == 0)
58 {
59 fp->_flags |= _IO_LINKED;
60 fp->_chain = _IO_list_all;
61 _IO_list_all = fp;
62 }
63 }
64
65 /* Return minimum _pos markers
66 Assumes the current get area is the main get area. */
67 static _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
68
69 static _IO_ssize_t
70 _IO_least_marker (fp, end_p)
71 _IO_FILE *fp;
72 char *end_p;
73 {
74 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
75 struct _IO_marker *mark;
76 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
77 if (mark->_pos < least_so_far)
78 least_so_far = mark->_pos;
79 return least_so_far;
80 }
81
82 /* Switch current get area from backup buffer to (start of) main get area. */
83
84 void
85 _IO_switch_to_main_get_area (fp)
86 _IO_FILE *fp;
87 {
88 char *tmp;
89 fp->_flags &= ~_IO_IN_BACKUP;
90 /* Swap _IO_read_end and _IO_save_end. */
91 tmp = fp->_IO_read_end;
92 fp->_IO_read_end = fp->_IO_save_end;
93 fp->_IO_save_end= tmp;
94 /* Swap _IO_read_base and _IO_save_base. */
95 tmp = fp->_IO_read_base;
96 fp->_IO_read_base = fp->_IO_save_base;
97 fp->_IO_save_base = tmp;
98 /* Set _IO_read_ptr. */
99 fp->_IO_read_ptr = fp->_IO_read_base;
100 }
101
102 /* Switch current get area from main get area to (end of) backup area. */
103
104 void
105 _IO_switch_to_backup_area (fp)
106 _IO_FILE *fp;
107 {
108 char *tmp;
109 fp->_flags |= _IO_IN_BACKUP;
110 /* Swap _IO_read_end and _IO_save_end. */
111 tmp = fp->_IO_read_end;
112 fp->_IO_read_end = fp->_IO_save_end;
113 fp->_IO_save_end = tmp;
114 /* Swap _IO_read_base and _IO_save_base. */
115 tmp = fp->_IO_read_base;
116 fp->_IO_read_base = fp->_IO_save_base;
117 fp->_IO_save_base = tmp;
118 /* Set _IO_read_ptr. */
119 fp->_IO_read_ptr = fp->_IO_read_end;
120 }
121
122 int
123 _IO_switch_to_get_mode (fp)
124 _IO_FILE *fp;
125 {
126 if (fp->_IO_write_ptr > fp->_IO_write_base)
127 if (_IO_OVERFLOW (fp, EOF) == EOF)
128 return EOF;
129 if (_IO_in_backup (fp))
130 fp->_IO_read_base = fp->_IO_backup_base;
131 else
132 {
133 fp->_IO_read_base = fp->_IO_buf_base;
134 if (fp->_IO_write_ptr > fp->_IO_read_end)
135 fp->_IO_read_end = fp->_IO_write_ptr;
136 }
137 fp->_IO_read_ptr = fp->_IO_write_ptr;
138
139 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
140
141 fp->_flags &= ~_IO_CURRENTLY_PUTTING;
142 return 0;
143 }
144
145 void
146 _IO_free_backup_area (fp)
147 _IO_FILE *fp;
148 {
149 if (_IO_in_backup (fp))
150 _IO_switch_to_main_get_area (fp); /* Just in case. */
151 free (fp->_IO_save_base);
152 fp->_IO_save_base = NULL;
153 fp->_IO_save_end = NULL;
154 fp->_IO_backup_base = NULL;
155 }
156
157 #if 0
158 int
159 _IO_switch_to_put_mode (fp)
160 _IO_FILE *fp;
161 {
162 fp->_IO_write_base = fp->_IO_read_ptr;
163 fp->_IO_write_ptr = fp->_IO_read_ptr;
164 /* Following is wrong if line- or un-buffered? */
165 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
166 ? fp->_IO_read_end : fp->_IO_buf_end);
167
168 fp->_IO_read_ptr = fp->_IO_read_end;
169 fp->_IO_read_base = fp->_IO_read_end;
170
171 fp->_flags |= _IO_CURRENTLY_PUTTING;
172 return 0;
173 }
174 #endif
175
176 int
177 __overflow (f, ch)
178 _IO_FILE *f;
179 int ch;
180 {
181 return _IO_OVERFLOW (f, ch);
182 }
183
184 static int save_for_backup __P ((_IO_FILE *fp, char *end_p))
185 #ifdef _LIBC
186 internal_function
187 #endif
188 ;
189
190 static int
191 #ifdef _LIBC
192 internal_function
193 #endif
194 save_for_backup (fp, end_p)
195 _IO_FILE *fp;
196 char *end_p;
197 {
198 /* Append [_IO_read_base..end_p] to backup area. */
199 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
200 /* needed_size is how much space we need in the backup area. */
201 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
202 /* FIXME: Dubious arithmetic if pointers are NULL */
203 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
204 _IO_size_t avail; /* Extra space available for future expansion. */
205 _IO_ssize_t delta;
206 struct _IO_marker *mark;
207 if (needed_size > current_Bsize)
208 {
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)
215 {
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 end_p - 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 end_p - fp->_IO_read_base);
229 #endif
230 }
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;
239 }
240 else
241 {
242 avail = current_Bsize - needed_size;
243 if (least_mark < 0)
244 {
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 end_p - fp->_IO_read_base);
251 }
252 else if (needed_size > 0)
253 memcpy (fp->_IO_save_base + avail,
254 fp->_IO_read_base + least_mark,
255 needed_size);
256 }
257 fp->_IO_backup_base = fp->_IO_save_base + avail;
258 /* Adjust all the streammarkers. */
259 delta = end_p - fp->_IO_read_base;
260 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
261 mark->_pos -= delta;
262 return 0;
263 }
264
265 int
266 __underflow (fp)
267 _IO_FILE *fp;
268 {
269 if (_IO_in_put_mode (fp))
270 if (_IO_switch_to_get_mode (fp) == EOF)
271 return EOF;
272 if (fp->_IO_read_ptr < fp->_IO_read_end)
273 return *(unsigned char *) fp->_IO_read_ptr;
274 if (_IO_in_backup (fp))
275 {
276 _IO_switch_to_main_get_area (fp);
277 if (fp->_IO_read_ptr < fp->_IO_read_end)
278 return *(unsigned char *) fp->_IO_read_ptr;
279 }
280 if (_IO_have_markers (fp))
281 {
282 if (save_for_backup (fp, fp->_IO_read_end))
283 return EOF;
284 }
285 else if (_IO_have_backup (fp))
286 _IO_free_backup_area (fp);
287 return _IO_UNDERFLOW (fp);
288 }
289
290 int
291 __uflow (fp)
292 _IO_FILE *fp;
293 {
294 if (_IO_in_put_mode (fp))
295 if (_IO_switch_to_get_mode (fp) == EOF)
296 return EOF;
297 if (fp->_IO_read_ptr < fp->_IO_read_end)
298 return *(unsigned char *) fp->_IO_read_ptr++;
299 if (_IO_in_backup (fp))
300 {
301 _IO_switch_to_main_get_area (fp);
302 if (fp->_IO_read_ptr < fp->_IO_read_end)
303 return *(unsigned char *) fp->_IO_read_ptr++;
304 }
305 if (_IO_have_markers (fp))
306 {
307 if (save_for_backup (fp, fp->_IO_read_end))
308 return EOF;
309 }
310 else if (_IO_have_backup (fp))
311 _IO_free_backup_area (fp);
312 return _IO_UFLOW (fp);
313 }
314
315 void
316 _IO_setb (f, b, eb, a)
317 _IO_FILE *f;
318 char *b;
319 char *eb;
320 int a;
321 {
322 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
323 FREE_BUF (f->_IO_buf_base, _IO_blen (f));
324 f->_IO_buf_base = b;
325 f->_IO_buf_end = eb;
326 if (a)
327 f->_flags &= ~_IO_USER_BUF;
328 else
329 f->_flags |= _IO_USER_BUF;
330 }
331
332 void
333 _IO_doallocbuf (fp)
334 _IO_FILE *fp;
335 {
336 if (fp->_IO_buf_base)
337 return;
338 if (!(fp->_flags & _IO_UNBUFFERED))
339 if (_IO_DOALLOCATE (fp) != EOF)
340 return;
341 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
342 }
343
344 int
345 _IO_default_underflow (fp)
346 _IO_FILE *fp;
347 {
348 return EOF;
349 }
350
351 int
352 _IO_default_uflow (fp)
353 _IO_FILE *fp;
354 {
355 int ch = _IO_UNDERFLOW (fp);
356 if (ch == EOF)
357 return EOF;
358 return *(unsigned char *) fp->_IO_read_ptr++;
359 }
360
361 _IO_size_t
362 _IO_default_xsputn (f, data, n)
363 _IO_FILE *f;
364 const void *data;
365 _IO_size_t n;
366 {
367 const char *s = (char *) data;
368 _IO_size_t more = n;
369 if (more <= 0)
370 return 0;
371 for (;;)
372 {
373 /* Space available. */
374 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr;
375 if (count > 0)
376 {
377 if ((_IO_size_t) count > more)
378 count = more;
379 if (count > 20)
380 {
381 #ifdef _LIBC
382 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
383 #else
384 memcpy (f->_IO_write_ptr, s, count);
385 f->_IO_write_ptr += count;
386 #endif
387 s += count;
388 }
389 else if (count <= 0)
390 count = 0;
391 else
392 {
393 char *p = f->_IO_write_ptr;
394 _IO_ssize_t i;
395 for (i = count; --i >= 0; )
396 *p++ = *s++;
397 f->_IO_write_ptr = p;
398 }
399 more -= count;
400 }
401 if (more == 0 || __overflow (f, (unsigned char) *s++) == EOF)
402 break;
403 more--;
404 }
405 return n - more;
406 }
407
408 _IO_size_t
409 _IO_sgetn (fp, data, n)
410 _IO_FILE *fp;
411 void *data;
412 _IO_size_t n;
413 {
414 /* FIXME handle putback buffer here! */
415 return _IO_XSGETN (fp, data, n);
416 }
417
418 _IO_size_t
419 _IO_default_xsgetn (fp, data, n)
420 _IO_FILE *fp;
421 void *data;
422 _IO_size_t n;
423 {
424 _IO_size_t more = n;
425 char *s = (char*) data;
426 for (;;)
427 {
428 /* Data available. */
429 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr;
430 if (count > 0)
431 {
432 if ((_IO_size_t) count > more)
433 count = more;
434 if (count > 20)
435 {
436 #ifdef _LIBC
437 s = __mempcpy (s, fp->_IO_read_ptr, count);
438 #else
439 memcpy (s, fp->_IO_read_ptr, count);
440 s += count;
441 #endif
442 fp->_IO_read_ptr += count;
443 }
444 else if (count <= 0)
445 count = 0;
446 else
447 {
448 char *p = fp->_IO_read_ptr;
449 int i = (int) count;
450 while (--i >= 0)
451 *s++ = *p++;
452 fp->_IO_read_ptr = p;
453 }
454 more -= count;
455 }
456 if (more == 0 || __underflow (fp) == EOF)
457 break;
458 }
459 return n - more;
460 }
461
462 #if 0
463 /* Seems not to be needed. --drepper */
464 int
465 _IO_sync (fp)
466 _IO_FILE *fp;
467 {
468 return 0;
469 }
470 #endif
471
472 _IO_FILE *
473 _IO_default_setbuf (fp, p, len)
474 _IO_FILE *fp;
475 char *p;
476 _IO_ssize_t len;
477 {
478 if (_IO_SYNC (fp) == EOF)
479 return NULL;
480 if (p == NULL || len == 0)
481 {
482 fp->_flags |= _IO_UNBUFFERED;
483 _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
484 }
485 else
486 {
487 fp->_flags &= ~_IO_UNBUFFERED;
488 _IO_setb (fp, p, p+len, 0);
489 }
490 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
491 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
492 return fp;
493 }
494
495 _IO_fpos64_t
496 _IO_default_seekpos (fp, pos, mode)
497 _IO_FILE *fp;
498 _IO_fpos64_t pos;
499 int mode;
500 {
501 return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
502 }
503
504 int
505 _IO_default_doallocate (fp)
506 _IO_FILE *fp;
507 {
508 char *buf;
509
510 ALLOC_BUF (buf, _IO_BUFSIZ, EOF);
511 _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1);
512 return 1;
513 }
514
515 void
516 _IO_init (fp, flags)
517 _IO_FILE *fp;
518 int flags;
519 {
520 fp->_flags = _IO_MAGIC|flags;
521 fp->_IO_buf_base = NULL;
522 fp->_IO_buf_end = NULL;
523 fp->_IO_read_base = NULL;
524 fp->_IO_read_ptr = NULL;
525 fp->_IO_read_end = NULL;
526 fp->_IO_write_base = NULL;
527 fp->_IO_write_ptr = NULL;
528 fp->_IO_write_end = NULL;
529 fp->_chain = NULL; /* Not necessary. */
530
531 fp->_IO_save_base = NULL;
532 fp->_IO_backup_base = NULL;
533 fp->_IO_save_end = NULL;
534 fp->_markers = NULL;
535 fp->_cur_column = 0;
536 #if _IO_JUMPS_OFFSET
537 fp->_vtable_offset = 0;
538 #endif
539 #ifdef _IO_MTSAFE_IO
540 _IO_lock_init (*fp->_lock);
541 #endif
542 }
543
544 int
545 _IO_default_sync (fp)
546 _IO_FILE *fp;
547 {
548 return 0;
549 }
550
551 /* The way the C++ classes are mapped into the C functions in the
552 current implementation, this function can get called twice! */
553
554 void
555 _IO_default_finish (fp, dummy)
556 _IO_FILE *fp;
557 int dummy;
558 {
559 struct _IO_marker *mark;
560 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
561 {
562 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp));
563 fp->_IO_buf_base = fp->_IO_buf_end = NULL;
564 }
565
566 for (mark = fp->_markers; mark != NULL; mark = mark->_next)
567 mark->_sbuf = NULL;
568
569 if (fp->_IO_save_base)
570 {
571 free (fp->_IO_save_base);
572 fp->_IO_save_base = NULL;
573 }
574
575 #ifdef _IO_MTSAFE_IO
576 _IO_lock_fini (*fp->_lock);
577 #endif
578
579 _IO_un_link (fp);
580 }
581
582 _IO_fpos64_t
583 _IO_default_seekoff (fp, offset, dir, mode)
584 _IO_FILE *fp;
585 _IO_off64_t offset;
586 int dir;
587 int mode;
588 {
589 return _IO_pos_BAD;
590 }
591
592 int
593 _IO_sputbackc (fp, c)
594 _IO_FILE *fp;
595 int c;
596 {
597 int result;
598
599 if (fp->_IO_read_ptr > fp->_IO_read_base
600 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
601 {
602 fp->_IO_read_ptr--;
603 result = (unsigned char) c;
604 }
605 else
606 result = _IO_PBACKFAIL (fp, c);
607
608 if (result != EOF)
609 fp->_flags &= ~_IO_EOF_SEEN;
610
611 return result;
612 }
613
614 int
615 _IO_sungetc (fp)
616 _IO_FILE *fp;
617 {
618 int result;
619
620 if (fp->_IO_read_ptr > fp->_IO_read_base)
621 {
622 fp->_IO_read_ptr--;
623 result = (unsigned char) *fp->_IO_read_ptr;
624 }
625 else
626 result = _IO_PBACKFAIL (fp, EOF);
627
628 if (result != EOF)
629 fp->_flags &= ~_IO_EOF_SEEN;
630
631 return result;
632 }
633
634 #if 0 /* Work in progress */
635 /* Seems not to be needed. */
636 #if 0
637 void
638 _IO_set_column (fp, c)
639 _IO_FILE *fp;
640 int c;
641 {
642 if (c == -1)
643 fp->_column = -1;
644 else
645 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base);
646 }
647 #else
648 int
649 _IO_set_column (fp, i)
650 _IO_FILE *fp;
651 int i;
652 {
653 fp->_cur_column = i + 1;
654 return 0;
655 }
656 #endif
657 #endif
658
659
660 unsigned
661 _IO_adjust_column (start, line, count)
662 unsigned start;
663 const char *line;
664 int count;
665 {
666 const char *ptr = line + count;
667 while (ptr > line)
668 if (*--ptr == '\n')
669 return line + count - ptr - 1;
670 return start + count;
671 }
672
673 #if 0
674 /* Seems not to be needed. --drepper */
675 int
676 _IO_get_column (fp)
677 _IO_FILE *fp;
678 {
679 if (fp->_cur_column)
680 return _IO_adjust_column (fp->_cur_column - 1,
681 fp->_IO_write_base,
682 fp->_IO_write_ptr - fp->_IO_write_base);
683 return -1;
684 }
685 #endif
686
687 int
688 _IO_flush_all ()
689 {
690 int result = 0;
691 _IO_FILE *fp;
692 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
693 if (fp->_IO_write_ptr > fp->_IO_write_base
694 && _IO_OVERFLOW (fp, EOF) == EOF)
695 result = EOF;
696 return result;
697 }
698
699 void
700 _IO_flush_all_linebuffered ()
701 {
702 _IO_FILE *fp;
703 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
704 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF)
705 _IO_OVERFLOW (fp, EOF);
706 }
707
708 static void _IO_unbuffer_all __P ((void));
709
710 static void
711 _IO_unbuffer_all ()
712 {
713 _IO_FILE *fp;
714 for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
715 if (! (fp->_flags & _IO_UNBUFFERED))
716 _IO_SETBUF (fp, NULL, 0);
717 }
718
719 int
720 _IO_cleanup ()
721 {
722 int result = _IO_flush_all ();
723
724 /* We currently don't have a reliable mechanism for making sure that
725 C++ static destructors are executed in the correct order.
726 So it is possible that other static destructors might want to
727 write to cout - and they're supposed to be able to do so.
728
729 The following will make the standard streambufs be unbuffered,
730 which forces any output from late destructors to be written out. */
731 _IO_unbuffer_all ();
732
733 return result;
734 }
735
736
737 void
738 _IO_init_marker (marker, fp)
739 struct _IO_marker *marker;
740 _IO_FILE *fp;
741 {
742 marker->_sbuf = fp;
743 if (_IO_in_put_mode (fp))
744 _IO_switch_to_get_mode (fp);
745 if (_IO_in_backup (fp))
746 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end;
747 else
748 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base;
749
750 /* Should perhaps sort the chain? */
751 marker->_next = fp->_markers;
752 fp->_markers = marker;
753 }
754
755 void
756 _IO_remove_marker (marker)
757 struct _IO_marker *marker;
758 {
759 /* Unlink from sb's chain. */
760 struct _IO_marker **ptr = &marker->_sbuf->_markers;
761 for (; ; ptr = &(*ptr)->_next)
762 {
763 if (*ptr == NULL)
764 break;
765 else if (*ptr == marker)
766 {
767 *ptr = marker->_next;
768 return;
769 }
770 }
771 #if 0
772 if _sbuf has a backup area that is no longer needed, should we delete
773 it now, or wait until the next underflow?
774 #endif
775 }
776
777 #define BAD_DELTA EOF
778
779 int
780 _IO_marker_difference (mark1, mark2)
781 struct _IO_marker *mark1;
782 struct _IO_marker *mark2;
783 {
784 return mark1->_pos - mark2->_pos;
785 }
786
787 /* Return difference between MARK and current position of MARK's stream. */
788 int
789 _IO_marker_delta (mark)
790 struct _IO_marker *mark;
791 {
792 int cur_pos;
793 if (mark->_sbuf == NULL)
794 return BAD_DELTA;
795 if (_IO_in_backup (mark->_sbuf))
796 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end;
797 else
798 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base;
799 return mark->_pos - cur_pos;
800 }
801
802 int
803 _IO_seekmark (fp, mark, delta)
804 _IO_FILE *fp;
805 struct _IO_marker *mark;
806 int delta;
807 {
808 if (mark->_sbuf != fp)
809 return EOF;
810 if (mark->_pos >= 0)
811 {
812 if (_IO_in_backup (fp))
813 _IO_switch_to_main_get_area (fp);
814 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos;
815 }
816 else
817 {
818 if (!_IO_in_backup (fp))
819 _IO_switch_to_backup_area (fp);
820 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos;
821 }
822 return 0;
823 }
824
825 void
826 _IO_unsave_markers (fp)
827 _IO_FILE *fp;
828 {
829 struct _IO_marker *mark = fp->_markers;
830 if (mark)
831 {
832 #ifdef TODO
833 streampos offset = seekoff (0, ios::cur, ios::in);
834 if (offset != EOF)
835 {
836 offset += eGptr () - Gbase ();
837 for ( ; mark != NULL; mark = mark->_next)
838 mark->set_streampos (mark->_pos + offset);
839 }
840 else
841 {
842 for ( ; mark != NULL; mark = mark->_next)
843 mark->set_streampos (EOF);
844 }
845 #endif
846 fp->_markers = 0;
847 }
848
849 if (_IO_have_backup (fp))
850 _IO_free_backup_area (fp);
851 }
852
853 #if 0
854 /* Seems not to be needed. --drepper */
855 int
856 _IO_nobackup_pbackfail (fp, c)
857 _IO_FILE *fp;
858 int c;
859 {
860 if (fp->_IO_read_ptr > fp->_IO_read_base)
861 fp->_IO_read_ptr--;
862 if (c != EOF && *fp->_IO_read_ptr != c)
863 *fp->_IO_read_ptr = c;
864 return (unsigned char) c;
865 }
866 #endif
867
868 int
869 _IO_default_pbackfail (fp, c)
870 _IO_FILE *fp;
871 int c;
872 {
873 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp)
874 && (unsigned char) fp->_IO_read_ptr[-1] == c)
875 --fp->_IO_read_ptr;
876 else
877 {
878 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
879 if (!_IO_in_backup (fp))
880 {
881 /* We need to keep the invariant that the main get area
882 logically follows the backup area. */
883 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp))
884 {
885 if (save_for_backup (fp, fp->_IO_read_ptr))
886 return EOF;
887 }
888 else if (!_IO_have_backup (fp))
889 {
890 /* No backup buffer: allocate one. */
891 /* Use nshort buffer, if unused? (probably not) FIXME */
892 int backup_size = 128;
893 char *bbuf = (char *) malloc (backup_size);
894 if (bbuf == NULL)
895 return EOF;
896 fp->_IO_save_base = bbuf;
897 fp->_IO_save_end = fp->_IO_save_base + backup_size;
898 fp->_IO_backup_base = fp->_IO_save_end;
899 }
900 fp->_IO_read_base = fp->_IO_read_ptr;
901 _IO_switch_to_backup_area (fp);
902 }
903 else if (fp->_IO_read_ptr <= fp->_IO_read_base)
904 {
905 /* Increase size of existing backup buffer. */
906 _IO_size_t new_size;
907 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base;
908 char *new_buf;
909 new_size = 2 * old_size;
910 new_buf = (char *) malloc (new_size);
911 if (new_buf == NULL)
912 return EOF;
913 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base,
914 old_size);
915 free (fp->_IO_read_base);
916 _IO_setg (fp, new_buf, new_buf + (new_size - old_size),
917 new_buf + new_size);
918 fp->_IO_backup_base = fp->_IO_read_ptr;
919 }
920
921 *--fp->_IO_read_ptr = c;
922 }
923 return (unsigned char) c;
924 }
925
926 _IO_fpos64_t
927 _IO_default_seek (fp, offset, dir)
928 _IO_FILE *fp;
929 _IO_off64_t offset;
930 int dir;
931 {
932 return _IO_pos_BAD;
933 }
934
935 int
936 _IO_default_stat (fp, st)
937 _IO_FILE *fp;
938 void* st;
939 {
940 return EOF;
941 }
942
943 _IO_ssize_t
944 _IO_default_read (fp, data, n)
945 _IO_FILE* fp;
946 void *data;
947 _IO_ssize_t n;
948 {
949 return -1;
950 }
951
952 _IO_ssize_t
953 _IO_default_write (fp, data, n)
954 _IO_FILE *fp;
955 const void *data;
956 _IO_ssize_t n;
957 {
958 return 0;
959 }
960
961 int
962 _IO_default_showmanyc (fp)
963 _IO_FILE *fp;
964 {
965 return -1;
966 }
967
968 void
969 _IO_default_imbue (fp, locale)
970 _IO_FILE *fp;
971 void *locale;
972 {
973 }
974
975
976 #ifdef TODO
977 #if defined(linux)
978 #define IO_CLEANUP ;
979 #endif
980
981 #ifdef IO_CLEANUP
982 IO_CLEANUP
983 #else
984 struct __io_defs {
985 __io_defs() { }
986 ~__io_defs() { _IO_cleanup (); }
987 };
988 __io_defs io_defs__;
989 #endif
990
991 #endif /* TODO */
992
993 #ifdef weak_alias
994 weak_alias (_IO_cleanup, _cleanup)
995 #endif
996
997 #ifdef text_set_element
998 text_set_element(__libc_atexit, _cleanup);
999 #endif