1 /* Copyright (C) 1993, 1995, 1997-2002, 2003 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 Written by Per Bothner <bothner@cygnus.com>. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA. 19 20 As a special exception, if you link the code in this file with 21 files compiled with a GNU compiler to produce an executable, 22 that does not cause the resulting executable to be covered by 23 the GNU Lesser General Public License. This exception does not 24 however invalidate any other reasons why the executable file 25 might be covered by the GNU Lesser General Public License. 26 This exception applies to code released by its copyright holders 27 in files containing the exception. */ 28 29 30 #ifndef _POSIX_SOURCE 31 # define _POSIX_SOURCE 32 #endif 33 #include "libioP.h" 34 #include <assert.h> 35 #include <fcntl.h> 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #include <string.h> 40 #include <errno.h> 41 #include <unistd.h> 42 #ifdef __STDC__ 43 #include <stdlib.h> 44 #endif 45 #if 0 46 #if _LIBC 47 # include "../wcsmbs/wcsmbsload.h" 48 # include "../iconv/gconv_charset.h" 49 # include "../iconv/gconv_int.h" 50 # include <shlib-compat.h> 51 #endif 52 #endif 53 #ifndef errno 54 extern int errno; 55 #endif 56 #ifndef __set_errno 57 # define __set_errno(Val) errno = (Val) 58 #endif 59 60 #ifdef _LIBC 61 /*# define open(Name, Flags, Prot) __open (Name, Flags, Prot) 62 # define close(FD) __close (FD) 63 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) 64 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) 65 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)*/ 66 # define _IO_do_write _IO_new_do_write /* For macro uses. */ 67 #else 68 # define _IO_new_do_write _IO_do_write 69 # define _IO_new_file_attach _IO_file_attach 70 # define _IO_new_file_close_it _IO_file_close_it 71 # define _IO_new_file_finish _IO_file_finish 72 # define _IO_new_file_fopen _IO_file_fopen 73 # define _IO_new_file_init _IO_file_init 74 # define _IO_new_file_setbuf _IO_file_setbuf 75 # define _IO_new_file_sync _IO_file_sync 76 # define _IO_new_file_overflow _IO_file_overflow 77 # define _IO_new_file_seekoff _IO_file_seekoff 78 # define _IO_new_file_underflow _IO_file_underflow 79 # define _IO_new_file_write _IO_file_write 80 # define _IO_new_file_xsputn _IO_file_xsputn 81 #endif 82 83 #if 0 84 #ifdef _LIBC 85 extern struct __gconv_trans_data __libio_translit attribute_hidden; 86 #endif 87 #endif 88 89 /* An fstream can be in at most one of put mode, get mode, or putback mode. 90 Putback mode is a variant of get mode. 91 92 In a filebuf, there is only one current position, instead of two 93 separate get and put pointers. In get mode, the current position 94 is that of gptr(); in put mode that of pptr(). 95 96 The position in the buffer that corresponds to the position 97 in external file system is normally _IO_read_end, except in putback 98 mode, when it is _IO_save_end. 99 If the field _fb._offset is >= 0, it gives the offset in 100 the file as a whole corresponding to eGptr(). (?) 101 102 PUT MODE: 103 If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end, 104 and _IO_read_base are equal to each other. These are usually equal 105 to _IO_buf_base, though not necessarily if we have switched from 106 get mode to put mode. (The reason is to maintain the invariant 107 that _IO_read_end corresponds to the external file position.) 108 _IO_write_base is non-NULL and usually equal to _IO_base_base. 109 We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode. 110 The un-flushed character are those between _IO_write_base and _IO_write_ptr. 111 112 GET MODE: 113 If a filebuf is in get or putback mode, eback() != egptr(). 114 In get mode, the unread characters are between gptr() and egptr(). 115 The OS file position corresponds to that of egptr(). 116 117 PUTBACK MODE: 118 Putback mode is used to remember "excess" characters that have 119 been sputbackc'd in a separate putback buffer. 120 In putback mode, the get buffer points to the special putback buffer. 121 The unread characters are the characters between gptr() and egptr() 122 in the putback buffer, as well as the area between save_gptr() 123 and save_egptr(), which point into the original reserve buffer. 124 (The pointers save_gptr() and save_egptr() are the values 125 of gptr() and egptr() at the time putback mode was entered.) 126 The OS position corresponds to that of save_egptr(). 127 128 LINE BUFFERED OUTPUT: 129 During line buffered output, _IO_write_base==base() && epptr()==base(). 130 However, ptr() may be anywhere between base() and ebuf(). 131 This forces a call to filebuf::overflow(int C) on every put. 132 If there is more space in the buffer, and C is not a '\n', 133 then C is inserted, and pptr() incremented. 134 135 UNBUFFERED STREAMS: 136 If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer. 137 */ 138 139 #define CLOSED_FILEBUF_FLAGS \ 140 (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET) 141 142 143 void 144 _IO_new_file_init (fp) 145 struct _IO_FILE_plus *fp; 146 { 147 /* POSIX.1 allows another file handle to be used to change the position 148 of our file descriptor. Hence we actually don't know the actual 149 position before we do the first fseek (and until a following fflush). */ 150 fp->file._offset = _IO_pos_BAD; 151 fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; 152 153 INTUSE(_IO_link_in) (fp); 154 fp->file._fileno = -1; 155 } 156 INTDEF2(_IO_new_file_init, _IO_file_init) 157 158 int 159 _IO_new_file_close_it (fp) 160 _IO_FILE *fp; 161 { 162 int write_status, close_status; 163 if (!_IO_file_is_open (fp)) 164 return EOF; 165 166 if ((fp->_flags & _IO_NO_WRITES) == 0 167 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) 168 write_status = _IO_do_flush (fp); 169 else 170 write_status = 0; 171 172 INTUSE(_IO_unsave_markers) (fp); 173 174 close_status = _IO_SYSCLOSE (fp); 175 176 /* Free buffer. */ 177 if (fp->_mode <= 0) 178 { 179 INTUSE(_IO_setb) (fp, NULL, NULL, 0); 180 _IO_setg (fp, NULL, NULL, NULL); 181 _IO_setp (fp, NULL, NULL); 182 } 183 #if 0 184 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T 185 else 186 { 187 if (_IO_have_wbackup (fp)) 188 INTUSE(_IO_free_wbackup_area) (fp); 189 INTUSE(_IO_wsetb) (fp, NULL, NULL, 0); 190 _IO_wsetg (fp, NULL, NULL, NULL); 191 _IO_wsetp (fp, NULL, NULL); 192 } 193 #endif 194 #endif 195 196 INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp); 197 fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; 198 fp->_fileno = -1; 199 fp->_offset = _IO_pos_BAD; 200 201 return close_status ? close_status : write_status; 202 } 203 INTDEF2(_IO_new_file_close_it, _IO_file_close_it) 204 205 void 206 _IO_new_file_finish (fp, dummy) 207 _IO_FILE *fp; 208 int dummy; 209 { 210 if (_IO_file_is_open (fp)) 211 { 212 _IO_do_flush (fp); 213 if (!(fp->_flags & _IO_DELETE_DONT_CLOSE)) 214 _IO_SYSCLOSE (fp); 215 } 216 INTUSE(_IO_default_finish) (fp, 0); 217 } 218 INTDEF2(_IO_new_file_finish, _IO_file_finish) 219 220 #if defined __GNUC__ && __GNUC__ >= 2 221 __inline__ 222 #endif 223 _IO_FILE * 224 _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64) 225 _IO_FILE *fp; 226 const char *filename; 227 int posix_mode; 228 int prot; 229 int read_write; 230 int is32not64; 231 { 232 int fdesc; 233 #ifdef _G_OPEN64 234 fdesc = (is32not64 235 ? open (filename, posix_mode, prot) 236 : _G_OPEN64 (filename, posix_mode, prot)); 237 #else 238 fdesc = open (filename, posix_mode, prot); 239 #endif 240 if (fdesc < 0) 241 return NULL; 242 fp->_fileno = fdesc; 243 _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); 244 if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS)) 245 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) 246 == _IO_pos_BAD && errno != ESPIPE) 247 { 248 close (fdesc); 249 return NULL; 250 } 251 INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp); 252 return fp; 253 } 254 libc_hidden_def (_IO_file_open) 255 256 257 _IO_FILE * 258 _IO_new_file_fopen(_IO_FILE *fp, const char *filename, const char *mode, int is32not64) 259 { 260 int oflags = 0, omode; 261 int read_write; 262 int oprot = 0666; 263 int i; 264 _IO_FILE *result; 265 #ifdef _LIBC 266 // const char *cs; 267 const char *last_recognized; 268 #endif 269 270 if (_IO_file_is_open (fp)) 271 return 0; 272 switch (*mode) 273 { 274 case 'r': 275 omode = O_RDONLY; 276 read_write = _IO_NO_WRITES; 277 break; 278 case 'w': 279 omode = O_WRONLY; 280 oflags = O_CREAT|O_TRUNC; 281 read_write = _IO_NO_READS; 282 break; 283 case 'a': 284 omode = O_WRONLY; 285 oflags = O_CREAT|O_APPEND; 286 read_write = _IO_NO_READS|_IO_IS_APPENDING; 287 break; 288 default: 289 __set_errno (EINVAL); 290 return NULL; 291 } 292 #ifdef _LIBC 293 last_recognized = mode; 294 #endif 295 for (i = 1; i < 5; ++i) 296 { 297 switch (*++mode) 298 { 299 case '\0': 300 break; 301 case '+': 302 omode = O_RDWR; 303 read_write &= _IO_IS_APPENDING; 304 #ifdef _LIBC 305 last_recognized = mode; 306 #endif 307 continue; 308 case 'x': 309 oflags |= O_EXCL; 310 #ifdef _LIBC 311 last_recognized = mode; 312 #endif 313 continue; 314 case 'b': 315 #ifdef _LIBC 316 last_recognized = mode; 317 #endif 318 continue; 319 case 'm': 320 fp->_flags2 |= _IO_FLAGS2_MMAP; 321 continue; 322 default: 323 /* Ignore. */ 324 continue; 325 } 326 break; 327 } 328 329 result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, 330 is32not64); 331 332 #if 0 333 #ifdef _LIBC 334 if (result != NULL) 335 { 336 /* Test whether the mode string specifies the conversion. */ 337 cs = strstr (last_recognized + 1, ",ccs="); 338 if (cs != NULL) 339 { 340 /* Yep. Load the appropriate conversions and set the orientation 341 to wide. */ 342 struct gconv_fcts fcts; 343 struct _IO_codecvt *cc; 344 char *endp = __strchrnul (cs + 5, ','); 345 char ccs[endp - (cs + 5) + 3]; 346 347 *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0'; 348 strip (ccs, ccs); 349 350 if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0' 351 ? upstr (ccs, cs + 5) : ccs) != 0) 352 { 353 /* Something went wrong, we cannot load the conversion modules. 354 This means we cannot proceed since the user explicitly asked 355 for these. */ 356 (void) INTUSE(_IO_file_close_it) (fp); 357 __set_errno (EINVAL); 358 return NULL; 359 } 360 361 assert (fcts.towc_nsteps == 1); 362 assert (fcts.tomb_nsteps == 1); 363 364 fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; 365 fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; 366 367 /* Clear the state. We start all over again. */ 368 memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); 369 memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t)); 370 371 cc = fp->_codecvt = &fp->_wide_data->_codecvt; 372 373 /* The functions are always the same. */ 374 *cc = __libio_codecvt; 375 376 cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; 377 cc->__cd_in.__cd.__steps = fcts.towc; 378 379 cc->__cd_in.__cd.__data[0].__invocation_counter = 0; 380 cc->__cd_in.__cd.__data[0].__internal_use = 1; 381 cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST; 382 cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state; 383 384 /* XXX For now no transliteration. */ 385 cc->__cd_in.__cd.__data[0].__trans = NULL; 386 387 cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps; 388 cc->__cd_out.__cd.__steps = fcts.tomb; 389 390 cc->__cd_out.__cd.__data[0].__invocation_counter = 0; 391 cc->__cd_out.__cd.__data[0].__internal_use = 1; 392 cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST; 393 cc->__cd_out.__cd.__data[0].__statep = 394 &result->_wide_data->_IO_state; 395 396 /* And now the transliteration. */ 397 cc->__cd_out.__cd.__data[0].__trans = &__libio_translit; 398 399 /* Set the mode now. */ 400 result->_mode = 1; 401 402 /* We don't need the step data structure anymore. */ 403 __gconv_release_cache (fcts.towc, fcts.towc_nsteps); 404 __gconv_release_cache (fcts.tomb, fcts.tomb_nsteps); 405 } 406 } 407 #endif /* GNU libc */ 408 #endif 409 410 return result; 411 } 412 INTDEF2(_IO_new_file_fopen, _IO_file_fopen) 413 414 _IO_FILE * 415 _IO_new_file_attach (fp, fd) 416 _IO_FILE *fp; 417 int fd; 418 { 419 if (_IO_file_is_open (fp)) 420 return NULL; 421 fp->_fileno = fd; 422 fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES); 423 fp->_flags |= _IO_DELETE_DONT_CLOSE; 424 /* Get the current position of the file. */ 425 /* We have to do that since that may be junk. */ 426 fp->_offset = _IO_pos_BAD; 427 if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) 428 == _IO_pos_BAD && errno != ESPIPE) 429 return NULL; 430 return fp; 431 } 432 INTDEF2(_IO_new_file_attach, _IO_file_attach) 433 434 _IO_FILE * 435 _IO_new_file_setbuf (fp, p, len) 436 _IO_FILE *fp; 437 char *p; 438 _IO_ssize_t len; 439 { 440 if (_IO_default_setbuf (fp, p, len) == NULL) 441 return NULL; 442 443 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end 444 = fp->_IO_buf_base; 445 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); 446 447 return fp; 448 } 449 INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf) 450 451 452 _IO_FILE * 453 _IO_file_setbuf_mmap(_IO_FILE *fp, char *p, _IO_ssize_t len) 454 { 455 _IO_FILE *result; 456 457 /* Change the function table. */ 458 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &INTUSE(_IO_file_jumps); 459 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; 460 461 /* And perform the normal operation. */ 462 result = _IO_new_file_setbuf(fp, p, len); 463 464 #if HAVE_MMAP 465 /* If the call failed, restore to using mmap. */ 466 if (result == NULL) { 467 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap; 468 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; 469 } 470 #endif 471 472 return result; 473 } 474 475 static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t)); 476 477 /* Write TO_DO bytes from DATA to FP. 478 Then mark FP as having empty buffers. */ 479 480 int 481 _IO_new_do_write (fp, data, to_do) 482 _IO_FILE *fp; 483 const char *data; 484 _IO_size_t to_do; 485 { 486 return (to_do == 0 487 || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF; 488 } 489 INTDEF2(_IO_new_do_write, _IO_do_write) 490 491 static 492 int 493 new_do_write (fp, data, to_do) 494 _IO_FILE *fp; 495 const char *data; 496 _IO_size_t to_do; 497 { 498 _IO_size_t count; 499 if (fp->_flags & _IO_IS_APPENDING) 500 /* On a system without a proper O_APPEND implementation, 501 you would need to sys_seek(0, SEEK_END) here, but is 502 is not needed nor desirable for Unix- or Posix-like systems. 503 Instead, just indicate that offset (before and after) is 504 unpredictable. */ 505 fp->_offset = _IO_pos_BAD; 506 else if (fp->_IO_read_end != fp->_IO_write_base) 507 { 508 _IO_off64_t new_pos 509 = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); 510 if (new_pos == _IO_pos_BAD) 511 return 0; 512 fp->_offset = new_pos; 513 } 514 count = _IO_SYSWRITE (fp, data, to_do); 515 if (fp->_cur_column && count) 516 fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data, 517 count) + 1; 518 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); 519 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base; 520 fp->_IO_write_end = (fp->_mode <= 0 521 && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) 522 ? fp->_IO_buf_base : fp->_IO_buf_end); 523 return count; 524 } 525 526 int 527 _IO_new_file_underflow (fp) 528 _IO_FILE *fp; 529 { 530 _IO_ssize_t count; 531 #if 0 532 /* SysV does not make this test; take it out for compatibility */ 533 if (fp->_flags & _IO_EOF_SEEN) 534 return (EOF); 535 #endif 536 537 if (fp->_flags & _IO_NO_READS) 538 { 539 fp->_flags |= _IO_ERR_SEEN; 540 __set_errno (EBADF); 541 return EOF; 542 } 543 if (fp->_IO_read_ptr < fp->_IO_read_end) 544 return *(unsigned char *) fp->_IO_read_ptr; 545 546 if (fp->_IO_buf_base == NULL) 547 { 548 /* Maybe we already have a push back pointer. */ 549 if (fp->_IO_save_base != NULL) 550 { 551 free (fp->_IO_save_base); 552 fp->_flags &= ~_IO_IN_BACKUP; 553 } 554 INTUSE(_IO_doallocbuf) (fp); 555 } 556 557 /* Flush all line buffered files before reading. */ 558 /* FIXME This can/should be moved to genops ?? */ 559 if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) 560 { 561 #if 0 562 INTUSE(_IO_flush_all_linebuffered) (); 563 #else 564 /* We used to flush all line-buffered stream. This really isn't 565 required by any standard. My recollection is that 566 traditional Unix systems did this for stdout. stderr better 567 not be line buffered. So we do just that here 568 explicitly. --drepper */ 569 _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, 570 _IO_stdout); 571 _IO_flockfile (_IO_stdout); 572 573 if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) 574 == (_IO_LINKED | _IO_LINE_BUF)) 575 _IO_OVERFLOW (_IO_stdout, EOF); 576 577 _IO_funlockfile (_IO_stdout); 578 _IO_cleanup_region_end (0); 579 #endif 580 } 581 582 INTUSE(_IO_switch_to_get_mode) (fp); 583 584 /* This is very tricky. We have to adjust those 585 pointers before we call _IO_SYSREAD () since 586 we may longjump () out while waiting for 587 input. Those pointers may be screwed up. H.J. */ 588 fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base; 589 fp->_IO_read_end = fp->_IO_buf_base; 590 fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end 591 = fp->_IO_buf_base; 592 593 count = _IO_SYSREAD (fp, fp->_IO_buf_base, 594 fp->_IO_buf_end - fp->_IO_buf_base); 595 if (count <= 0) 596 { 597 if (count == 0) 598 fp->_flags |= _IO_EOF_SEEN; 599 else 600 fp->_flags |= _IO_ERR_SEEN, count = 0; 601 } 602 fp->_IO_read_end += count; 603 if (count == 0) 604 return EOF; 605 if (fp->_offset != _IO_pos_BAD) 606 _IO_pos_adjust (fp->_offset, count); 607 return *(unsigned char *) fp->_IO_read_ptr; 608 } 609 INTDEF2(_IO_new_file_underflow, _IO_file_underflow) 610 611 #ifdef HAVE_MMAP 612 /* Guts of underflow callback if we mmap the file. This stats the file and 613 updates the stream state to match. In the normal case we return zero. 614 If the file is no longer eligible for mmap, its jump tables are reset to 615 the vanilla ones and we return nonzero. */ 616 static int 617 mmap_remap_check (_IO_FILE *fp) 618 { 619 struct _G_stat64 st; 620 621 if (_IO_SYSSTAT (fp, &st) == 0 622 && S_ISREG (st.st_mode) && st.st_size != 0 623 /* Limit the file size to 1MB for 32-bit machines. */ 624 && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024)) 625 { 626 const size_t pagesize = __getpagesize (); 627 # define ROUNDED(x) (((x) + pagesize - 1) & ~(pagesize - 1)) 628 if (ROUNDED (st.st_size) < ROUNDED (fp->_IO_buf_end 629 - fp->_IO_buf_base)) 630 { 631 /* We can trim off some pages past the end of the file. */ 632 (void) __munmap (fp->_IO_buf_base + ROUNDED (st.st_size), 633 ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base) 634 - ROUNDED (st.st_size)); 635 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; 636 } 637 else if (ROUNDED (st.st_size) > ROUNDED (fp->_IO_buf_end 638 - fp->_IO_buf_base)) 639 { 640 /* The file added some pages. We need to remap it. */ 641 void *p; 642 #if defined __linux__ /* XXX */ 643 p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end 644 - fp->_IO_buf_base), 645 ROUNDED (st.st_size), MREMAP_MAYMOVE); 646 if (p == MAP_FAILED) 647 { 648 (void) __munmap (fp->_IO_buf_base, 649 fp->_IO_buf_end - fp->_IO_buf_base); 650 goto punt; 651 } 652 #else 653 (void) __munmap (fp->_IO_buf_base, 654 fp->_IO_buf_end - fp->_IO_buf_base); 655 # ifdef _G_MMAP64 656 p = _G_MMAP64 (NULL, st.st_size, PROT_READ, MAP_SHARED, 657 fp->_fileno, 0); 658 # else 659 p = __mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, 660 fp->_fileno, 0); 661 # endif 662 if (p == MAP_FAILED) 663 goto punt; 664 #endif 665 fp->_IO_buf_base = p; 666 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; 667 } 668 else 669 { 670 /* The number of pages didn't change. */ 671 fp->_IO_buf_end = fp->_IO_buf_base + st.st_size; 672 } 673 # undef ROUNDED 674 675 fp->_offset -= fp->_IO_read_end - fp->_IO_read_ptr; 676 _IO_setg (fp, fp->_IO_buf_base, 677 fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base 678 ? fp->_IO_buf_base + fp->_offset : fp->_IO_buf_end, 679 fp->_IO_buf_end); 680 681 /* If we are already positioned at or past the end of the file, don't 682 change the current offset. If not, seek past what we have mapped, 683 mimicking the position left by a normal underflow reading into its 684 buffer until EOF. */ 685 686 if (fp->_offset < fp->_IO_buf_end - fp->_IO_buf_base) 687 { 688 if ( 689 # ifdef _G_LSEEK64 690 _G_LSEEK64 691 # else 692 __lseek 693 # endif 694 (fp->_fileno, fp->_IO_buf_end - fp->_IO_buf_base, SEEK_SET) 695 != fp->_IO_buf_end - fp->_IO_buf_base) 696 fp->_flags |= _IO_ERR_SEEN; 697 else 698 fp->_offset = fp->_IO_buf_end - fp->_IO_buf_base; 699 } 700 701 return 0; 702 } 703 else 704 { 705 /* Life is no longer good for mmap. Punt it. */ 706 __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base); 707 708 punt: 709 fp->_IO_buf_base = fp->_IO_buf_end = NULL; 710 _IO_setg (fp, NULL, NULL, NULL); 711 712 if (fp->_mode <= 0) 713 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &INTUSE(_IO_file_jumps); 714 else 715 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps; 716 717 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; 718 719 return 1; 720 } 721 } 722 723 724 /* Special callback replacing the underflow callbacks if we mmap the file. */ 725 int 726 _IO_file_underflow_mmap (_IO_FILE *fp) 727 { 728 if (fp->_IO_read_ptr < fp->_IO_read_end) 729 return *(unsigned char *) fp->_IO_read_ptr; 730 731 if (__builtin_expect (mmap_remap_check (fp), 0)) 732 /* We punted to the regular file functions. */ 733 return _IO_UNDERFLOW (fp); 734 735 if (fp->_IO_read_ptr < fp->_IO_read_end) 736 return *(unsigned char *) fp->_IO_read_ptr; 737 738 fp->_flags |= _IO_EOF_SEEN; 739 return EOF; 740 } 741 742 743 static void 744 decide_maybe_mmap(_IO_FILE *fp) 745 { 746 /* We use the file in read-only mode. This could mean we can 747 * mmap the file and use it without any copying. But not all 748 * file descriptors are for mmap-able objects and on 32-bit 749 * machines we don't want to map files which are too large since 750 * this would require too much virtual memory. 751 */ 752 struct _G_stat64 st; 753 754 if (_IO_SYSSTAT(fp, &st) == 0 755 && S_ISREG (st.st_mode) && st.st_size != 0 756 /* Limit the file size to 1MB for 32-bit machines. */ 757 && (sizeof(ptrdiff_t) > 4 || st.st_size < 1*1024*1024) 758 /* Sanity check. */ 759 && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) 760 { 761 /* Try to map the file. */ 762 void *p; 763 764 # ifdef _G_MMAP64 765 p = _G_MMAP64(NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); 766 # else 767 p = __mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); 768 # endif 769 770 if (p != MAP_FAILED) { 771 /* OK, we managed to map the file. Set the buffer up and use a 772 * special jump table with simplified underflow functions which 773 * never tries to read anything from the file. 774 */ 775 776 if ( 777 # ifdef _G_LSEEK64 778 _G_LSEEK64 779 # else 780 __lseek 781 # endif 782 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size) { 783 (void) __munmap (p, st.st_size); 784 fp->_offset = _IO_pos_BAD; 785 } else { 786 INTUSE(_IO_setb) (fp, p, (char *) p + st.st_size, 0); 787 788 if (fp->_offset == _IO_pos_BAD) 789 fp->_offset = 0; 790 791 _IO_setg (fp, p, p + fp->_offset, p + st.st_size); 792 fp->_offset = st.st_size; 793 794 if (fp->_mode <= 0) 795 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap; 796 else 797 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap; 798 799 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; 800 801 return; 802 } 803 } 804 } 805 806 /* We couldn't use mmap, so revert to the vanilla file operations. */ 807 808 if (fp->_mode <= 0) 809 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &INTUSE(_IO_file_jumps); 810 else 811 _IO_JUMPS((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps; 812 813 fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; 814 } 815 816 817 int 818 _IO_file_underflow_maybe_mmap (_IO_FILE *fp) 819 { 820 /* This is the first read attempt. Choose mmap or vanilla operations 821 and then punt to the chosen underflow routine. */ 822 decide_maybe_mmap (fp); 823 return _IO_UNDERFLOW (fp); 824 } 825 #endif /* HAVE_MMAP */ 826 827 828 int 829 _IO_new_file_overflow (f, ch) 830 _IO_FILE *f; 831 int ch; 832 { 833 if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ 834 { 835 f->_flags |= _IO_ERR_SEEN; 836 __set_errno (EBADF); 837 return EOF; 838 } 839 /* If currently reading or no buffer allocated. */ 840 if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0) 841 { 842 /* Allocate a buffer if needed. */ 843 if (f->_IO_write_base == 0) 844 { 845 INTUSE(_IO_doallocbuf) (f); 846 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); 847 } 848 /* Otherwise must be currently reading. 849 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, 850 logically slide the buffer forwards one block (by setting the 851 read pointers to all point at the beginning of the block). This 852 makes room for subsequent output. 853 Otherwise, set the read pointers to _IO_read_end (leaving that 854 alone, so it can continue to correspond to the external position). */ 855 if (f->_IO_read_ptr == f->_IO_buf_end) 856 f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; 857 f->_IO_write_ptr = f->_IO_read_ptr; 858 f->_IO_write_base = f->_IO_write_ptr; 859 f->_IO_write_end = f->_IO_buf_end; 860 f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; 861 862 f->_flags |= _IO_CURRENTLY_PUTTING; 863 if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED)) 864 f->_IO_write_end = f->_IO_write_ptr; 865 } 866 if (ch == EOF) 867 return INTUSE(_IO_do_write) (f, f->_IO_write_base, 868 f->_IO_write_ptr - f->_IO_write_base); 869 if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ 870 if (_IO_do_flush (f) == EOF) 871 return EOF; 872 *f->_IO_write_ptr++ = ch; 873 if ((f->_flags & _IO_UNBUFFERED) 874 || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) 875 if (INTUSE(_IO_do_write) (f, f->_IO_write_base, 876 f->_IO_write_ptr - f->_IO_write_base) == EOF) 877 return EOF; 878 return (unsigned char) ch; 879 } 880 INTDEF2(_IO_new_file_overflow, _IO_file_overflow) 881 882 int 883 _IO_new_file_sync (fp) 884 _IO_FILE *fp; 885 { 886 _IO_ssize_t delta; 887 int retval = 0; 888 889 /* char* ptr = cur_ptr(); */ 890 if (fp->_IO_write_ptr > fp->_IO_write_base) 891 if (_IO_do_flush(fp)) return EOF; 892 delta = fp->_IO_read_ptr - fp->_IO_read_end; 893 if (delta != 0) 894 { 895 #ifdef TODO 896 if (_IO_in_backup (fp)) 897 delta -= eGptr () - Gbase (); 898 #endif 899 _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); 900 if (new_pos != (_IO_off64_t) EOF) 901 fp->_IO_read_end = fp->_IO_read_ptr; 902 #ifdef ESPIPE 903 else if (errno == ESPIPE) 904 ; /* Ignore error from unseekable devices. */ 905 #endif 906 else 907 retval = EOF; 908 } 909 if (retval != EOF) 910 fp->_offset = _IO_pos_BAD; 911 /* FIXME: Cleanup - can this be shared? */ 912 /* setg(base(), ptr, ptr); */ 913 return retval; 914 } 915 INTDEF2(_IO_new_file_sync, _IO_file_sync) 916 917 #ifdef HAVE_MMAP 918 static int 919 _IO_file_sync_mmap (_IO_FILE *fp) 920 { 921 if (fp->_IO_read_ptr != fp->_IO_read_end) 922 { 923 #ifdef TODO 924 if (_IO_in_backup (fp)) 925 delta -= eGptr () - Gbase (); 926 #endif 927 if ( 928 # ifdef _G_LSEEK64 929 _G_LSEEK64 930 # else 931 __lseek 932 # endif 933 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, SEEK_SET) 934 != fp->_IO_read_ptr - fp->_IO_buf_base) 935 { 936 fp->_flags |= _IO_ERR_SEEN; 937 return EOF; 938 } 939 } 940 fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base; 941 fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base; 942 return 0; 943 } 944 #endif /* HAVE_MMAP */ 945 946 947 _IO_off64_t 948 _IO_new_file_seekoff (fp, offset, dir, mode) 949 _IO_FILE *fp; 950 _IO_off64_t offset; 951 int dir; 952 int mode; 953 { 954 _IO_off64_t result; 955 _IO_off64_t delta, new_offset; 956 long count; 957 /* POSIX.1 8.2.3.7 says that after a call the fflush() the file 958 offset of the underlying file must be exact. */ 959 int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end 960 && fp->_IO_write_base == fp->_IO_write_ptr); 961 962 if (mode == 0) 963 dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ 964 965 /* Flush unwritten characters. 966 (This may do an unneeded write if we seek within the buffer. 967 But to be able to switch to reading, we would need to set 968 egptr to ptr. That can't be done in the current design, 969 which assumes file_ptr() is eGptr. Anyway, since we probably 970 end up flushing when we close(), it doesn't make much difference.) 971 FIXME: simulate mem-papped files. */ 972 973 if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp)) 974 if (INTUSE(_IO_switch_to_get_mode) (fp)) 975 return EOF; 976 977 if (fp->_IO_buf_base == NULL) 978 { 979 /* It could be that we already have a pushback buffer. */ 980 if (fp->_IO_read_base != NULL) 981 { 982 free (fp->_IO_read_base); 983 fp->_flags &= ~_IO_IN_BACKUP; 984 } 985 INTUSE(_IO_doallocbuf) (fp); 986 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); 987 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); 988 } 989 990 switch (dir) 991 { 992 case _IO_seek_cur: 993 /* Adjust for read-ahead (bytes is buffer). */ 994 offset -= fp->_IO_read_end - fp->_IO_read_ptr; 995 if (fp->_offset == _IO_pos_BAD) 996 goto dumb; 997 /* Make offset absolute, assuming current pointer is file_ptr(). */ 998 offset += fp->_offset; 999 if (offset < 0) 1000 { 1001 __set_errno (EINVAL); 1002 return EOF; 1003 } 1004 1005 dir = _IO_seek_set; 1006 break; 1007 case _IO_seek_set: 1008 break; 1009 case _IO_seek_end: 1010 { 1011 struct _G_stat64 st; 1012 if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)) 1013 { 1014 offset += st.st_size; 1015 dir = _IO_seek_set; 1016 } 1017 else 1018 goto dumb; 1019 } 1020 } 1021 /* At this point, dir==_IO_seek_set. */ 1022 1023 /* If we are only interested in the current position we've found it now. */ 1024 if (mode == 0) 1025 return offset; 1026 1027 /* If destination is within current buffer, optimize: */ 1028 if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL 1029 && !_IO_in_backup (fp)) 1030 { 1031 /* Offset relative to start of main get area. */ 1032 _IO_off64_t rel_offset = (offset - fp->_offset 1033 + (fp->_IO_read_end - fp->_IO_read_base)); 1034 if (rel_offset >= 0) 1035 { 1036 #if 0 1037 if (_IO_in_backup (fp)) 1038 _IO_switch_to_main_get_area (fp); 1039 #endif 1040 if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) 1041 { 1042 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, 1043 fp->_IO_read_end); 1044 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); 1045 { 1046 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1047 goto resync; 1048 } 1049 } 1050 #ifdef TODO 1051 /* If we have streammarkers, seek forward by reading ahead. */ 1052 if (_IO_have_markers (fp)) 1053 { 1054 int to_skip = rel_offset 1055 - (fp->_IO_read_ptr - fp->_IO_read_base); 1056 if (ignore (to_skip) != to_skip) 1057 goto dumb; 1058 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1059 goto resync; 1060 } 1061 #endif 1062 } 1063 #ifdef TODO 1064 if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ()) 1065 { 1066 if (!_IO_in_backup (fp)) 1067 _IO_switch_to_backup_area (fp); 1068 gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr); 1069 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1070 goto resync; 1071 } 1072 #endif 1073 } 1074 1075 #ifdef TODO 1076 INTUSE(_IO_unsave_markers) (fp); 1077 #endif 1078 1079 if (fp->_flags & _IO_NO_READS) 1080 goto dumb; 1081 1082 /* Try to seek to a block boundary, to improve kernel page management. */ 1083 new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1); 1084 delta = offset - new_offset; 1085 if (delta > fp->_IO_buf_end - fp->_IO_buf_base) 1086 { 1087 new_offset = offset; 1088 delta = 0; 1089 } 1090 result = _IO_SYSSEEK (fp, new_offset, 0); 1091 if (result < 0) 1092 return EOF; 1093 if (delta == 0) 1094 count = 0; 1095 else 1096 { 1097 count = _IO_SYSREAD (fp, fp->_IO_buf_base, 1098 (must_be_exact 1099 ? delta : fp->_IO_buf_end - fp->_IO_buf_base)); 1100 if (count < delta) 1101 { 1102 /* We weren't allowed to read, but try to seek the remainder. */ 1103 offset = count == EOF ? delta : delta-count; 1104 dir = _IO_seek_cur; 1105 goto dumb; 1106 } 1107 } 1108 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta, 1109 fp->_IO_buf_base + count); 1110 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); 1111 fp->_offset = result + count; 1112 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1113 return offset; 1114 dumb: 1115 1116 INTUSE(_IO_unsave_markers) (fp); 1117 result = _IO_SYSSEEK (fp, offset, dir); 1118 if (result != EOF) 1119 { 1120 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1121 fp->_offset = result; 1122 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); 1123 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); 1124 } 1125 return result; 1126 1127 resync: 1128 /* We need to do it since it is possible that the file offset in 1129 the kernel may be changed behind our back. It may happen when 1130 we fopen a file and then do a fork. One process may access the 1131 the file and the kernel file offset will be changed. */ 1132 if (fp->_offset >= 0) 1133 _IO_SYSSEEK (fp, fp->_offset, 0); 1134 1135 return offset; 1136 } 1137 INTDEF2(_IO_new_file_seekoff, _IO_file_seekoff) 1138 1139 _IO_off64_t 1140 _IO_file_seekoff_mmap (fp, offset, dir, mode) 1141 _IO_FILE *fp; 1142 _IO_off64_t offset; 1143 int dir; 1144 int mode; 1145 { 1146 _IO_off64_t result; 1147 1148 /* If we are only interested in the current position, calculate it and 1149 return right now. This calculation does the right thing when we are 1150 using a pushback buffer, but in the usual case has the same value as 1151 (fp->_IO_read_ptr - fp->_IO_buf_base). */ 1152 if (mode == 0) 1153 return fp->_offset - (fp->_IO_read_end - fp->_IO_read_ptr); 1154 1155 switch (dir) 1156 { 1157 case _IO_seek_cur: 1158 /* Adjust for read-ahead (bytes is buffer). */ 1159 offset += fp->_IO_read_ptr - fp->_IO_read_base; 1160 break; 1161 case _IO_seek_set: 1162 break; 1163 case _IO_seek_end: 1164 offset += fp->_IO_buf_end - fp->_IO_buf_base; 1165 break; 1166 } 1167 /* At this point, dir==_IO_seek_set. */ 1168 1169 if (offset < 0) 1170 { 1171 /* No negative offsets are valid. */ 1172 __set_errno (EINVAL); 1173 return EOF; 1174 } 1175 1176 result = _IO_SYSSEEK (fp, offset, 0); 1177 if (result < 0) 1178 return EOF; 1179 1180 if (offset > fp->_IO_buf_end - fp->_IO_buf_base) 1181 /* One can fseek arbitrarily past the end of the file 1182 and it is meaningless until one attempts to read. 1183 Leave the buffer pointers in EOF state until underflow. */ 1184 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_end, fp->_IO_buf_end); 1185 else 1186 /* Adjust the read pointers to match the file position, 1187 but so the next read attempt will call underflow. */ 1188 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + offset, 1189 fp->_IO_buf_base + offset); 1190 1191 fp->_offset = result; 1192 1193 _IO_mask_flags (fp, 0, _IO_EOF_SEEN); 1194 1195 return offset; 1196 } 1197 1198 #ifdef HAVE_MMAP 1199 static _IO_off64_t 1200 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, 1201 int mode) 1202 { 1203 /* We only get here when we haven't tried to read anything yet. 1204 So there is nothing more useful for us to do here than just 1205 the underlying lseek call. */ 1206 1207 _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir); 1208 if (result < 0) 1209 return EOF; 1210 1211 fp->_offset = result; 1212 return result; 1213 } 1214 #endif /* HAVE_MMAP */ 1215 1216 _IO_ssize_t 1217 _IO_file_read (fp, buf, size) 1218 _IO_FILE *fp; 1219 void *buf; 1220 _IO_ssize_t size; 1221 { 1222 return read (fp->_fileno, buf, size); 1223 } 1224 INTDEF(_IO_file_read) 1225 1226 _IO_off64_t 1227 _IO_file_seek (fp, offset, dir) 1228 _IO_FILE *fp; 1229 _IO_off64_t offset; 1230 int dir; 1231 { 1232 #ifdef _G_LSEEK64 1233 return _G_LSEEK64 (fp->_fileno, offset, dir); 1234 #else 1235 return lseek (fp->_fileno, offset, dir); 1236 #endif 1237 } 1238 INTDEF(_IO_file_seek) 1239 1240 int 1241 _IO_file_stat (fp, st) 1242 _IO_FILE *fp; 1243 void *st; 1244 { 1245 #ifdef _G_FSTAT64 1246 return _G_FSTAT64 (fp->_fileno, (struct _G_stat64 *) st); 1247 #else 1248 return fstat (fp->_fileno, (struct stat *) st); 1249 #endif 1250 } 1251 INTDEF(_IO_file_stat) 1252 1253 #ifdef HAVE_MMAP 1254 int 1255 _IO_file_close_mmap (fp) 1256 _IO_FILE *fp; 1257 { 1258 /* In addition to closing the file descriptor we have to unmap the file. */ 1259 (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base); 1260 fp->_IO_buf_base = fp->_IO_buf_end = NULL; 1261 return close (fp->_fileno); 1262 } 1263 #endif 1264 1265 int 1266 _IO_file_close (fp) 1267 _IO_FILE *fp; 1268 { 1269 return close (fp->_fileno); 1270 } 1271 INTDEF(_IO_file_close) 1272 1273 _IO_ssize_t 1274 _IO_new_file_write (f, data, n) 1275 _IO_FILE *f; 1276 const void *data; 1277 _IO_ssize_t n; 1278 { 1279 _IO_ssize_t to_do = n; 1280 while (to_do > 0) 1281 { 1282 _IO_ssize_t count = write (f->_fileno, data, to_do); 1283 if (count < 0) 1284 { 1285 f->_flags |= _IO_ERR_SEEN; 1286 break; 1287 } 1288 to_do -= count; 1289 data = (void *) ((char *) data + count); 1290 } 1291 n -= to_do; 1292 if (f->_offset >= 0) 1293 f->_offset += n; 1294 return n; 1295 } 1296 1297 _IO_size_t 1298 _IO_new_file_xsputn (f, data, n) 1299 _IO_FILE *f; 1300 const void *data; 1301 _IO_size_t n; 1302 { 1303 register const char *s = (const char *) data; 1304 _IO_size_t to_do = n; 1305 int must_flush = 0; 1306 _IO_size_t count; 1307 1308 if (n <= 0) 1309 return 0; 1310 /* This is an optimized implementation. 1311 If the amount to be written straddles a block boundary 1312 (or the filebuf is unbuffered), use sys_write directly. */ 1313 1314 /* First figure out how much space is available in the buffer. */ 1315 count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */ 1316 if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) 1317 { 1318 count = f->_IO_buf_end - f->_IO_write_ptr; 1319 if (count >= n) 1320 { 1321 register const char *p; 1322 for (p = s + n; p > s; ) 1323 { 1324 if (*--p == '\n') 1325 { 1326 count = p - s + 1; 1327 must_flush = 1; 1328 break; 1329 } 1330 } 1331 } 1332 } 1333 /* Then fill the buffer. */ 1334 if (count > 0) 1335 { 1336 if (count > to_do) 1337 count = to_do; 1338 if (count > 20) 1339 { 1340 #ifdef _LIBC 1341 f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); 1342 #else 1343 memcpy (f->_IO_write_ptr, s, count); 1344 f->_IO_write_ptr += count; 1345 #endif 1346 s += count; 1347 } 1348 else 1349 { 1350 register char *p = f->_IO_write_ptr; 1351 register int i = (int) count; 1352 while (--i >= 0) 1353 *p++ = *s++; 1354 f->_IO_write_ptr = p; 1355 } 1356 to_do -= count; 1357 } 1358 if (to_do + must_flush > 0) 1359 { 1360 _IO_size_t block_size, do_write; 1361 /* Next flush the (full) buffer. */ 1362 if (_IO_OVERFLOW (f, EOF) == EOF) 1363 return n - to_do; 1364 1365 /* Try to maintain alignment: write a whole number of blocks. 1366 dont_write is what gets left over. */ 1367 block_size = f->_IO_buf_end - f->_IO_buf_base; 1368 do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); 1369 1370 if (do_write) 1371 { 1372 count = new_do_write (f, s, do_write); 1373 to_do -= count; 1374 if (count < do_write) 1375 return n - to_do; 1376 } 1377 1378 /* Now write out the remainder. Normally, this will fit in the 1379 buffer, but it's somewhat messier for line-buffered files, 1380 so we let _IO_default_xsputn handle the general case. */ 1381 if (to_do) 1382 to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do); 1383 } 1384 return n - to_do; 1385 } 1386 INTDEF2(_IO_new_file_xsputn, _IO_file_xsputn) 1387 1388 _IO_size_t 1389 _IO_file_xsgetn (fp, data, n) 1390 _IO_FILE *fp; 1391 void *data; 1392 _IO_size_t n; 1393 { 1394 register _IO_size_t want, have; 1395 register _IO_ssize_t count; 1396 register char *s = data; 1397 1398 want = n; 1399 1400 if (fp->_IO_buf_base == NULL) 1401 { 1402 /* Maybe we already have a push back pointer. */ 1403 if (fp->_IO_save_base != NULL) 1404 { 1405 free (fp->_IO_save_base); 1406 fp->_flags &= ~_IO_IN_BACKUP; 1407 } 1408 INTUSE(_IO_doallocbuf) (fp); 1409 } 1410 1411 while (want > 0) 1412 { 1413 have = fp->_IO_read_end - fp->_IO_read_ptr; 1414 if (want <= have) 1415 { 1416 memcpy (s, fp->_IO_read_ptr, want); 1417 fp->_IO_read_ptr += want; 1418 want = 0; 1419 } 1420 else 1421 { 1422 if (have > 0) 1423 { 1424 #ifdef _LIBC 1425 s = __mempcpy (s, fp->_IO_read_ptr, have); 1426 #else 1427 memcpy (s, fp->_IO_read_ptr, have); 1428 s += have; 1429 #endif 1430 want -= have; 1431 fp->_IO_read_ptr += have; 1432 } 1433 1434 /* Check for backup and repeat */ 1435 if (_IO_in_backup (fp)) 1436 { 1437 _IO_switch_to_main_get_area (fp); 1438 continue; 1439 } 1440 1441 /* If we now want less than a buffer, underflow and repeat 1442 the copy. Otherwise, _IO_SYSREAD directly to 1443 the user buffer. */ 1444 if (fp->_IO_buf_base 1445 && want < (size_t) (fp->_IO_buf_end - fp->_IO_buf_base)) 1446 { 1447 if (__underflow (fp) == EOF) 1448 break; 1449 1450 continue; 1451 } 1452 1453 /* These must be set before the sysread as we might longjmp out 1454 waiting for input. */ 1455 _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base); 1456 _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); 1457 1458 /* Try to maintain alignment: read a whole number of blocks. */ 1459 count = want; 1460 if (fp->_IO_buf_base) 1461 { 1462 _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; 1463 if (block_size >= 128) 1464 count -= want % block_size; 1465 } 1466 1467 count = _IO_SYSREAD (fp, s, count); 1468 if (count <= 0) 1469 { 1470 if (count == 0) 1471 fp->_flags |= _IO_EOF_SEEN; 1472 else 1473 fp->_flags |= _IO_ERR_SEEN; 1474 1475 break; 1476 } 1477 1478 s += count; 1479 want -= count; 1480 if (fp->_offset != _IO_pos_BAD) 1481 _IO_pos_adjust (fp->_offset, count); 1482 } 1483 } 1484 1485 return n - want; 1486 } 1487 INTDEF(_IO_file_xsgetn) 1488 1489 #ifdef HAVE_MMAP 1490 static _IO_size_t _IO_file_xsgetn_mmap __P ((_IO_FILE *, void *, _IO_size_t)); 1491 static _IO_size_t 1492 _IO_file_xsgetn_mmap (fp, data, n) 1493 _IO_FILE *fp; 1494 void *data; 1495 _IO_size_t n; 1496 { 1497 register _IO_size_t have; 1498 char *read_ptr = fp->_IO_read_ptr; 1499 register char *s = (char *) data; 1500 1501 have = fp->_IO_read_end - fp->_IO_read_ptr; 1502 1503 if (have < n) 1504 { 1505 if (__builtin_expect (_IO_in_backup (fp), 0)) 1506 { 1507 #ifdef _LIBC 1508 s = __mempcpy (s, read_ptr, have); 1509 #else 1510 memcpy (s, read_ptr, have); 1511 s += have; 1512 #endif 1513 n -= have; 1514 _IO_switch_to_main_get_area (fp); 1515 read_ptr = fp->_IO_read_ptr; 1516 have = fp->_IO_read_end - fp->_IO_read_ptr; 1517 } 1518 1519 if (have < n) 1520 { 1521 /* Check that we are mapping all of the file, in case it grew. */ 1522 if (__builtin_expect (mmap_remap_check (fp), 0)) 1523 /* We punted mmap, so complete with the vanilla code. */ 1524 return s - (char *) data + _IO_XSGETN (fp, data, n); 1525 1526 read_ptr = fp->_IO_read_ptr; 1527 have = fp->_IO_read_end - read_ptr; 1528 } 1529 } 1530 1531 if (have < n) 1532 fp->_flags |= _IO_EOF_SEEN; 1533 1534 if (have != 0) 1535 { 1536 have = MIN (have, n); 1537 #ifdef _LIBC 1538 s = __mempcpy (s, read_ptr, have); 1539 #else 1540 memcpy (s, read_ptr, have); 1541 s += have; 1542 #endif 1543 fp->_IO_read_ptr = read_ptr + have; 1544 } 1545 1546 return s - (char *) data; 1547 } 1548 1549 static _IO_size_t _IO_file_xsgetn_maybe_mmap __P ((_IO_FILE *, void *, 1550 _IO_size_t)); 1551 static _IO_size_t 1552 _IO_file_xsgetn_maybe_mmap (fp, data, n) 1553 _IO_FILE *fp; 1554 void *data; 1555 _IO_size_t n; 1556 { 1557 /* We only get here if this is the first attempt to read something. 1558 Decide which operations to use and then punt to the chosen one. */ 1559 1560 decide_maybe_mmap (fp); 1561 return _IO_XSGETN (fp, data, n); 1562 } 1563 #endif /* HAVE_MMAP */ 1564 1565 #ifdef _LIBC 1566 # undef _IO_do_write 1567 versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1); 1568 versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1); 1569 versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1); 1570 versioned_symbol (libc, _IO_new_file_finish, _IO_file_finish, GLIBC_2_1); 1571 versioned_symbol (libc, _IO_new_file_fopen, _IO_file_fopen, GLIBC_2_1); 1572 versioned_symbol (libc, _IO_new_file_init, _IO_file_init, GLIBC_2_1); 1573 versioned_symbol (libc, _IO_new_file_setbuf, _IO_file_setbuf, GLIBC_2_1); 1574 versioned_symbol (libc, _IO_new_file_sync, _IO_file_sync, GLIBC_2_1); 1575 versioned_symbol (libc, _IO_new_file_overflow, _IO_file_overflow, GLIBC_2_1); 1576 versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1); 1577 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1); 1578 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1); 1579 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1); 1580 #endif 1581 1582 struct _IO_jump_t _IO_file_jumps = 1583 { 1584 JUMP_INIT_DUMMY, 1585 JUMP_INIT(finish, INTUSE(_IO_file_finish)), 1586 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), 1587 JUMP_INIT(underflow, INTUSE(_IO_file_underflow)), 1588 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), 1589 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), 1590 JUMP_INIT(xsputn, INTUSE(_IO_file_xsputn)), 1591 JUMP_INIT(xsgetn, INTUSE(_IO_file_xsgetn)), 1592 JUMP_INIT(seekoff, _IO_new_file_seekoff), 1593 JUMP_INIT(seekpos, _IO_default_seekpos), 1594 JUMP_INIT(setbuf, _IO_new_file_setbuf), 1595 JUMP_INIT(sync, _IO_new_file_sync), 1596 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), 1597 JUMP_INIT(read, INTUSE(_IO_file_read)), 1598 JUMP_INIT(write, _IO_new_file_write), 1599 JUMP_INIT(seek, INTUSE(_IO_file_seek)), 1600 JUMP_INIT(close, INTUSE(_IO_file_close)), 1601 JUMP_INIT(stat, INTUSE(_IO_file_stat)), 1602 JUMP_INIT(showmanyc, _IO_default_showmanyc), 1603 JUMP_INIT(imbue, _IO_default_imbue) 1604 }; 1605 INTVARDEF(_IO_file_jumps) 1606 1607 #ifdef HAVE_MMAP 1608 struct _IO_jump_t _IO_file_jumps_mmap = 1609 { 1610 JUMP_INIT_DUMMY, 1611 JUMP_INIT(finish, INTUSE(_IO_file_finish)), 1612 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), 1613 JUMP_INIT(underflow, _IO_file_underflow_mmap), 1614 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), 1615 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), 1616 JUMP_INIT(xsputn, _IO_new_file_xsputn), 1617 JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap), 1618 JUMP_INIT(seekoff, _IO_file_seekoff_mmap), 1619 JUMP_INIT(seekpos, _IO_default_seekpos), 1620 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), 1621 JUMP_INIT(sync, _IO_file_sync_mmap), 1622 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), 1623 JUMP_INIT(read, INTUSE(_IO_file_read)), 1624 JUMP_INIT(write, _IO_new_file_write), 1625 JUMP_INIT(seek, INTUSE(_IO_file_seek)), 1626 JUMP_INIT(close, _IO_file_close_mmap), 1627 JUMP_INIT(stat, INTUSE(_IO_file_stat)), 1628 JUMP_INIT(showmanyc, _IO_default_showmanyc), 1629 JUMP_INIT(imbue, _IO_default_imbue) 1630 }; 1631 1632 struct _IO_jump_t _IO_file_jumps_maybe_mmap = 1633 { 1634 JUMP_INIT_DUMMY, 1635 JUMP_INIT(finish, INTUSE(_IO_file_finish)), 1636 JUMP_INIT(overflow, INTUSE(_IO_file_overflow)), 1637 JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap), 1638 JUMP_INIT(uflow, INTUSE(_IO_default_uflow)), 1639 JUMP_INIT(pbackfail, INTUSE(_IO_default_pbackfail)), 1640 JUMP_INIT(xsputn, _IO_new_file_xsputn), 1641 JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap), 1642 JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap), 1643 JUMP_INIT(seekpos, _IO_default_seekpos), 1644 JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), 1645 JUMP_INIT(sync, _IO_new_file_sync), 1646 JUMP_INIT(doallocate, INTUSE(_IO_file_doallocate)), 1647 JUMP_INIT(read, INTUSE(_IO_file_read)), 1648 JUMP_INIT(write, _IO_new_file_write), 1649 JUMP_INIT(seek, INTUSE(_IO_file_seek)), 1650 JUMP_INIT(close, _IO_file_close), 1651 JUMP_INIT(stat, INTUSE(_IO_file_stat)), 1652 JUMP_INIT(showmanyc, _IO_default_showmanyc), 1653 JUMP_INIT(imbue, _IO_default_imbue) 1654 }; 1655 #endif /* HAVE_MMAP */ 1656