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