1 /* Copyright (C) 1993,1995,1997-2002, 2003 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, write to the Free 16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 17 02111-1307 USA. 18 19 As a special exception, if you link the code in this file with 20 files compiled with a GNU compiler to produce an executable, 21 that does not cause the resulting executable to be covered by 22 the GNU Lesser General Public License. This exception does not 23 however invalidate any other reasons why the executable file 24 might be covered by the GNU Lesser General Public License. 25 This exception applies to code released by its copyright holders 26 in files containing the exception. 27 */ 28 29 /* Generic or default I/O operations. */ 30 31 #include "libioP.h" 32 #include <stdlib.h> 33 #include <string.h> 34 35 36 #ifdef _IO_MTSAFE_IO 37 static _IO_lock_t list_all_lock = _IO_lock_initializer; 38 #endif 39 40 /* Used to signal modifications to the list of FILE decriptors. */ 41 static int _IO_list_all_stamp; 42 43 44 static _IO_FILE *run_fp; 45 46 #if 0 47 static void 48 flush_cleanup (void *not_used) 49 { 50 if (run_fp != NULL) 51 _IO_funlockfile (run_fp); 52 #ifdef _IO_MTSAFE_IO 53 _IO_lock_unlock (list_all_lock); 54 #endif 55 } 56 #endif 57 58 59 void 60 _IO_un_link(struct _IO_FILE_plus *fp) 61 { 62 if (fp->file._flags & _IO_LINKED) 63 { 64 struct _IO_FILE_plus **f; 65 #ifdef _IO_MTSAFE_IO 66 _IO_cleanup_region_start_noarg (flush_cleanup); 67 _IO_lock_lock (list_all_lock); 68 run_fp = (_IO_FILE *) fp; 69 _IO_flockfile ((_IO_FILE *) fp); 70 #endif 71 for (f = &INTUSE(_IO_list_all); *f; 72 f = (struct _IO_FILE_plus **) &(*f)->file._chain) 73 { 74 if (*f == fp) 75 { 76 *f = (struct _IO_FILE_plus *) fp->file._chain; 77 ++_IO_list_all_stamp; 78 break; 79 } 80 } 81 fp->file._flags &= ~_IO_LINKED; 82 #ifdef _IO_MTSAFE_IO 83 _IO_funlockfile ((_IO_FILE *) fp); 84 run_fp = NULL; 85 _IO_lock_unlock (list_all_lock); 86 _IO_cleanup_region_end (0); 87 #endif 88 } 89 } 90 INTDEF(_IO_un_link) 91 92 void 93 _IO_link_in (fp) 94 struct _IO_FILE_plus *fp; 95 { 96 if ((fp->file._flags & _IO_LINKED) == 0) 97 { 98 fp->file._flags |= _IO_LINKED; 99 #ifdef _IO_MTSAFE_IO 100 _IO_cleanup_region_start_noarg (flush_cleanup); 101 _IO_lock_lock (list_all_lock); 102 run_fp = (_IO_FILE *) fp; 103 _IO_flockfile ((_IO_FILE *) fp); 104 #endif 105 fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all); 106 INTUSE(_IO_list_all) = fp; 107 ++_IO_list_all_stamp; 108 #ifdef _IO_MTSAFE_IO 109 _IO_funlockfile ((_IO_FILE *) fp); 110 run_fp = NULL; 111 _IO_lock_unlock (list_all_lock); 112 _IO_cleanup_region_end (0); 113 #endif 114 } 115 } 116 INTDEF(_IO_link_in) 117 118 /* Return minimum _pos markers 119 Assumes the current get area is the main get area. */ 120 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p)); 121 122 _IO_ssize_t 123 _IO_least_marker (fp, end_p) 124 _IO_FILE *fp; 125 char *end_p; 126 { 127 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base; 128 struct _IO_marker *mark; 129 for (mark = fp->_markers; mark != NULL; mark = mark->_next) 130 if (mark->_pos < least_so_far) 131 least_so_far = mark->_pos; 132 return least_so_far; 133 } 134 135 /* Switch current get area from backup buffer to (start of) main get area. */ 136 137 void 138 _IO_switch_to_main_get_area (fp) 139 _IO_FILE *fp; 140 { 141 char *tmp; 142 fp->_flags &= ~_IO_IN_BACKUP; 143 /* Swap _IO_read_end and _IO_save_end. */ 144 tmp = fp->_IO_read_end; 145 fp->_IO_read_end = fp->_IO_save_end; 146 fp->_IO_save_end= tmp; 147 /* Swap _IO_read_base and _IO_save_base. */ 148 tmp = fp->_IO_read_base; 149 fp->_IO_read_base = fp->_IO_save_base; 150 fp->_IO_save_base = tmp; 151 /* Set _IO_read_ptr. */ 152 fp->_IO_read_ptr = fp->_IO_read_base; 153 } 154 155 /* Switch current get area from main get area to (end of) backup area. */ 156 157 void 158 _IO_switch_to_backup_area (fp) 159 _IO_FILE *fp; 160 { 161 char *tmp; 162 fp->_flags |= _IO_IN_BACKUP; 163 /* Swap _IO_read_end and _IO_save_end. */ 164 tmp = fp->_IO_read_end; 165 fp->_IO_read_end = fp->_IO_save_end; 166 fp->_IO_save_end = tmp; 167 /* Swap _IO_read_base and _IO_save_base. */ 168 tmp = fp->_IO_read_base; 169 fp->_IO_read_base = fp->_IO_save_base; 170 fp->_IO_save_base = tmp; 171 /* Set _IO_read_ptr. */ 172 fp->_IO_read_ptr = fp->_IO_read_end; 173 } 174 175 int 176 _IO_switch_to_get_mode (fp) 177 _IO_FILE *fp; 178 { 179 if (fp->_IO_write_ptr > fp->_IO_write_base) 180 if (_IO_OVERFLOW (fp, EOF) == EOF) 181 return EOF; 182 if (_IO_in_backup (fp)) 183 fp->_IO_read_base = fp->_IO_backup_base; 184 else 185 { 186 fp->_IO_read_base = fp->_IO_buf_base; 187 if (fp->_IO_write_ptr > fp->_IO_read_end) 188 fp->_IO_read_end = fp->_IO_write_ptr; 189 } 190 fp->_IO_read_ptr = fp->_IO_write_ptr; 191 192 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr; 193 194 fp->_flags &= ~_IO_CURRENTLY_PUTTING; 195 return 0; 196 } 197 INTDEF(_IO_switch_to_get_mode) 198 199 void 200 _IO_free_backup_area (fp) 201 _IO_FILE *fp; 202 { 203 if (_IO_in_backup (fp)) 204 _IO_switch_to_main_get_area (fp); /* Just in case. */ 205 free (fp->_IO_save_base); 206 fp->_IO_save_base = NULL; 207 fp->_IO_save_end = NULL; 208 fp->_IO_backup_base = NULL; 209 } 210 INTDEF(_IO_free_backup_area) 211 212 #if 0 213 int 214 _IO_switch_to_put_mode (fp) 215 _IO_FILE *fp; 216 { 217 fp->_IO_write_base = fp->_IO_read_ptr; 218 fp->_IO_write_ptr = fp->_IO_read_ptr; 219 /* Following is wrong if line- or un-buffered? */ 220 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP 221 ? fp->_IO_read_end : fp->_IO_buf_end); 222 223 fp->_IO_read_ptr = fp->_IO_read_end; 224 fp->_IO_read_base = fp->_IO_read_end; 225 226 fp->_flags |= _IO_CURRENTLY_PUTTING; 227 return 0; 228 } 229 #endif 230 231 232 int 233 __overflow(_IO_FILE *file, int character) 234 { 235 /* This is a single-byte stream. */ 236 if (file->_mode == 0) 237 _IO_fwide(file, -1); 238 239 return _IO_OVERFLOW(file, character); 240 } 241 libc_hidden_def(__overflow) 242 243 244 static int save_for_backup __P ((_IO_FILE *fp, char *end_p)) 245 #ifdef _LIBC 246 internal_function 247 #endif 248 ; 249 250 static int 251 #ifdef _LIBC 252 internal_function 253 #endif 254 save_for_backup (fp, end_p) 255 _IO_FILE *fp; 256 char *end_p; 257 { 258 /* Append [_IO_read_base..end_p] to backup area. */ 259 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p); 260 /* needed_size is how much space we need in the backup area. */ 261 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; 262 /* FIXME: Dubious arithmetic if pointers are NULL */ 263 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; 264 _IO_size_t avail; /* Extra space available for future expansion. */ 265 _IO_ssize_t delta; 266 struct _IO_marker *mark; 267 if (needed_size > current_Bsize) 268 { 269 char *new_buffer; 270 avail = 100; 271 new_buffer = (char *) malloc (avail + needed_size); 272 if (new_buffer == NULL) 273 return EOF; /* FIXME */ 274 if (least_mark < 0) 275 { 276 #ifdef _LIBC 277 __mempcpy (__mempcpy (new_buffer + avail, 278 fp->_IO_save_end + least_mark, 279 -least_mark), 280 fp->_IO_read_base, 281 end_p - fp->_IO_read_base); 282 #else 283 memcpy (new_buffer + avail, 284 fp->_IO_save_end + least_mark, 285 -least_mark); 286 memcpy (new_buffer + avail - least_mark, 287 fp->_IO_read_base, 288 end_p - fp->_IO_read_base); 289 #endif 290 } 291 else 292 memcpy (new_buffer + avail, 293 fp->_IO_read_base + least_mark, 294 needed_size); 295 if (fp->_IO_save_base) 296 free (fp->_IO_save_base); 297 fp->_IO_save_base = new_buffer; 298 fp->_IO_save_end = new_buffer + avail + needed_size; 299 } 300 else 301 { 302 avail = current_Bsize - needed_size; 303 if (least_mark < 0) 304 { 305 memmove (fp->_IO_save_base + avail, 306 fp->_IO_save_end + least_mark, 307 -least_mark); 308 memcpy (fp->_IO_save_base + avail - least_mark, 309 fp->_IO_read_base, 310 end_p - fp->_IO_read_base); 311 } 312 else if (needed_size > 0) 313 memcpy (fp->_IO_save_base + avail, 314 fp->_IO_read_base + least_mark, 315 needed_size); 316 } 317 fp->_IO_backup_base = fp->_IO_save_base + avail; 318 /* Adjust all the streammarkers. */ 319 delta = end_p - fp->_IO_read_base; 320 for (mark = fp->_markers; mark != NULL; mark = mark->_next) 321 mark->_pos -= delta; 322 return 0; 323 } 324 325 326 int 327 __underflow(_IO_FILE *file) 328 { 329 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 330 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1) 331 return EOF; 332 #endif 333 334 if (file->_mode == 0) 335 _IO_fwide(file, -1); 336 337 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF) 338 return EOF; 339 340 if (file->_IO_read_ptr < file->_IO_read_end) 341 return *(unsigned char *)file->_IO_read_ptr; 342 343 if (_IO_in_backup(file)) { 344 _IO_switch_to_main_get_area(file); 345 346 if (file->_IO_read_ptr < file->_IO_read_end) 347 return *(unsigned char *)file->_IO_read_ptr; 348 } 349 if (_IO_have_markers(file)) { 350 if (save_for_backup(file, file->_IO_read_end)) 351 return EOF; 352 } else if (_IO_have_backup(file)) 353 INTUSE(_IO_free_backup_area)(file); 354 355 return _IO_UNDERFLOW(file); 356 } 357 libc_hidden_def(__underflow) 358 359 360 int 361 __uflow(_IO_FILE *file) 362 { 363 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 364 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1) 365 return EOF; 366 #endif 367 368 if (file->_mode == 0) 369 _IO_fwide(file, -11); 370 371 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF) 372 return EOF; 373 374 if (file->_IO_read_ptr < file->_IO_read_end) 375 return *(unsigned char *)file->_IO_read_ptr++; 376 377 if (_IO_in_backup(file)) { 378 _IO_switch_to_main_get_area(file); 379 380 if (file->_IO_read_ptr < file->_IO_read_end) 381 return *(unsigned char *)file->_IO_read_ptr++; 382 } 383 384 if (_IO_have_markers(file)) { 385 if (save_for_backup(file, file->_IO_read_end)) 386 return EOF; 387 } else if (_IO_have_backup(file)) 388 INTUSE(_IO_free_backup_area)(file); 389 390 return _IO_UFLOW(file); 391 } 392 libc_hidden_def(__uflow) 393 394 395 void 396 _IO_setb (f, b, eb, a) 397 _IO_FILE *f; 398 char *b; 399 char *eb; 400 int a; 401 { 402 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) 403 FREE_BUF (f->_IO_buf_base, _IO_blen (f)); 404 f->_IO_buf_base = b; 405 f->_IO_buf_end = eb; 406 if (a) 407 f->_flags &= ~_IO_USER_BUF; 408 else 409 f->_flags |= _IO_USER_BUF; 410 } 411 INTDEF(_IO_setb) 412 413 void 414 _IO_doallocbuf (fp) 415 _IO_FILE *fp; 416 { 417 if (fp->_IO_buf_base) 418 return; 419 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) 420 if (_IO_DOALLOCATE (fp) != EOF) 421 return; 422 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); 423 } 424 INTDEF(_IO_doallocbuf) 425 426 int 427 _IO_default_underflow (fp) 428 _IO_FILE *fp; 429 { 430 return EOF; 431 } 432 433 int 434 _IO_default_uflow (fp) 435 _IO_FILE *fp; 436 { 437 int ch = _IO_UNDERFLOW (fp); 438 if (ch == EOF) 439 return EOF; 440 return *(unsigned char *) fp->_IO_read_ptr++; 441 } 442 INTDEF(_IO_default_uflow) 443 444 _IO_size_t 445 _IO_default_xsputn (f, data, n) 446 _IO_FILE *f; 447 const void *data; 448 _IO_size_t n; 449 { 450 const char *s = (char *) data; 451 _IO_size_t more = n; 452 if (more <= 0) 453 return 0; 454 for (;;) 455 { 456 /* Space available. */ 457 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; 458 if (count > 0) 459 { 460 if ((_IO_size_t) count > more) 461 count = more; 462 if (count > 20) 463 { 464 #ifdef _LIBC 465 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); 466 #else 467 memcpy (f->_IO_write_ptr, s, count); 468 f->_IO_write_ptr += count; 469 #endif 470 s += count; 471 } 472 else if (count <= 0) 473 count = 0; 474 else 475 { 476 char *p = f->_IO_write_ptr; 477 _IO_ssize_t i; 478 for (i = count; --i >= 0; ) 479 *p++ = *s++; 480 f->_IO_write_ptr = p; 481 } 482 more -= count; 483 } 484 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF) 485 break; 486 more--; 487 } 488 return n - more; 489 } 490 INTDEF(_IO_default_xsputn) 491 492 _IO_size_t 493 _IO_sgetn (fp, data, n) 494 _IO_FILE *fp; 495 void *data; 496 _IO_size_t n; 497 { 498 /* FIXME handle putback buffer here! */ 499 return _IO_XSGETN (fp, data, n); 500 } 501 INTDEF(_IO_sgetn) 502 503 _IO_size_t 504 _IO_default_xsgetn (fp, data, n) 505 _IO_FILE *fp; 506 void *data; 507 _IO_size_t n; 508 { 509 _IO_size_t more = n; 510 char *s = (char*) data; 511 for (;;) 512 { 513 /* Data available. */ 514 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; 515 if (count > 0) 516 { 517 if ((_IO_size_t) count > more) 518 count = more; 519 if (count > 20) 520 { 521 #ifdef _LIBC 522 s = __mempcpy (s, fp->_IO_read_ptr, count); 523 #else 524 memcpy (s, fp->_IO_read_ptr, count); 525 s += count; 526 #endif 527 fp->_IO_read_ptr += count; 528 } 529 else if (count <= 0) 530 count = 0; 531 else 532 { 533 char *p = fp->_IO_read_ptr; 534 int i = (int) count; 535 while (--i >= 0) 536 *s++ = *p++; 537 fp->_IO_read_ptr = p; 538 } 539 more -= count; 540 } 541 if (more == 0 || __underflow (fp) == EOF) 542 break; 543 } 544 return n - more; 545 } 546 INTDEF(_IO_default_xsgetn) 547 548 #if 0 549 /* Seems not to be needed. --drepper */ 550 int 551 _IO_sync (fp) 552 _IO_FILE *fp; 553 { 554 return 0; 555 } 556 #endif 557 558 _IO_FILE * 559 _IO_default_setbuf (fp, p, len) 560 _IO_FILE *fp; 561 char *p; 562 _IO_ssize_t len; 563 { 564 if (_IO_SYNC (fp) == EOF) 565 return NULL; 566 if (p == NULL || len == 0) 567 { 568 fp->_flags |= _IO_UNBUFFERED; 569 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); 570 } 571 else 572 { 573 fp->_flags &= ~_IO_UNBUFFERED; 574 INTUSE(_IO_setb) (fp, p, p+len, 0); 575 } 576 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0; 577 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0; 578 return fp; 579 } 580 581 _IO_off64_t 582 _IO_default_seekpos (fp, pos, mode) 583 _IO_FILE *fp; 584 _IO_off64_t pos; 585 int mode; 586 { 587 return _IO_SEEKOFF (fp, pos, 0, mode); 588 } 589 590 int 591 _IO_default_doallocate (fp) 592 _IO_FILE *fp; 593 { 594 char *buf; 595 596 ALLOC_BUF (buf, _IO_BUFSIZ, EOF); 597 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1); 598 return 1; 599 } 600 INTDEF(_IO_default_doallocate) 601 602 void 603 _IO_init (fp, flags) 604 _IO_FILE *fp; 605 int flags; 606 { 607 _IO_no_init (fp, flags, -1, NULL, NULL); 608 } 609 INTDEF(_IO_init) 610 611 void 612 _IO_no_init (fp, flags, orientation, wd, jmp) 613 _IO_FILE *fp; 614 int flags; 615 int orientation; 616 struct _IO_wide_data *wd; 617 struct _IO_jump_t *jmp; 618 { 619 fp->_flags = _IO_MAGIC|flags; 620 fp->_flags2 = 0; 621 fp->_IO_buf_base = NULL; 622 fp->_IO_buf_end = NULL; 623 fp->_IO_read_base = NULL; 624 fp->_IO_read_ptr = NULL; 625 fp->_IO_read_end = NULL; 626 fp->_IO_write_base = NULL; 627 fp->_IO_write_ptr = NULL; 628 fp->_IO_write_end = NULL; 629 fp->_chain = NULL; /* Not necessary. */ 630 631 fp->_IO_save_base = NULL; 632 fp->_IO_backup_base = NULL; 633 fp->_IO_save_end = NULL; 634 fp->_markers = NULL; 635 fp->_cur_column = 0; 636 #if _IO_JUMPS_OFFSET 637 fp->_vtable_offset = 0; 638 #endif 639 #ifdef _IO_MTSAFE_IO 640 if (fp->_lock != NULL) 641 _IO_lock_init (*fp->_lock); 642 #endif 643 fp->_mode = orientation; 644 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 645 if (orientation >= 0) 646 { 647 fp->_wide_data = wd; 648 fp->_wide_data->_IO_buf_base = NULL; 649 fp->_wide_data->_IO_buf_end = NULL; 650 fp->_wide_data->_IO_read_base = NULL; 651 fp->_wide_data->_IO_read_ptr = NULL; 652 fp->_wide_data->_IO_read_end = NULL; 653 fp->_wide_data->_IO_write_base = NULL; 654 fp->_wide_data->_IO_write_ptr = NULL; 655 fp->_wide_data->_IO_write_end = NULL; 656 fp->_wide_data->_IO_save_base = NULL; 657 fp->_wide_data->_IO_backup_base = NULL; 658 fp->_wide_data->_IO_save_end = NULL; 659 660 fp->_wide_data->_wide_vtable = jmp; 661 } 662 #endif 663 } 664 665 int 666 _IO_default_sync (fp) 667 _IO_FILE *fp; 668 { 669 return 0; 670 } 671 672 /* The way the C++ classes are mapped into the C functions in the 673 current implementation, this function can get called twice! */ 674 675 void 676 _IO_default_finish (fp, dummy) 677 _IO_FILE *fp; 678 int dummy; 679 { 680 struct _IO_marker *mark; 681 if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) 682 { 683 FREE_BUF (fp->_IO_buf_base, _IO_blen (fp)); 684 fp->_IO_buf_base = fp->_IO_buf_end = NULL; 685 } 686 687 for (mark = fp->_markers; mark != NULL; mark = mark->_next) 688 mark->_sbuf = NULL; 689 690 if (fp->_IO_save_base) 691 { 692 free (fp->_IO_save_base); 693 fp->_IO_save_base = NULL; 694 } 695 696 #ifdef _IO_MTSAFE_IO 697 if (fp->_lock != NULL) 698 _IO_lock_fini (*fp->_lock); 699 #endif 700 701 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); 702 } 703 INTDEF(_IO_default_finish) 704 705 _IO_off64_t 706 _IO_default_seekoff (fp, offset, dir, mode) 707 _IO_FILE *fp; 708 _IO_off64_t offset; 709 int dir; 710 int mode; 711 { 712 return _IO_pos_BAD; 713 } 714 715 int 716 _IO_sputbackc (fp, c) 717 _IO_FILE *fp; 718 int c; 719 { 720 int result; 721 722 if (fp->_IO_read_ptr > fp->_IO_read_base 723 && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c) 724 { 725 fp->_IO_read_ptr--; 726 result = (unsigned char) c; 727 } 728 else 729 result = _IO_PBACKFAIL (fp, c); 730 731 if (result != EOF) 732 fp->_flags &= ~_IO_EOF_SEEN; 733 734 return result; 735 } 736 INTDEF(_IO_sputbackc) 737 738 int 739 _IO_sungetc (fp) 740 _IO_FILE *fp; 741 { 742 int result; 743 744 if (fp->_IO_read_ptr > fp->_IO_read_base) 745 { 746 fp->_IO_read_ptr--; 747 result = (unsigned char) *fp->_IO_read_ptr; 748 } 749 else 750 result = _IO_PBACKFAIL (fp, EOF); 751 752 if (result != EOF) 753 fp->_flags &= ~_IO_EOF_SEEN; 754 755 return result; 756 } 757 758 #if 0 /* Work in progress */ 759 /* Seems not to be needed. */ 760 #if 0 761 void 762 _IO_set_column (fp, c) 763 _IO_FILE *fp; 764 int c; 765 { 766 if (c == -1) 767 fp->_column = -1; 768 else 769 fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base); 770 } 771 #else 772 int 773 _IO_set_column (fp, i) 774 _IO_FILE *fp; 775 int i; 776 { 777 fp->_cur_column = i + 1; 778 return 0; 779 } 780 #endif 781 #endif 782 783 784 unsigned 785 _IO_adjust_column (start, line, count) 786 unsigned start; 787 const char *line; 788 int count; 789 { 790 const char *ptr = line + count; 791 while (ptr > line) 792 if (*--ptr == '\n') 793 return line + count - ptr - 1; 794 return start + count; 795 } 796 INTDEF(_IO_adjust_column) 797 798 #if 0 799 /* Seems not to be needed. --drepper */ 800 int 801 _IO_get_column (fp) 802 _IO_FILE *fp; 803 { 804 if (fp->_cur_column) 805 return _IO_adjust_column (fp->_cur_column - 1, 806 fp->_IO_write_base, 807 fp->_IO_write_ptr - fp->_IO_write_base); 808 return -1; 809 } 810 #endif 811 812 813 int 814 _IO_flush_all_lockp (int do_lock) 815 { 816 int result = 0; 817 struct _IO_FILE *fp; 818 int last_stamp; 819 820 #ifdef _IO_MTSAFE_IO 821 _IO_cleanup_region_start_noarg (flush_cleanup); 822 if (do_lock) 823 _IO_lock_lock (list_all_lock); 824 #endif 825 826 last_stamp = _IO_list_all_stamp; 827 fp = (_IO_FILE *) INTUSE(_IO_list_all); 828 while (fp != NULL) 829 { 830 run_fp = fp; 831 if (do_lock) 832 _IO_flockfile (fp); 833 834 if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base) 835 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 836 || (fp->_vtable_offset == 0 837 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr 838 > fp->_wide_data->_IO_write_base)) 839 #endif 840 ) 841 && _IO_OVERFLOW (fp, EOF) == EOF) 842 result = EOF; 843 844 if (do_lock) 845 _IO_funlockfile (fp); 846 run_fp = NULL; 847 848 if (last_stamp != _IO_list_all_stamp) 849 { 850 /* Something was added to the list. Start all over again. */ 851 fp = (_IO_FILE *) INTUSE(_IO_list_all); 852 last_stamp = _IO_list_all_stamp; 853 } 854 else 855 fp = fp->_chain; 856 } 857 858 #ifdef _IO_MTSAFE_IO 859 if (do_lock) 860 _IO_lock_unlock (list_all_lock); 861 _IO_cleanup_region_end (0); 862 #endif 863 864 return result; 865 } 866 867 868 int 869 _IO_flush_all () 870 { 871 /* We want locking. */ 872 return _IO_flush_all_lockp (1); 873 } 874 INTDEF(_IO_flush_all) 875 876 void 877 _IO_flush_all_linebuffered () 878 { 879 struct _IO_FILE *fp; 880 int last_stamp; 881 882 #ifdef _IO_MTSAFE_IO 883 _IO_cleanup_region_start_noarg (flush_cleanup); 884 _IO_lock_lock (list_all_lock); 885 #endif 886 887 last_stamp = _IO_list_all_stamp; 888 fp = (_IO_FILE *) INTUSE(_IO_list_all); 889 while (fp != NULL) 890 { 891 run_fp = fp; 892 _IO_flockfile (fp); 893 894 if ((fp->_flags & _IO_NO_WRITES) == 0 && fp->_flags & _IO_LINE_BUF) 895 _IO_OVERFLOW (fp, EOF); 896 897 _IO_funlockfile (fp); 898 run_fp = NULL; 899 900 if (last_stamp != _IO_list_all_stamp) 901 { 902 /* Something was added to the list. Start all over again. */ 903 fp = (_IO_FILE *) INTUSE(_IO_list_all); 904 last_stamp = _IO_list_all_stamp; 905 } 906 else 907 fp = fp->_chain; 908 } 909 910 #ifdef _IO_MTSAFE_IO 911 _IO_lock_unlock (list_all_lock); 912 _IO_cleanup_region_end (0); 913 #endif 914 } 915 INTDEF(_IO_flush_all_linebuffered) 916 #ifdef _LIBC 917 weak_alias (_IO_flush_all_linebuffered, _flushlbf) 918 #endif 919 920 static void _IO_unbuffer_write __P ((void)); 921 922 static void 923 _IO_unbuffer_write () 924 { 925 struct _IO_FILE *fp; 926 for (fp = (_IO_FILE *) INTUSE(_IO_list_all); fp; fp = fp->_chain) 927 { 928 if (! (fp->_flags & _IO_UNBUFFERED) 929 && (! (fp->_flags & _IO_NO_WRITES) 930 || (fp->_flags & _IO_IS_APPENDING)) 931 /* Iff stream is un-orientated, it wasn't used. */ 932 && fp->_mode != 0) 933 _IO_SETBUF (fp, NULL, 0); 934 935 /* Make sure that never again the wide char functions can be 936 used. */ 937 fp->_mode = -1; 938 } 939 } 940 941 int 942 _IO_cleanup () 943 { 944 int result = INTUSE(_IO_flush_all) (); 945 946 /* We currently don't have a reliable mechanism for making sure that 947 C++ static destructors are executed in the correct order. 948 So it is possible that other static destructors might want to 949 write to cout - and they're supposed to be able to do so. 950 951 The following will make the standard streambufs be unbuffered, 952 which forces any output from late destructors to be written out. */ 953 _IO_unbuffer_write (); 954 955 return result; 956 } 957 958 959 void 960 _IO_init_marker (marker, fp) 961 struct _IO_marker *marker; 962 _IO_FILE *fp; 963 { 964 marker->_sbuf = fp; 965 if (_IO_in_put_mode (fp)) 966 INTUSE(_IO_switch_to_get_mode) (fp); 967 if (_IO_in_backup (fp)) 968 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end; 969 else 970 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base; 971 972 /* Should perhaps sort the chain? */ 973 marker->_next = fp->_markers; 974 fp->_markers = marker; 975 } 976 977 void 978 _IO_remove_marker (marker) 979 struct _IO_marker *marker; 980 { 981 /* Unlink from sb's chain. */ 982 struct _IO_marker **ptr = &marker->_sbuf->_markers; 983 for (; ; ptr = &(*ptr)->_next) 984 { 985 if (*ptr == NULL) 986 break; 987 else if (*ptr == marker) 988 { 989 *ptr = marker->_next; 990 return; 991 } 992 } 993 #if 0 994 if _sbuf has a backup area that is no longer needed, should we delete 995 it now, or wait until the next underflow? 996 #endif 997 } 998 999 #define BAD_DELTA EOF 1000 1001 int 1002 _IO_marker_difference (mark1, mark2) 1003 struct _IO_marker *mark1; 1004 struct _IO_marker *mark2; 1005 { 1006 return mark1->_pos - mark2->_pos; 1007 } 1008 1009 /* Return difference between MARK and current position of MARK's stream. */ 1010 int 1011 _IO_marker_delta (mark) 1012 struct _IO_marker *mark; 1013 { 1014 int cur_pos; 1015 if (mark->_sbuf == NULL) 1016 return BAD_DELTA; 1017 if (_IO_in_backup (mark->_sbuf)) 1018 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end; 1019 else 1020 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base; 1021 return mark->_pos - cur_pos; 1022 } 1023 1024 int 1025 _IO_seekmark (fp, mark, delta) 1026 _IO_FILE *fp; 1027 struct _IO_marker *mark; 1028 int delta; 1029 { 1030 if (mark->_sbuf != fp) 1031 return EOF; 1032 if (mark->_pos >= 0) 1033 { 1034 if (_IO_in_backup (fp)) 1035 _IO_switch_to_main_get_area (fp); 1036 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos; 1037 } 1038 else 1039 { 1040 if (!_IO_in_backup (fp)) 1041 _IO_switch_to_backup_area (fp); 1042 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos; 1043 } 1044 return 0; 1045 } 1046 1047 void 1048 _IO_unsave_markers (fp) 1049 _IO_FILE *fp; 1050 { 1051 struct _IO_marker *mark = fp->_markers; 1052 if (mark) 1053 { 1054 #ifdef TODO 1055 streampos offset = seekoff (0, ios::cur, ios::in); 1056 if (offset != EOF) 1057 { 1058 offset += eGptr () - Gbase (); 1059 for ( ; mark != NULL; mark = mark->_next) 1060 mark->set_streampos (mark->_pos + offset); 1061 } 1062 else 1063 { 1064 for ( ; mark != NULL; mark = mark->_next) 1065 mark->set_streampos (EOF); 1066 } 1067 #endif 1068 fp->_markers = 0; 1069 } 1070 1071 if (_IO_have_backup (fp)) 1072 INTUSE(_IO_free_backup_area) (fp); 1073 } 1074 INTDEF(_IO_unsave_markers) 1075 1076 #if 0 1077 /* Seems not to be needed. --drepper */ 1078 int 1079 _IO_nobackup_pbackfail (fp, c) 1080 _IO_FILE *fp; 1081 int c; 1082 { 1083 if (fp->_IO_read_ptr > fp->_IO_read_base) 1084 fp->_IO_read_ptr--; 1085 if (c != EOF && *fp->_IO_read_ptr != c) 1086 *fp->_IO_read_ptr = c; 1087 return (unsigned char) c; 1088 } 1089 #endif 1090 1091 int 1092 _IO_default_pbackfail (fp, c) 1093 _IO_FILE *fp; 1094 int c; 1095 { 1096 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) 1097 && (unsigned char) fp->_IO_read_ptr[-1] == c) 1098 --fp->_IO_read_ptr; 1099 else 1100 { 1101 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ 1102 if (!_IO_in_backup (fp)) 1103 { 1104 /* We need to keep the invariant that the main get area 1105 logically follows the backup area. */ 1106 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp)) 1107 { 1108 if (save_for_backup (fp, fp->_IO_read_ptr)) 1109 return EOF; 1110 } 1111 else if (!_IO_have_backup (fp)) 1112 { 1113 /* No backup buffer: allocate one. */ 1114 /* Use nshort buffer, if unused? (probably not) FIXME */ 1115 int backup_size = 128; 1116 char *bbuf = (char *) malloc (backup_size); 1117 if (bbuf == NULL) 1118 return EOF; 1119 fp->_IO_save_base = bbuf; 1120 fp->_IO_save_end = fp->_IO_save_base + backup_size; 1121 fp->_IO_backup_base = fp->_IO_save_end; 1122 } 1123 fp->_IO_read_base = fp->_IO_read_ptr; 1124 _IO_switch_to_backup_area (fp); 1125 } 1126 else if (fp->_IO_read_ptr <= fp->_IO_read_base) 1127 { 1128 /* Increase size of existing backup buffer. */ 1129 _IO_size_t new_size; 1130 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; 1131 char *new_buf; 1132 new_size = 2 * old_size; 1133 new_buf = (char *) malloc (new_size); 1134 if (new_buf == NULL) 1135 return EOF; 1136 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base, 1137 old_size); 1138 free (fp->_IO_read_base); 1139 _IO_setg (fp, new_buf, new_buf + (new_size - old_size), 1140 new_buf + new_size); 1141 fp->_IO_backup_base = fp->_IO_read_ptr; 1142 } 1143 1144 *--fp->_IO_read_ptr = c; 1145 } 1146 return (unsigned char) c; 1147 } 1148 INTDEF(_IO_default_pbackfail) 1149 1150 _IO_off64_t 1151 _IO_default_seek (fp, offset, dir) 1152 _IO_FILE *fp; 1153 _IO_off64_t offset; 1154 int dir; 1155 { 1156 return _IO_pos_BAD; 1157 } 1158 1159 int 1160 _IO_default_stat (fp, st) 1161 _IO_FILE *fp; 1162 void* st; 1163 { 1164 return EOF; 1165 } 1166 1167 _IO_ssize_t 1168 _IO_default_read (fp, data, n) 1169 _IO_FILE* fp; 1170 void *data; 1171 _IO_ssize_t n; 1172 { 1173 return -1; 1174 } 1175 1176 _IO_ssize_t 1177 _IO_default_write (fp, data, n) 1178 _IO_FILE *fp; 1179 const void *data; 1180 _IO_ssize_t n; 1181 { 1182 return 0; 1183 } 1184 1185 int 1186 _IO_default_showmanyc (fp) 1187 _IO_FILE *fp; 1188 { 1189 return -1; 1190 } 1191 1192 void 1193 _IO_default_imbue (fp, locale) 1194 _IO_FILE *fp; 1195 void *locale; 1196 { 1197 } 1198 1199 _IO_ITER 1200 _IO_iter_begin() 1201 { 1202 return (_IO_ITER) INTUSE(_IO_list_all); 1203 } 1204 libc_hidden_def (_IO_iter_begin) 1205 1206 _IO_ITER 1207 _IO_iter_end() 1208 { 1209 return NULL; 1210 } 1211 libc_hidden_def (_IO_iter_end) 1212 1213 _IO_ITER 1214 _IO_iter_next(iter) 1215 _IO_ITER iter; 1216 { 1217 return iter->_chain; 1218 } 1219 libc_hidden_def (_IO_iter_next) 1220 1221 _IO_FILE * 1222 _IO_iter_file(iter) 1223 _IO_ITER iter; 1224 { 1225 return iter; 1226 } 1227 libc_hidden_def (_IO_iter_file) 1228 1229 void 1230 _IO_list_lock() 1231 { 1232 #ifdef _IO_MTSAFE_IO 1233 _IO_lock_lock (list_all_lock); 1234 #endif 1235 } 1236 libc_hidden_def (_IO_list_lock) 1237 1238 void 1239 _IO_list_unlock() 1240 { 1241 #ifdef _IO_MTSAFE_IO 1242 _IO_lock_unlock (list_all_lock); 1243 #endif 1244 } 1245 libc_hidden_def (_IO_list_unlock) 1246 1247 void 1248 _IO_list_resetlock() 1249 { 1250 #ifdef _IO_MTSAFE_IO 1251 _IO_lock_init (list_all_lock); 1252 #endif 1253 } 1254 libc_hidden_def (_IO_list_resetlock) 1255 1256 1257 #ifdef TODO 1258 #if defined(linux) 1259 #define IO_CLEANUP ; 1260 #endif 1261 1262 #ifdef IO_CLEANUP 1263 IO_CLEANUP 1264 #else 1265 struct __io_defs { 1266 __io_defs() { } 1267 ~__io_defs() { _IO_cleanup (); } 1268 }; 1269 __io_defs io_defs__; 1270 #endif 1271 1272 #endif /* TODO */ 1273 1274 #ifdef text_set_element 1275 text_set_element(__libc_atexit, _IO_cleanup); 1276 #endif 1277