Changeset ef8bcc6 in mainline for uspace/lib/libc/generic/io/io.c
- Timestamp:
- 2009-06-15T21:46:21Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 953769f
- Parents:
- c07af37
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/io/io.c
rc07af37 ref8bcc6 36 36 #include <unistd.h> 37 37 #include <fcntl.h> 38 #include <assert.h> 38 39 #include <string.h> 39 40 #include <errno.h> … … 45 46 #include <adt/list.h> 46 47 48 static void _fflushbuf(FILE *stream); 49 47 50 static FILE stdin_null = { 48 51 .fd = -1, … … 50 53 .eof = true, 51 54 .klog = false, 52 .phone = -1 55 .phone = -1, 56 .btype = _IONBF, 57 .buf = NULL, 58 .buf_size = 0, 59 .buf_head = NULL 53 60 }; 54 61 … … 58 65 .eof = false, 59 66 .klog = true, 60 .phone = -1 67 .phone = -1, 68 .btype = _IOLBF, 69 .buf = NULL, 70 .buf_size = BUFSIZ, 71 .buf_head = NULL 61 72 }; 62 73 … … 66 77 .eof = false, 67 78 .klog = true, 68 .phone = -1 79 .phone = -1, 80 .btype = _IONBF, 81 .buf = NULL, 82 .buf_size = 0, 83 .buf_head = NULL 69 84 }; 70 85 … … 157 172 } 158 173 174 /** Set stream buffer. */ 175 void setvbuf(FILE *stream, void *buf, int mode, size_t size) 176 { 177 stream->btype = mode; 178 stream->buf = buf; 179 stream->buf_size = size; 180 stream->buf_head = stream->buf; 181 } 182 183 /** Allocate stream buffer. */ 184 static int _fallocbuf(FILE *stream) 185 { 186 assert(stream->buf == NULL); 187 188 stream->buf = malloc(stream->buf_size); 189 if (stream->buf == NULL) { 190 errno = ENOMEM; 191 return -1; 192 } 193 194 stream->buf_head = stream->buf; 195 return 0; 196 } 197 159 198 /** Open a stream. 160 199 * … … 187 226 stream->klog = false; 188 227 stream->phone = -1; 228 229 /* FIXME: Should select buffering type based on what was opened. */ 230 setvbuf(stream, NULL, _IOFBF, BUFSIZ); 189 231 190 232 list_append(&stream->link, &files); … … 207 249 stream->klog = false; 208 250 stream->phone = -1; 251 252 /* FIXME: Should select buffering type based on what was opened. */ 253 setvbuf(stream, NULL, _IOLBF, BUFSIZ); 209 254 210 255 list_append(&stream->link, &files); … … 237 282 stream->klog = false; 238 283 stream->phone = -1; 284 285 /* FIXME: Should select buffering type based on what was opened. */ 286 setvbuf(stream, NULL, _IOLBF, BUFSIZ); 239 287 240 288 list_append(&stream->link, &files); … … 284 332 size_t left = size * nmemb; 285 333 size_t done = 0; 286 334 335 /* Make sure no data is pending write. */ 336 _fflushbuf(stream); 337 287 338 while ((left > 0) && (!stream->error) && (!stream->eof)) { 288 339 ssize_t rd = read(stream->fd, buf + done, left); … … 301 352 } 302 353 303 /** Write to a stream. 304 * 305 * @param buf Source buffer. 306 * @param size Size of each record. 307 * @param nmemb Number of records to write. 308 * @param stream Pointer to the stream. 309 * 310 */ 311 size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 354 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 312 355 { 313 356 size_t left = size * nmemb; … … 333 376 } 334 377 378 /** Drain stream buffer, do not sync stream. */ 379 static void _fflushbuf(FILE *stream) 380 { 381 size_t bytes_used; 382 383 if (!stream->buf || stream->btype == _IONBF || stream->error) 384 return; 385 386 bytes_used = stream->buf_head - stream->buf; 387 if (bytes_used == 0) 388 return; 389 390 (void) _fwrite(stream->buf, 1, bytes_used, stream); 391 stream->buf_head = stream->buf; 392 } 393 394 /** Write to a stream. 395 * 396 * @param buf Source buffer. 397 * @param size Size of each record. 398 * @param nmemb Number of records to write. 399 * @param stream Pointer to the stream. 400 * 401 */ 402 size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream) 403 { 404 uint8_t *data; 405 size_t bytes_left; 406 size_t now; 407 size_t buf_free; 408 size_t total_written; 409 size_t i; 410 uint8_t b; 411 bool need_flush; 412 413 /* If not buffered stream, write out directly. */ 414 if (stream->btype == _IONBF) 415 return _fwrite(buf, size, nmemb, stream); 416 417 /* Perform lazy allocation of stream buffer. */ 418 if (stream->buf == NULL) { 419 if (_fallocbuf(stream) != 0) 420 return 0; /* Errno set by _fallocbuf(). */ 421 } 422 423 data = (uint8_t *) buf; 424 bytes_left = size * nmemb; 425 total_written = 0; 426 need_flush = false; 427 428 while (!stream->error && bytes_left > 0) { 429 430 buf_free = stream->buf_size - (stream->buf_head - stream->buf); 431 if (bytes_left > buf_free) 432 now = buf_free; 433 else 434 now = bytes_left; 435 436 for (i = 0; i < now; i++) { 437 b = data[i]; 438 stream->buf_head[i] = b; 439 440 if (b == '\n' && stream->btype == _IOLBF) 441 need_flush = true; 442 } 443 444 buf += now; 445 stream->buf_head += now; 446 buf_free -= now; 447 bytes_left -= now; 448 total_written += now; 449 450 if (buf_free == 0) { 451 /* Only need to drain buffer. */ 452 _fflushbuf(stream); 453 need_flush = false; 454 } 455 } 456 457 if (need_flush) 458 fflush(stream); 459 460 return (total_written / size); 461 } 462 335 463 int fputc(wchar_t c, FILE *stream) 336 464 { … … 406 534 int fflush(FILE *stream) 407 535 { 536 _fflushbuf(stream); 537 408 538 if (stream->klog) { 409 539 klog_update();
Note:
See TracChangeset
for help on using the changeset viewer.