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 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