Perform buffered input and/or output until specified conditions are met. * When given a "needed" read or write request, this returns without doing any * I/O if the needed input bytes or write space is already available. Once I/O * is needed, this will try to do whatever reading and/or writing is currently * possible, up to the maximum buffer allowances, no matter if this is a read * or write
| 560 | * buffer. In the old days, only raw data was in the input buffer, and any |
| 561 | * unused raw data in the buf would prevent the reading of socket data. */ |
| 562 | static char *perform_io(size_t needed, int flags) |
| 563 | { |
| 564 | fd_set r_fds, e_fds, w_fds; |
| 565 | struct timeval tv; |
| 566 | int cnt, max_fd; |
| 567 | size_t empty_buf_len = 0; |
| 568 | xbuf *out; |
| 569 | char *data; |
| 570 | |
| 571 | if (iobuf.in.len == 0 && iobuf.in.pos != 0) { |
| 572 | if (iobuf.raw_input_ends_before) |
| 573 | iobuf.raw_input_ends_before -= iobuf.in.pos; |
| 574 | iobuf.in.pos = 0; |
| 575 | } |
| 576 | |
| 577 | switch (flags & PIO_NEED_FLAGS) { |
| 578 | case PIO_NEED_INPUT: |
| 579 | /* We never resize the circular input buffer. */ |
| 580 | if (iobuf.in.size < needed) { |
| 581 | rprintf(FERROR, "need to read %" SIZE_T_FMT_MOD "d bytes," |
| 582 | " iobuf.in.buf is only %" SIZE_T_FMT_MOD "d bytes.\n", |
| 583 | (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.in.size); |
| 584 | exit_cleanup(RERR_PROTOCOL); |
| 585 | } |
| 586 | |
| 587 | if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) { |
| 588 | rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d, %sinput)\n", |
| 589 | who_am_i(), (SIZE_T_FMT_CAST)needed, flags & PIO_CONSUME_INPUT ? "consume&" : ""); |
| 590 | } |
| 591 | break; |
| 592 | |
| 593 | case PIO_NEED_OUTROOM: |
| 594 | /* We never resize the circular output buffer. */ |
| 595 | if (iobuf.out.size - iobuf.out_empty_len < needed) { |
| 596 | fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes," |
| 597 | " iobuf.out.buf is only %" SIZE_T_FMT_MOD "d bytes.\n", |
| 598 | (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)(iobuf.out.size - iobuf.out_empty_len)); |
| 599 | exit_cleanup(RERR_PROTOCOL); |
| 600 | } |
| 601 | |
| 602 | if (msgs2stderr == 1 && DEBUG_GTE(IO, 3)) { |
| 603 | rprintf(FINFO, "[%s] perform_io(%" SIZE_T_FMT_MOD "d," |
| 604 | " outroom) needs to flush %" SIZE_T_FMT_MOD "d\n", |
| 605 | who_am_i(), (SIZE_T_FMT_CAST)needed, |
| 606 | iobuf.out.len + needed > iobuf.out.size |
| 607 | ? (SIZE_T_FMT_CAST)(iobuf.out.len + needed - iobuf.out.size) : (SIZE_T_FMT_CAST)0); |
| 608 | } |
| 609 | break; |
| 610 | |
| 611 | case PIO_NEED_MSGROOM: |
| 612 | /* We never resize the circular message buffer. */ |
| 613 | if (iobuf.msg.size < needed) { |
| 614 | fprintf(stderr, "need to write %" SIZE_T_FMT_MOD "d bytes," |
| 615 | " iobuf.msg.buf is only %" SIZE_T_FMT_MOD "d bytes.\n", |
| 616 | (SIZE_T_FMT_CAST)needed, (SIZE_T_FMT_CAST)iobuf.msg.size); |
| 617 | exit_cleanup(RERR_PROTOCOL); |
| 618 | } |
| 619 |
no test coverage detected