Rev 4541 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4541 | Rev 4590 | ||
|---|---|---|---|
| Line 178... | Line 178... | ||
| 178 | stream->buf = buf; |
178 | stream->buf = buf; |
| 179 | stream->buf_size = size; |
179 | stream->buf_size = size; |
| 180 | stream->buf_head = stream->buf; |
180 | stream->buf_head = stream->buf; |
| 181 | } |
181 | } |
| 182 | 182 | ||
| - | 183 | static void _setvbuf(FILE *stream) |
|
| - | 184 | { |
|
| - | 185 | /* FIXME: Use more complex rules for setting buffering options. */ |
|
| - | 186 | ||
| - | 187 | switch (stream->fd) { |
|
| - | 188 | case 1: |
|
| - | 189 | setvbuf(stream, NULL, _IOLBF, BUFSIZ); |
|
| - | 190 | break; |
|
| - | 191 | case 0: |
|
| - | 192 | case 2: |
|
| - | 193 | setvbuf(stream, NULL, _IONBF, 0); |
|
| - | 194 | break; |
|
| - | 195 | default: |
|
| - | 196 | setvbuf(stream, NULL, _IOFBF, BUFSIZ); |
|
| - | 197 | } |
|
| - | 198 | } |
|
| - | 199 | ||
| 183 | /** Allocate stream buffer. */ |
200 | /** Allocate stream buffer. */ |
| 184 | static int _fallocbuf(FILE *stream) |
201 | static int _fallocbuf(FILE *stream) |
| 185 | { |
202 | { |
| 186 | assert(stream->buf == NULL); |
203 | assert(stream->buf == NULL); |
| 187 | 204 | ||
| 188 | stream->buf = malloc(stream->buf_size); |
205 | stream->buf = malloc(stream->buf_size); |
| 189 | if (stream->buf == NULL) { |
206 | if (stream->buf == NULL) { |
| 190 | errno = ENOMEM; |
207 | errno = ENOMEM; |
| 191 | return -1; |
208 | return -1; |
| 192 | } |
209 | } |
| 193 | 210 | ||
| 194 | stream->buf_head = stream->buf; |
211 | stream->buf_head = stream->buf; |
| 195 | return 0; |
212 | return 0; |
| 196 | } |
213 | } |
| 197 | 214 | ||
| 198 | /** Open a stream. |
215 | /** Open a stream. |
| Line 223... | Line 240... | ||
| 223 | 240 | ||
| 224 | stream->error = false; |
241 | stream->error = false; |
| 225 | stream->eof = false; |
242 | stream->eof = false; |
| 226 | stream->klog = false; |
243 | stream->klog = false; |
| 227 | stream->phone = -1; |
244 | stream->phone = -1; |
| 228 | - | ||
| 229 | /* FIXME: Should select buffering type based on what was opened. */ |
- | |
| 230 | setvbuf(stream, NULL, _IOFBF, BUFSIZ); |
245 | _setvbuf(stream); |
| 231 | 246 | ||
| 232 | list_append(&stream->link, &files); |
247 | list_append(&stream->link, &files); |
| 233 | 248 | ||
| 234 | return stream; |
249 | return stream; |
| 235 | } |
250 | } |
| Line 246... | Line 261... | ||
| 246 | stream->fd = fd; |
261 | stream->fd = fd; |
| 247 | stream->error = false; |
262 | stream->error = false; |
| 248 | stream->eof = false; |
263 | stream->eof = false; |
| 249 | stream->klog = false; |
264 | stream->klog = false; |
| 250 | stream->phone = -1; |
265 | stream->phone = -1; |
| 251 | - | ||
| 252 | /* FIXME: Should select buffering type based on what was opened. */ |
- | |
| 253 | setvbuf(stream, NULL, _IOLBF, BUFSIZ); |
266 | _setvbuf(stream); |
| 254 | 267 | ||
| 255 | list_append(&stream->link, &files); |
268 | list_append(&stream->link, &files); |
| 256 | 269 | ||
| 257 | return stream; |
270 | return stream; |
| 258 | } |
271 | } |
| Line 279... | Line 292... | ||
| 279 | 292 | ||
| 280 | stream->error = false; |
293 | stream->error = false; |
| 281 | stream->eof = false; |
294 | stream->eof = false; |
| 282 | stream->klog = false; |
295 | stream->klog = false; |
| 283 | stream->phone = -1; |
296 | stream->phone = -1; |
| 284 | - | ||
| 285 | /* FIXME: Should select buffering type based on what was opened. */ |
- | |
| 286 | setvbuf(stream, NULL, _IOLBF, BUFSIZ); |
297 | _setvbuf(stream); |
| 287 | 298 | ||
| 288 | list_append(&stream->link, &files); |
299 | list_append(&stream->link, &files); |
| 289 | 300 | ||
| 290 | return stream; |
301 | return stream; |
| 291 | } |
302 | } |
| Line 329... | Line 340... | ||
| 329 | */ |
340 | */ |
| 330 | 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) |
| 331 | { |
342 | { |
| 332 | size_t left = size * nmemb; |
343 | size_t left = size * nmemb; |
| 333 | size_t done = 0; |
344 | size_t done = 0; |
| 334 | 345 | ||
| 335 | /* Make sure no data is pending write. */ |
346 | /* Make sure no data is pending write. */ |
| 336 | _fflushbuf(stream); |
347 | _fflushbuf(stream); |
| 337 | 348 | ||
| 338 | while ((left > 0) && (!stream->error) && (!stream->eof)) { |
349 | while ((left > 0) && (!stream->error) && (!stream->eof)) { |
| 339 | ssize_t rd = read(stream->fd, buf + done, left); |
350 | ssize_t rd = read(stream->fd, buf + done, left); |
| 340 | 351 | ||
| 341 | if (rd < 0) |
352 | if (rd < 0) |
| 342 | stream->error = true; |
353 | stream->error = true; |
| Line 377... | Line 388... | ||
| 377 | 388 | ||
| 378 | /** Drain stream buffer, do not sync stream. */ |
389 | /** Drain stream buffer, do not sync stream. */ |
| 379 | static void _fflushbuf(FILE *stream) |
390 | static void _fflushbuf(FILE *stream) |
| 380 | { |
391 | { |
| 381 | size_t bytes_used; |
392 | size_t bytes_used; |
| 382 | 393 | ||
| 383 | if (!stream->buf || stream->btype == _IONBF || stream->error) |
394 | if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error)) |
| 384 | return; |
395 | return; |
| 385 | 396 | ||
| 386 | bytes_used = stream->buf_head - stream->buf; |
397 | bytes_used = stream->buf_head - stream->buf; |
| 387 | if (bytes_used == 0) |
398 | if (bytes_used == 0) |
| 388 | return; |
399 | return; |
| 389 | 400 | ||
| 390 | (void) _fwrite(stream->buf, 1, bytes_used, stream); |
401 | (void) _fwrite(stream->buf, 1, bytes_used, stream); |
| 391 | stream->buf_head = stream->buf; |
402 | stream->buf_head = stream->buf; |
| 392 | } |
403 | } |
| 393 | 404 | ||
| 394 | /** Write to a stream. |
405 | /** Write to a stream. |
| Line 407... | Line 418... | ||
| 407 | size_t buf_free; |
418 | size_t buf_free; |
| 408 | size_t total_written; |
419 | size_t total_written; |
| 409 | size_t i; |
420 | size_t i; |
| 410 | uint8_t b; |
421 | uint8_t b; |
| 411 | bool need_flush; |
422 | bool need_flush; |
| 412 | 423 | ||
| 413 | /* If not buffered stream, write out directly. */ |
424 | /* If not buffered stream, write out directly. */ |
| 414 | if (stream->btype == _IONBF) |
425 | if (stream->btype == _IONBF) { |
| 415 | return _fwrite(buf, size, nmemb, stream); |
426 | now = _fwrite(buf, size, nmemb, stream); |
| - | 427 | fflush(stream); |
|
| - | 428 | return now; |
|
| - | 429 | } |
|
| 416 | 430 | ||
| 417 | /* Perform lazy allocation of stream buffer. */ |
431 | /* Perform lazy allocation of stream buffer. */ |
| 418 | if (stream->buf == NULL) { |
432 | if (stream->buf == NULL) { |
| 419 | if (_fallocbuf(stream) != 0) |
433 | if (_fallocbuf(stream) != 0) |
| 420 | return 0; /* Errno set by _fallocbuf(). */ |
434 | return 0; /* Errno set by _fallocbuf(). */ |
| 421 | } |
435 | } |
| 422 | 436 | ||
| 423 | data = (uint8_t *) buf; |
437 | data = (uint8_t *) buf; |
| 424 | bytes_left = size * nmemb; |
438 | bytes_left = size * nmemb; |
| 425 | total_written = 0; |
439 | total_written = 0; |
| 426 | need_flush = false; |
440 | need_flush = false; |
| 427 | 441 | ||
| 428 | while (!stream->error && bytes_left > 0) { |
442 | while ((!stream->error) && (bytes_left > 0)) { |
| 429 | - | ||
| 430 | buf_free = stream->buf_size - (stream->buf_head - stream->buf); |
443 | buf_free = stream->buf_size - (stream->buf_head - stream->buf); |
| 431 | if (bytes_left > buf_free) |
444 | if (bytes_left > buf_free) |
| 432 | now = buf_free; |
445 | now = buf_free; |
| 433 | else |
446 | else |
| 434 | now = bytes_left; |
447 | now = bytes_left; |
| 435 | 448 | ||
| 436 | for (i = 0; i < now; i++) { |
449 | for (i = 0; i < now; i++) { |
| 437 | b = data[i]; |
450 | b = data[i]; |
| 438 | stream->buf_head[i] = b; |
451 | stream->buf_head[i] = b; |
| 439 | 452 | ||
| 440 | if (b == '\n' && stream->btype == _IOLBF) |
453 | if ((b == '\n') && (stream->btype == _IOLBF)) |
| 441 | need_flush = true; |
454 | need_flush = true; |
| 442 | } |
455 | } |
| 443 | 456 | ||
| 444 | buf += now; |
457 | buf += now; |
| 445 | stream->buf_head += now; |
458 | stream->buf_head += now; |
| 446 | buf_free -= now; |
459 | buf_free -= now; |
| 447 | bytes_left -= now; |
460 | bytes_left -= now; |
| 448 | total_written += now; |
461 | total_written += now; |
| 449 | 462 | ||
| 450 | if (buf_free == 0) { |
463 | if (buf_free == 0) { |
| 451 | /* Only need to drain buffer. */ |
464 | /* Only need to drain buffer. */ |
| 452 | _fflushbuf(stream); |
465 | _fflushbuf(stream); |
| 453 | need_flush = false; |
466 | need_flush = false; |
| 454 | } |
467 | } |
| 455 | } |
468 | } |
| 456 | 469 | ||
| 457 | if (need_flush) |
470 | if (need_flush) |
| 458 | fflush(stream); |
471 | fflush(stream); |
| 459 | 472 | ||
| 460 | return (total_written / size); |
473 | return (total_written / size); |
| 461 | } |
474 | } |
| 462 | 475 | ||
| 463 | int fputc(wchar_t c, FILE *stream) |
476 | int fputc(wchar_t c, FILE *stream) |
| 464 | { |
477 | { |
| Line 493... | Line 506... | ||
| 493 | } |
506 | } |
| 494 | 507 | ||
| 495 | int fgetc(FILE *stream) |
508 | int fgetc(FILE *stream) |
| 496 | { |
509 | { |
| 497 | char c; |
510 | char c; |
| 498 | 511 | ||
| 499 | /* This could be made faster by only flushing when needed. */ |
512 | /* This could be made faster by only flushing when needed. */ |
| 500 | if (stdout) |
513 | if (stdout) |
| 501 | fflush(stdout); |
514 | fflush(stdout); |
| 502 | if (stderr) |
515 | if (stderr) |
| 503 | fflush(stderr); |
516 | fflush(stderr); |
| 504 | 517 | ||
| 505 | if (fread(&c, sizeof(char), 1, stream) < sizeof(char)) |
518 | if (fread(&c, sizeof(char), 1, stream) < sizeof(char)) |
| 506 | return EOF; |
519 | return EOF; |
| 507 | 520 | ||
| 508 | return (int) c; |
521 | return (int) c; |
| 509 | } |
522 | } |
| Line 532... | Line 545... | ||
| 532 | } |
545 | } |
| 533 | 546 | ||
| 534 | int fflush(FILE *stream) |
547 | int fflush(FILE *stream) |
| 535 | { |
548 | { |
| 536 | _fflushbuf(stream); |
549 | _fflushbuf(stream); |
| 537 | 550 | ||
| 538 | if (stream->klog) { |
551 | if (stream->klog) { |
| 539 | klog_update(); |
552 | klog_update(); |
| 540 | return EOK; |
553 | return EOK; |
| 541 | } |
554 | } |
| 542 | 555 | ||