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 #ifdef _IO_MTSAFE_IO 36 static _IO_lock_t list_all_lock = _IO_lock_initializer; 37 #endif 38 39 /* Used to signal modifications to the list of FILE decriptors. */ 40 static int _IO_list_all_stamp; 41 42 43 static _IO_FILE *run_fp; 44 45 #if 0 46 static void 47 flush_cleanup (void *not_used) 48 { 49 if (run_fp != NULL) 50 _IO_funlockfile (run_fp); 51 #ifdef _IO_MTSAFE_IO 52 _IO_lock_unlock (list_all_lock); 53 #endif 54 } 55 #endif 56 57 58 void 59 _IO_un_link(struct _IO_FILE_plus *fp) 60 { 61 if (fp->file._flags & _IO_LINKED) 62 { 63 struct _IO_FILE_plus **f; 64 #ifdef _IO_MTSAFE_IO 65 _IO_cleanup_region_start_noarg (flush_cleanup); 66 _IO_lock_lock (list_all_lock); 67 run_fp = (_IO_FILE *) fp; 68 _IO_flockfile ((_IO_FILE *) fp); 69 #endif 70 for (f = &INTUSE(_IO_list_all); *f; 71 f = (struct _IO_FILE_plus **) &(*f)->file._chain) 72 { 73 if (*f == fp) 74 { 75 *f = (struct _IO_FILE_plus *) fp->file._chain; 76 ++_IO_list_all_stamp; 77 break; 78 } 79 } 80 fp->file._flags &= ~_IO_LINKED; 81 #ifdef _IO_MTSAFE_IO 82 _IO_funlockfile ((_IO_FILE *) fp); 83 run_fp = NULL; 84 _IO_lock_unlock (list_all_lock); 85 _IO_cleanup_region_end (0); 86 #endif 87 } 88 } 89 INTDEF(_IO_un_link) 90 91 void 92 _IO_link_in (fp) 93 struct _IO_FILE_plus *fp; 94 { 95 if ((fp->file._flags & _IO_LINKED) == 0) 96 { 97 fp->file._flags |= _IO_LINKED; 98 #ifdef _IO_MTSAFE_IO 99 _IO_cleanup_region_start_noarg (flush_cleanup); 100 _IO_lock_lock (list_all_lock); 101 run_fp = (_IO_FILE *) fp; 102 _IO_flockfile ((_IO_FILE *) fp); 103 #endif 104 fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all); 105 INTUSE(_IO_list_all) = fp; 106 ++_IO_list_all_stamp; 107 #ifdef _IO_MTSAFE_IO 108 _IO_funlockfile ((_IO_FILE *) fp); 109 run_fp = NULL; 110 _IO_lock_unlock (list_all_lock); 111 _IO_cleanup_region_end (0); 112 #endif 113 } 114 } 115 INTDEF(_IO_link_in) 116 117 /* Return minimum _pos markers 118 Assumes the current get area is the main get area. */ 119 _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p)); 120 121 _IO_ssize_t 122 _IO_least_marker (fp, end_p) 123 _IO_FILE *fp; 124 char *end_p; 125 { 126 _IO_ssize_t least_so_far = end_p - fp->_IO_read_base; 127 struct _IO_marker *mark; 128 for (mark = fp->_markers; mark != NULL; mark = mark->_next) 129 if (mark->_pos < least_so_far) 130 least_so_far = mark->_pos; 131 return least_so_far; 132 } 133 134 /* Switch current get area from backup buffer to (start of) main get area. */ 135 136 void 137 _IO_switch_to_main_get_area (fp) 138 _IO_FILE *fp; 139 { 140 char *tmp; 141 fp->_flags &= ~_IO_IN_BACKUP; 142 /* Swap _IO_read_end and _IO_save_end. */ 143 tmp = fp->_IO_read_end; 144 fp->_IO_read_end = fp->_IO_save_end; 145 fp->_IO_save_end= tmp; 146 /* Swap _IO_read_base and _IO_save_base. */ 147 tmp = fp->_IO_read_base; 148 fp->_IO_read_base = fp->_IO_save_base; 149 fp->_IO_save_base = tmp; 150 /* Set _IO_read_ptr. */ 151 fp->_IO_read_ptr = fp->_IO_read_base; 152 } 153 154 /* Switch current get area from main get area to (end of) backup area. */ 155 156 void 157 _IO_switch_to_backup_area (fp) 158 _IO_FILE *fp; 159 { 160 char *tmp; 161 fp->_flags |= _IO_IN_BACKUP; 162 /* Swap _IO_read_end and _IO_save_end. */ 163 tmp = fp->_IO_read_end; 164 fp->_IO_read_end = fp->_IO_save_end; 165 fp->_IO_save_end = tmp; 166 /* Swap _IO_read_base and _IO_save_base. */ 167 tmp = fp->_IO_read_base; 168 fp->_IO_read_base = fp->_IO_save_base; 169 fp->_IO_save_base = tmp; 170 /* Set _IO_read_ptr. */ 171 fp->_IO_read_ptr = fp->_IO_read_end; 172 } 173 174 int 175 _IO_switch_to_get_mode (fp) 176 _IO_FILE *fp; 177 { 178 if (fp->_IO_write_ptr > fp->_IO_write_base) 179 if (_IO_OVERFLOW (fp, EOF) == EOF) 180 return EOF; 181 if (_IO_in_backup (fp)) 182 fp->_IO_read_base = fp->_IO_backup_base; 183 else 184 { 185 fp->_IO_read_base = fp->_IO_buf_base; 186 if (fp->_IO_write_ptr > fp->_IO_read_end) 187 fp->_IO_read_end = fp->_IO_write_ptr; 188 } 189 fp->_IO_read_ptr = fp->_IO_write_ptr; 190 191 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr; 192 193 fp->_flags &= ~_IO_CURRENTLY_PUTTING; 194 return 0; 195 } 196 INTDEF(_IO_switch_to_get_mode) 197 198 void 199 _IO_free_backup_area (fp) 200 _IO_FILE *fp; 201 { 202 if (_IO_in_backup (fp)) 203 _IO_switch_to_main_get_area (fp); /* Just in case. */ 204 free (fp->_IO_save_base); 205 fp->_IO_save_base = NULL; 206 fp->_IO_save_end = NULL; 207 fp->_IO_backup_base = NULL; 208 } 209 INTDEF(_IO_free_backup_area) 210 211 #if 0 212 int 213 _IO_switch_to_put_mode (fp) 214 _IO_FILE *fp; 215 { 216 fp->_IO_write_base = fp->_IO_read_ptr; 217 fp->_IO_write_ptr = fp->_IO_read_ptr; 218 /* Following is wrong if line- or un-buffered? */ 219 fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP 220 ? fp->_IO_read_end : fp->_IO_buf_end); 221 222 fp->_IO_read_ptr = fp->_IO_read_end; 223 fp->_IO_read_base = fp->_IO_read_end; 224 225 fp->_flags |= _IO_CURRENTLY_PUTTING; 226 return 0; 227 } 228 #endif 229 230 231 int 232 __overflow(_IO_FILE *file, int character) 233 { 234 /* This is a single-byte stream. */ 235 if (file->_mode == 0) 236 _IO_fwide(file, -1); 237 238 return _IO_OVERFLOW(file, character); 239 } 240 libc_hidden_def(__overflow) 241 242 243 static int save_for_backup __P ((_IO_FILE *fp, char *end_p)) 244 #ifdef _LIBC 245 internal_function 246 #endif 247 ; 248 249 static int 250 #ifdef _LIBC 251 internal_function 252 #endif 253 save_for_backup (fp, end_p) 254 _IO_FILE *fp; 255 char *end_p; 256 { 257 /* Append [_IO_read_base..end_p] to backup area. */ 258 _IO_ssize_t least_mark = _IO_least_marker (fp, end_p); 259 /* needed_size is how much space we need in the backup area. */ 260 _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; 261 /* FIXME: Dubious arithmetic if pointers are NULL */ 262 _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; 263 _IO_size_t avail; /* Extra space available for future expansion. */ 264 _IO_ssize_t delta; 265 struct _IO_marker *mark; 266 if (needed_size > current_Bsize) 267 { 268 char *new_buffer; 269 avail = 100; 270 new_buffer = (char *) malloc (avail + needed_size); 271 if (new_buffer == NULL) 272 return EOF; /* FIXME */ 273 if (least_mark < 0) 274 { 275 #ifdef _LIBC 276 __mempcpy (__mempcpy (new_buffer + avail, 277 fp->_IO_save_end + least_mark, 278 -least_mark), 279 fp->_IO_read_base, 280 end_p - fp->_IO_read_base); 281 #else 282 memcpy (new_buffer + avail, 283 fp->_IO_save_end + least_mark, 284 -least_mark); 285 memcpy (new_buffer + avail - least_mark, 286 fp->_IO_read_base, 287 end_p - fp->_IO_read_base); 288 #endif 289 } 290 else 291 memcpy (new_buffer + avail, 292 fp->_IO_read_base + least_mark, 293 needed_size); 294 if (fp->_IO_save_base) 295 free (fp->_IO_save_base); 296 fp->_IO_save_base = new_buffer; 297 fp->_IO_save_end = new_buffer + avail + needed_size; 298 } 299 else 300 { 301 avail = current_Bsize - needed_size; 302 if (least_mark < 0) 303 { 304 memmove (fp->_IO_save_base + avail, 305 fp->_IO_save_end + least_mark, 306 -least_mark); 307 memcpy (fp->_IO_save_base + avail - least_mark, 308 fp->_IO_read_base, 309 end_p - fp->_IO_read_base); 310 } 311 else if (needed_size > 0) 312 memcpy (fp->_IO_save_base + avail, 313 fp->_IO_read_base + least_mark, 314 needed_size); 315 } 316 fp->_IO_backup_base = fp->_IO_save_base + avail; 317 /* Adjust all the streammarkers. */ 318 delta = end_p - fp->_IO_read_base; 319 for (mark = fp->_markers; mark != NULL; mark = mark->_next) 320 mark->_pos -= delta; 321 return 0; 322 } 323 324 325 int 326 __underflow(_IO_FILE *file) 327 { 328 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 329 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1) 330 return EOF; 331 #endif 332 333 if (file->_mode == 0) 334 _IO_fwide(file, -1); 335 336 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF) 337 return EOF; 338 339 if (file->_IO_read_ptr < file->_IO_read_end) 340 return *(unsigned char *)file->_IO_read_ptr; 341 342 if (_IO_in_backup(file)) { 343 _IO_switch_to_main_get_area(file); 344 345 if (file->_IO_read_ptr < file->_IO_read_end) 346 return *(unsigned char *)file->_IO_read_ptr; 347 } 348 if (_IO_have_markers(file)) { 349 if (save_for_backup(file, file->_IO_read_end)) 350 return EOF; 351 } else if (_IO_have_backup(file)) 352 INTUSE(_IO_free_backup_area)(file); 353 354 return _IO_UNDERFLOW(file); 355 } 356 libc_hidden_def(__underflow) 357 358 359 int 360 __uflow(_IO_FILE *file) 361 { 362 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 363 if (file->_vtable_offset == 0 && _IO_fwide(file, -1) != -1) 364 return EOF; 365 #endif 366 367 if (file->_mode == 0) 368 _IO_fwide(file, -11); 369 370 if (_IO_in_put_mode(file) && INTUSE(_IO_switch_to_get_mode)(file) == EOF) 371 return EOF; 372 373 if (file->_IO_read_ptr < file->_IO_read_end) 374 return *(unsigned char *)file->_IO_read_ptr++; 375 376 if (_IO_in_backup(file)) { 377 _IO_switch_to_main_get_area(file); 378 379 if (file->_IO_read_ptr < file->_IO_read_end) 380 return *(unsigned char *)file->_IO_read_ptr++; 381 } 382 383 if (_IO_have_markers(file)) { 384 if (save_for_backup(file, file->_IO_read_end)) 385 return EOF; 386 } else if (_IO_have_backup(file)) 387 INTUSE(_IO_free_backup_area)(file); 388 389 return _IO_UFLOW(file); 390 } 391 libc_hidden_def(__uflow) 392 393 394 void 395 _IO_setb (f, b, eb, a) 396 _IO_FILE *f; 397 char *b; 398 char *eb; 399 int a; 400 { 401 if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) 402 FREE_BUF (f->_IO_buf_base, _IO_blen (f)); 403 f->_IO_buf_base = b; 404 f->_IO_buf_end = eb; 405 if (a) 406 f->_flags &= ~_IO_USER_BUF; 407 else 408 f->_flags |= _IO_USER_BUF; 409 } 410 INTDEF(_IO_setb) 411 412 void 413 _IO_doallocbuf (fp) 414 _IO_FILE *fp; 415 { 416 if (fp->_IO_buf_base) 417 return; 418 if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) 419 if (_IO_DOALLOCATE (fp) != EOF) 420 return; 421 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); 422 } 423 INTDEF(_IO_doallocbuf) 424 425 int 426 _IO_default_underflow (fp) 427 _IO_FILE *fp; 428 { 429 return EOF; 430 } 431 432 int 433 _IO_default_uflow (fp) 434 _IO_FILE *fp; 435 { 436 int ch = _IO_UNDERFLOW (fp); 437 if (ch == EOF) 438 return EOF; 439 return *(unsigned char *) fp->_IO_read_ptr++; 440 } 441 INTDEF(_IO_default_uflow) 442 443 _IO_size_t 444 _IO_default_xsputn (f, data, n) 445 _IO_FILE *f; 446 const void *data; 447 _IO_size_t n; 448 { 449 const char *s = (char *) data; 450 _IO_size_t more = n; 451 if (more <= 0) 452 return 0; 453 for (;;) 454 { 455 /* Space available. */ 456 _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; 457 if (count > 0) 458 { 459 if ((_IO_size_t) count > more) 460 count = more; 461 if (count > 20) 462 { 463 #ifdef _LIBC 464 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); 465 #else 466 memcpy (f->_IO_write_ptr, s, count); 467 f->_IO_write_ptr += count; 468 #endif 469 s += count; 470 } 471 else if (count <= 0) 472 count = 0; 473 else 474 { 475 char *p = f->_IO_write_ptr; 476 _IO_ssize_t i; 477 for (i = count; --i >= 0; ) 478 *p++ = *s++; 479 f->_IO_write_ptr = p; 480 } 481 more -= count; 482 } 483 if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF) 484 break; 485 more--; 486 } 487 return n - more; 488 } 489 INTDEF(_IO_default_xsputn) 490 491 _IO_size_t 492 _IO_sgetn (fp, data, n) 493 _IO_FILE *fp; 494 void *data; 495 _IO_size_t n; 496 { 497 /* FIXME handle putback buffer here! */ 498 return _IO_XSGETN (fp, data, n); 499 } 500 INTDEF(_IO_sgetn) 501 502 _IO_size_t 503 _IO_default_xsgetn (fp, data, n) 504 _IO_FILE *fp; 505 void *data; 506 _IO_size_t n; 507 { 508 _IO_size_t more = n; 509 char *s = (char*) data; 510 for (;;) 511 { 512 /* Data available. */ 513 _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; 514 if (count > 0) 515 { 516 if ((_IO_size_t) count > more) 517 count = more; 518 if (count > 20) 519 { 520 #ifdef _LIBC 521 s = __mempcpy (s, fp->_IO_read_ptr, count); 522 #else 523 memcpy (s, fp->_IO_read_ptr, count); 524 s += count; 525 #endif 526 fp->_IO_read_ptr += count; 527 } 528 else if (count <= 0) 529 count = 0; 530 else 531 { 532 char *p = fp->_IO_read_ptr; 533 int i = (int) count; 534 while (--i >= 0) 535 *s++ = *p++; 536 fp->_IO_read_ptr = p; 537 } 538 more -= count; 539 } 540 if (more == 0 || __underflow (fp) == EOF) 541 break; 542 } 543 return n - more; 544 } 545 INTDEF(_IO_default_xsgetn) 546 547 #if 0 548 /* Seems not to be needed. --drepper */ 549 int 550 _IO_sync (fp) 551 _IO_FILE *fp; 552 { 553 return 0; 554 } 555 #endif 556 557 _IO_FILE * 558 _IO_default_setbuf (fp, p, len) 559 _IO_FILE *fp; 560 char *p; 561 _IO_ssize_t len; 562 { 563 if (_IO_SYNC (fp) == EOF) 564 return NULL; 565 if (p == NULL || len == 0) 566 { 567 fp->_flags |= _IO_UNBUFFERED; 568 INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0); 569 } 570 else 571 { 572 fp->_flags &= ~_IO_UNBUFFERED; 573 INTUSE(_IO_setb) (fp, p, p+len, 0); 574 } 575 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0; 576 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0; 577 return fp; 578 } 579 580 _IO_off64_t 581 _IO_default_seekpos (fp, pos, mode) 582 _IO_FILE *fp; 583 _IO_off64_t pos; 584 int mode; 585 { 586 return _IO_SEEKOFF (fp, pos, 0, mode); 587 } 588 589 int 590 _IO_default_doallocate (fp) 591 _IO_FILE *fp; 592 { 593 char *buf; 594 595 ALLOC_BUF (buf, _IO_BUFSIZ, EOF); 596 INTUSE(_IO_setb) (fp, buf, buf+_IO_BUFSIZ, 1); 597 return 1; 598 } 599 INTDEF(_IO_default_doallocate) 600 601 void 602 _IO_init (fp, flags) 603 _IO_FILE *fp; 604 int flags; 605 { 606 _IO_no_init (fp, flags, -1, NULL, NULL); 607 } 608 INTDEF(_IO_init) 609 610 void 611 _IO_no_init (fp, flags, orientation, wd, jmp) 612 _IO_FILE *fp; 613 int flags; 614 int orientation; 615 struct _IO_wide_data *wd; 616 struct _IO_jump_t *jmp; 617 { 618 fp->_flags = _IO_MAGIC|flags; 619 fp->_flags2 = 0; 620 fp->_IO_buf_base = NULL; 621 fp->_IO_buf_end = NULL; 622 fp->_IO_read_base = NULL; 623 fp->_IO_read_ptr = NULL; 624 fp->_IO_read_end = NULL; 625 fp->_IO_write_base = NULL; 626 fp->_IO_write_ptr = NULL; 627 fp->_IO_write_end = NULL; 628 fp->_chain = NULL; /* Not necessary. */ 629 630 fp->_IO_save_base = NULL; 631 fp->_IO_backup_base = NULL; 632 fp->_IO_save_end = NULL; 633 fp->_markers = NULL; 634 fp->_cur_column = 0; 635 #if _IO_JUMPS_OFFSET 636 fp->_vtable_offset = 0; 637 #endif 638 #ifdef _IO_MTSAFE_IO 639 if (fp->_lock != NULL) 640 _IO_lock_init (*fp->_lock); 641 #endif 642 fp->_mode = orientation; 643 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 644 if (orientation >= 0) 645 { 646 fp->_wide_data = wd; 647 fp->_wide_data->_IO_buf_base = NULL; 648 fp->_wide_data->_IO_buf_end = NULL; 649 fp->_wide_data->_IO_read_base = NULL; 650 fp->_wide_data->_IO_read_ptr = NULL; 651 fp->_wide_data->_IO_read_end = NULL; 652 fp->_wide_data->_IO_write_base = NULL; 653 fp->_wide_data->_IO_write_ptr = NULL; 654 fp->_wide_data->_IO_write_end = NULL; 655 fp->_wide_data->_IO_save_base = NULL; 656 fp->_wide_data->_IO_backup_base = NULL; 657 fp->_wide_data->_IO_save_end = NULL; 658 659 fp->_wide_data->_wide_vtable = jmp; 660 } 661 #endif 662 } 663 664 int 665 _IO_default_sync (fp) 666 _IO_FILE *fp; 667 { 668 return 0; 669 } 670 671 /* The way the C++ classes are mapped into the C functions in the 672 current implementation, this function can get called twice! */ 673 674 void 675 _IO_default_finish (fp, dummy) 676 _IO_FILE *fp; 677 int dummy; 678 { 679 struct _IO_marker *mark; 680 if (fp->_IO_buf_base && fp->_IO_buf_base != fp->_shortbuf 681 && !(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 /* We do *not* want locking. Some threads might use streams but 945 that is there problem, we flush them underneath them. */ 946 int result = _IO_flush_all_lockp (0); 947 948 /* We currently don't have a reliable mechanism for making sure that 949 C++ static destructors are executed in the correct order. 950 So it is possible that other static destructors might want to 951 write to cout - and they're supposed to be able to do so. 952 953 The following will make the standard streambufs be unbuffered, 954 which forces any output from late destructors to be written out. */ 955 _IO_unbuffer_write (); 956 957 return result; 958 } 959 960 961 void 962 _IO_init_marker (marker, fp) 963 struct _IO_marker *marker; 964 _IO_FILE *fp; 965 { 966 marker->_sbuf = fp; 967 if (_IO_in_put_mode (fp)) 968 INTUSE(_IO_switch_to_get_mode) (fp); 969 if (_IO_in_backup (fp)) 970 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_end; 971 else 972 marker->_pos = fp->_IO_read_ptr - fp->_IO_read_base; 973 974 /* Should perhaps sort the chain? */ 975 marker->_next = fp->_markers; 976 fp->_markers = marker; 977 } 978 979 void 980 _IO_remove_marker (marker) 981 struct _IO_marker *marker; 982 { 983 /* Unlink from sb's chain. */ 984 struct _IO_marker **ptr = &marker->_sbuf->_markers; 985 for (; ; ptr = &(*ptr)->_next) 986 { 987 if (*ptr == NULL) 988 break; 989 else if (*ptr == marker) 990 { 991 *ptr = marker->_next; 992 return; 993 } 994 } 995 #if 0 996 if _sbuf has a backup area that is no longer needed, should we delete 997 it now, or wait until the next underflow? 998 #endif 999 } 1000 1001 #define BAD_DELTA EOF 1002 1003 int 1004 _IO_marker_difference (mark1, mark2) 1005 struct _IO_marker *mark1; 1006 struct _IO_marker *mark2; 1007 { 1008 return mark1->_pos - mark2->_pos; 1009 } 1010 1011 /* Return difference between MARK and current position of MARK's stream. */ 1012 int 1013 _IO_marker_delta (mark) 1014 struct _IO_marker *mark; 1015 { 1016 int cur_pos; 1017 if (mark->_sbuf == NULL) 1018 return BAD_DELTA; 1019 if (_IO_in_backup (mark->_sbuf)) 1020 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_end; 1021 else 1022 cur_pos = mark->_sbuf->_IO_read_ptr - mark->_sbuf->_IO_read_base; 1023 return mark->_pos - cur_pos; 1024 } 1025 1026 int 1027 _IO_seekmark (fp, mark, delta) 1028 _IO_FILE *fp; 1029 struct _IO_marker *mark; 1030 int delta; 1031 { 1032 if (mark->_sbuf != fp) 1033 return EOF; 1034 if (mark->_pos >= 0) 1035 { 1036 if (_IO_in_backup (fp)) 1037 _IO_switch_to_main_get_area (fp); 1038 fp->_IO_read_ptr = fp->_IO_read_base + mark->_pos; 1039 } 1040 else 1041 { 1042 if (!_IO_in_backup (fp)) 1043 _IO_switch_to_backup_area (fp); 1044 fp->_IO_read_ptr = fp->_IO_read_end + mark->_pos; 1045 } 1046 return 0; 1047 } 1048 1049 void 1050 _IO_unsave_markers (fp) 1051 _IO_FILE *fp; 1052 { 1053 struct _IO_marker *mark = fp->_markers; 1054 if (mark) 1055 { 1056 #ifdef TODO 1057 streampos offset = seekoff (0, ios::cur, ios::in); 1058 if (offset != EOF) 1059 { 1060 offset += eGptr () - Gbase (); 1061 for ( ; mark != NULL; mark = mark->_next) 1062 mark->set_streampos (mark->_pos + offset); 1063 } 1064 else 1065 { 1066 for ( ; mark != NULL; mark = mark->_next) 1067 mark->set_streampos (EOF); 1068 } 1069 #endif 1070 fp->_markers = 0; 1071 } 1072 1073 if (_IO_have_backup (fp)) 1074 INTUSE(_IO_free_backup_area) (fp); 1075 } 1076 INTDEF(_IO_unsave_markers) 1077 1078 #if 0 1079 /* Seems not to be needed. --drepper */ 1080 int 1081 _IO_nobackup_pbackfail (fp, c) 1082 _IO_FILE *fp; 1083 int c; 1084 { 1085 if (fp->_IO_read_ptr > fp->_IO_read_base) 1086 fp->_IO_read_ptr--; 1087 if (c != EOF && *fp->_IO_read_ptr != c) 1088 *fp->_IO_read_ptr = c; 1089 return (unsigned char) c; 1090 } 1091 #endif 1092 1093 int 1094 _IO_default_pbackfail (fp, c) 1095 _IO_FILE *fp; 1096 int c; 1097 { 1098 if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) 1099 && (unsigned char) fp->_IO_read_ptr[-1] == c) 1100 --fp->_IO_read_ptr; 1101 else 1102 { 1103 /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ 1104 if (!_IO_in_backup (fp)) 1105 { 1106 /* We need to keep the invariant that the main get area 1107 logically follows the backup area. */ 1108 if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp)) 1109 { 1110 if (save_for_backup (fp, fp->_IO_read_ptr)) 1111 return EOF; 1112 } 1113 else if (!_IO_have_backup (fp)) 1114 { 1115 /* No backup buffer: allocate one. */ 1116 /* Use nshort buffer, if unused? (probably not) FIXME */ 1117 int backup_size = 128; 1118 char *bbuf = (char *) malloc (backup_size); 1119 if (bbuf == NULL) 1120 return EOF; 1121 fp->_IO_save_base = bbuf; 1122 fp->_IO_save_end = fp->_IO_save_base + backup_size; 1123 fp->_IO_backup_base = fp->_IO_save_end; 1124 } 1125 fp->_IO_read_base = fp->_IO_read_ptr; 1126 _IO_switch_to_backup_area (fp); 1127 } 1128 else if (fp->_IO_read_ptr <= fp->_IO_read_base) 1129 { 1130 /* Increase size of existing backup buffer. */ 1131 _IO_size_t new_size; 1132 _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; 1133 char *new_buf; 1134 new_size = 2 * old_size; 1135 new_buf = (char *) malloc (new_size); 1136 if (new_buf == NULL) 1137 return EOF; 1138 memcpy (new_buf + (new_size - old_size), fp->_IO_read_base, 1139 old_size); 1140 free (fp->_IO_read_base); 1141 _IO_setg (fp, new_buf, new_buf + (new_size - old_size), 1142 new_buf + new_size); 1143 fp->_IO_backup_base = fp->_IO_read_ptr; 1144 } 1145 1146 *--fp->_IO_read_ptr = c; 1147 } 1148 return (unsigned char) c; 1149 } 1150 INTDEF(_IO_default_pbackfail) 1151 1152 _IO_off64_t 1153 _IO_default_seek (fp, offset, dir) 1154 _IO_FILE *fp; 1155 _IO_off64_t offset; 1156 int dir; 1157 { 1158 return _IO_pos_BAD; 1159 } 1160 1161 int 1162 _IO_default_stat (fp, st) 1163 _IO_FILE *fp; 1164 void* st; 1165 { 1166 return EOF; 1167 } 1168 1169 _IO_ssize_t 1170 _IO_default_read (fp, data, n) 1171 _IO_FILE* fp; 1172 void *data; 1173 _IO_ssize_t n; 1174 { 1175 return -1; 1176 } 1177 1178 _IO_ssize_t 1179 _IO_default_write (fp, data, n) 1180 _IO_FILE *fp; 1181 const void *data; 1182 _IO_ssize_t n; 1183 { 1184 return 0; 1185 } 1186 1187 int 1188 _IO_default_showmanyc (fp) 1189 _IO_FILE *fp; 1190 { 1191 return -1; 1192 } 1193 1194 void 1195 _IO_default_imbue (fp, locale) 1196 _IO_FILE *fp; 1197 void *locale; 1198 { 1199 } 1200 1201 _IO_ITER 1202 _IO_iter_begin() 1203 { 1204 return (_IO_ITER) INTUSE(_IO_list_all); 1205 } 1206 libc_hidden_def (_IO_iter_begin) 1207 1208 _IO_ITER 1209 _IO_iter_end() 1210 { 1211 return NULL; 1212 } 1213 libc_hidden_def (_IO_iter_end) 1214 1215 _IO_ITER 1216 _IO_iter_next(iter) 1217 _IO_ITER iter; 1218 { 1219 return iter->_chain; 1220 } 1221 libc_hidden_def (_IO_iter_next) 1222 1223 _IO_FILE * 1224 _IO_iter_file(iter) 1225 _IO_ITER iter; 1226 { 1227 return iter; 1228 } 1229 libc_hidden_def (_IO_iter_file) 1230 1231 void 1232 _IO_list_lock() 1233 { 1234 #ifdef _IO_MTSAFE_IO 1235 _IO_lock_lock (list_all_lock); 1236 #endif 1237 } 1238 libc_hidden_def (_IO_list_lock) 1239 1240 void 1241 _IO_list_unlock() 1242 { 1243 #ifdef _IO_MTSAFE_IO 1244 _IO_lock_unlock (list_all_lock); 1245 #endif 1246 } 1247 libc_hidden_def (_IO_list_unlock) 1248 1249 void 1250 _IO_list_resetlock() 1251 { 1252 #ifdef _IO_MTSAFE_IO 1253 _IO_lock_init (list_all_lock); 1254 #endif 1255 } 1256 libc_hidden_def (_IO_list_resetlock) 1257 1258 1259 #ifdef TODO 1260 #if defined(linux) 1261 #define IO_CLEANUP ; 1262 #endif 1263 1264 #ifdef IO_CLEANUP 1265 IO_CLEANUP 1266 #else 1267 struct __io_defs { 1268 __io_defs() { } 1269 ~__io_defs() { _IO_cleanup (); } 1270 }; 1271 __io_defs io_defs__; 1272 #endif 1273 1274 #endif /* TODO */ 1275 1276 #ifdef text_set_element 1277 text_set_element(__libc_atexit, _IO_cleanup); 1278 #endif 1279