Changes in / [2070570:5782081] in mainline
- Location:
- uspace/lib/libc
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/io/io.c
r2070570 r5782081 46 46 #include <adt/list.h> 47 47 48 static void _ffillbuf(FILE *stream);49 48 static void _fflushbuf(FILE *stream); 50 49 … … 58 57 .buf = NULL, 59 58 .buf_size = 0, 60 .buf_head = NULL, 61 .buf_tail = NULL, 62 .buf_state = _bs_empty 59 .buf_head = NULL 63 60 }; 64 61 … … 72 69 .buf = NULL, 73 70 .buf_size = BUFSIZ, 74 .buf_head = NULL, 75 .buf_tail = NULL, 76 .buf_state = _bs_empty 71 .buf_head = NULL 77 72 }; 78 73 … … 86 81 .buf = NULL, 87 82 .buf_size = 0, 88 .buf_head = NULL, 89 .buf_tail = NULL, 90 .buf_state = _bs_empty 83 .buf_head = NULL 91 84 }; 92 85 … … 186 179 stream->buf_size = size; 187 180 stream->buf_head = stream->buf; 188 stream->buf_tail = stream->buf;189 stream->buf_state = _bs_empty;190 181 } 191 182 … … 219 210 220 211 stream->buf_head = stream->buf; 221 stream->buf_tail = stream->buf;222 212 return 0; 223 213 } … … 253 243 stream->klog = false; 254 244 stream->phone = -1; 255 stream->need_sync = false;256 245 _setvbuf(stream); 257 246 … … 275 264 stream->klog = false; 276 265 stream->phone = -1; 277 stream->need_sync = false;278 266 _setvbuf(stream); 279 267 … … 307 295 stream->klog = false; 308 296 stream->phone = -1; 309 stream->need_sync = false;310 297 _setvbuf(stream); 311 298 … … 344 331 } 345 332 346 /** Read from a stream (unbuffered).333 /** Read from a stream. 347 334 * 348 335 * @param buf Destination buffer. … … 350 337 * @param nmemb Number of records to read. 351 338 * @param stream Pointer to the stream. 339 * 352 340 */ 353 s tatic size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream) 354 342 { 355 343 size_t left, done; … … 357 345 if (size == 0 || nmemb == 0) 358 346 return 0; 347 348 /* Make sure no data is pending write. */ 349 _fflushbuf(stream); 359 350 360 351 left = size * nmemb; … … 377 368 } 378 369 379 /** Write to a stream (unbuffered).380 *381 * @param buf Source buffer.382 * @param size Size of each record.383 * @param nmemb Number of records to write.384 * @param stream Pointer to the stream.385 */386 370 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 387 371 { … … 410 394 } 411 395 } 412 413 if (done > 0)414 stream->need_sync = true;415 396 416 397 return (done / size); 417 398 } 418 399 419 /** Read some data in stream buffer. */ 420 static void _ffillbuf(FILE *stream) 421 { 422 ssize_t rc; 423 424 stream->buf_head = stream->buf_tail = stream->buf; 425 426 rc = read(stream->fd, stream->buf, stream->buf_size); 427 if (rc < 0) { 428 stream->error = true; 429 return; 430 } 431 432 if (rc == 0) { 433 stream->eof = true; 434 return; 435 } 436 437 stream->buf_head += rc; 438 stream->buf_state = _bs_read; 439 } 440 441 /** Write out stream buffer, do not sync stream. */ 400 /** Drain stream buffer, do not sync stream. */ 442 401 static void _fflushbuf(FILE *stream) 443 402 { 444 403 size_t bytes_used; 445 404 446 405 if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error)) 447 406 return; 448 449 bytes_used = stream->buf_head - stream->buf _tail;407 408 bytes_used = stream->buf_head - stream->buf; 450 409 if (bytes_used == 0) 451 410 return; 452 453 /* If buffer has prefetched read data, we need to seek back. */ 454 if (stream->buf_state == _bs_read) 455 lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR); 456 457 /* If buffer has unwritten data, we need to write them out. */ 458 if (stream->buf_state == _bs_write) 459 (void) _fwrite(stream->buf_tail, 1, bytes_used, stream); 460 411 412 (void) _fwrite(stream->buf, 1, bytes_used, stream); 461 413 stream->buf_head = stream->buf; 462 stream->buf_tail = stream->buf; 463 stream->buf_state = _bs_empty; 464 } 465 466 /** Read from a stream. 467 * 468 * @param dest Destination buffer. 469 * @param size Size of each record. 470 * @param nmemb Number of records to read. 471 * @param stream Pointer to the stream. 472 * 473 */ 474 size_t fread(void *dest, size_t size, size_t nmemb, FILE *stream) 475 { 476 uint8_t *dp; 477 size_t bytes_left; 478 size_t now; 479 size_t data_avail; 480 size_t total_read; 481 size_t i; 482 483 if (size == 0 || nmemb == 0) 484 return 0; 485 486 /* If not buffered stream, read in directly. */ 487 if (stream->btype == _IONBF) { 488 now = _fread(dest, size, nmemb, stream); 489 return now; 490 } 491 492 /* Make sure no data is pending write. */ 493 if (stream->buf_state == _bs_write) 494 _fflushbuf(stream); 495 496 /* Perform lazy allocation of stream buffer. */ 497 if (stream->buf == NULL) { 498 if (_fallocbuf(stream) != 0) 499 return 0; /* Errno set by _fallocbuf(). */ 500 } 501 502 bytes_left = size * nmemb; 503 total_read = 0; 504 dp = (uint8_t *) dest; 505 506 while ((!stream->error) && (!stream->eof) && (bytes_left > 0)) { 507 if (stream->buf_head == stream->buf_tail) 508 _ffillbuf(stream); 509 510 if (stream->error || stream->eof) 511 break; 512 513 data_avail = stream->buf_head - stream->buf_tail; 514 515 if (bytes_left > data_avail) 516 now = data_avail; 517 else 518 now = bytes_left; 519 520 for (i = 0; i < now; i++) { 521 dp[i] = stream->buf_tail[i]; 522 } 523 524 dp += now; 525 stream->buf_tail += now; 526 bytes_left -= now; 527 total_read += now; 528 } 529 530 return (total_read / size); 531 } 532 414 } 533 415 534 416 /** Write to a stream. … … 560 442 return now; 561 443 } 562 563 /* Make sure buffer contains no prefetched data. */ 564 if (stream->buf_state == _bs_read) 565 _fflushbuf(stream); 566 567 444 568 445 /* Perform lazy allocation of stream buffer. */ 569 446 if (stream->buf == NULL) { … … 605 482 } 606 483 607 if (total_written > 0)608 stream->buf_state = _bs_write;609 610 484 if (need_flush) 611 485 fflush(stream); … … 696 570 int fseek(FILE *stream, off64_t offset, int whence) 697 571 { 698 off64_t rc; 699 700 _fflushbuf(stream); 701 702 rc = lseek(stream->fd, offset, whence); 572 off64_t rc = lseek(stream->fd, offset, whence); 703 573 if (rc == (off64_t) (-1)) { 704 574 /* errno has been set by lseek64. */ 705 575 return -1; 706 576 } 707 577 708 578 stream->eof = false; 579 709 580 return 0; 710 581 } … … 729 600 } 730 601 731 if (stream->fd >= 0 && stream->need_sync) { 732 /** 733 * Better than syncing always, but probably still not the 734 * right thing to do. 735 */ 736 stream->need_sync = false; 602 if (stream->fd >= 0) 737 603 return fsync(stream->fd); 738 }739 604 740 605 return ENOENT; -
uspace/lib/libc/include/stdio.h
r2070570 r5782081 75 75 }; 76 76 77 enum _buffer_state {78 /** Buffer is empty */79 _bs_empty,80 81 /** Buffer contains data to be written */82 _bs_write,83 84 /** Buffer contains prefetched data for reading */85 _bs_read86 };87 88 77 typedef struct { 89 78 /** Linked list pointer. */ … … 105 94 int phone; 106 95 107 /**108 * Non-zero if the stream needs sync on fflush(). XXX change109 * console semantics so that sync is not needed.110 */111 int need_sync;112 113 96 /** Buffering type */ 114 97 enum _buffer_type btype; 115 116 98 /** Buffer */ 117 99 uint8_t *buf; 118 119 100 /** Buffer size */ 120 101 size_t buf_size; 121 122 /** Buffer state */123 enum _buffer_state buf_state;124 125 102 /** Buffer I/O pointer */ 126 103 uint8_t *buf_head; 127 128 /** Points to end of occupied space when in read mode. */129 uint8_t *buf_tail;130 104 } FILE; 131 105
Note:
See TracChangeset
for help on using the changeset viewer.