if (DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, outroom) needs to flush %ld\n",
who_am_i(), (long)needed,
- iobuf.out.len > iobuf.out.size - needed
- ? (long)iobuf.out.len - (iobuf.out.size - needed) : 0L);
+ iobuf.out.len + needed > iobuf.out.size
+ ? (long)(iobuf.out.len + needed - iobuf.out.size) : 0L);
}
break;
if (DEBUG_GTE(IO, 3)) {
rprintf(FINFO, "[%s] perform_io(%ld, msgroom) needs to flush %ld\n",
who_am_i(), (long)needed,
- iobuf.out.len > iobuf.msg.size - needed
- ? (long)iobuf.out.len - (iobuf.msg.size - needed) : 0L);
+ iobuf.msg.len + needed > iobuf.msg.size
+ ? (long)(iobuf.msg.len + needed - iobuf.msg.size) : 0L);
}
break;
goto double_break;
break;
case PIO_NEED_OUTROOM:
- if (iobuf.out.len <= iobuf.out.size - needed)
+ /* Note that iobuf.out_empty_len doesn't factor into this check
+ * because iobuf.out.len already holds any needed header len. */
+ if (iobuf.out.len + needed <= iobuf.out.size)
goto double_break;
break;
case PIO_NEED_MSGROOM:
- if (iobuf.msg.len <= iobuf.msg.size - needed)
+ if (iobuf.msg.len + needed <= iobuf.msg.size)
goto double_break;
break;
}
if (iobuf.raw_flushing_ends_before
|| (!iobuf.msg.len && iobuf.out.len > iobuf.out_empty_len && !(flags & PIO_NEED_MSGROOM))) {
if (OUT_MULTIPLEXED && !iobuf.raw_flushing_ends_before) {
- size_t val;
-
/* The iobuf.raw_flushing_ends_before value can point off the end
* of the iobuf.out buffer for a while, for easier subtracting. */
iobuf.raw_flushing_ends_before = iobuf.out.pos + iobuf.out.len;
SIVAL(iobuf.out.buf + iobuf.raw_data_header_pos, 0,
((MPLEX_BASE + (int)MSG_DATA)<<24) + iobuf.out.len - 4);
- if ((val = iobuf.out.size - iobuf.raw_data_header_pos) < 4) {
+ if (iobuf.raw_data_header_pos + 4 > iobuf.out.size) {
+ int siz = (int)(iobuf.raw_data_header_pos + 4 - iobuf.out.size);
/* We used some of the overflow bytes, so move them. */
if (DEBUG_GTE(IO, 4)) {
rprintf(FINFO, "[%s] wrap-bytes moved: %d (perform_io)\n",
- who_am_i(), (int)val);
+ who_am_i(), siz);
}
- memcpy(iobuf.out.buf, iobuf.out.buf + iobuf.out.size, 4 - val);
+ memcpy(iobuf.out.buf, iobuf.out.buf + iobuf.out.size, siz);
}
if (DEBUG_GTE(IO, 1)) {
}
if (extra_flist_sending_enabled) {
- if (file_total - file_old_total < MAX_FILECNT_LOOKAHEAD
- && file_total - file_old_total >= MIN_FILECNT_LOOKAHEAD)
+ if (file_total - file_old_total < MAX_FILECNT_LOOKAHEAD)
tv.tv_sec = 0;
else {
extra_flist_sending_enabled = False;
if (iobuf.raw_flushing_ends_before)
iobuf.raw_flushing_ends_before -= out->size;
out->pos = 0;
- }
- if (out->pos == iobuf.raw_flushing_ends_before)
+ } else if (out->pos == iobuf.raw_flushing_ends_before)
iobuf.raw_flushing_ends_before = 0;
if ((out->len -= n) == empty_buf_len) {
out->pos = 0;
char buf[1024];
kluge_around_eof = 1;
- set_io_timeout(protocol_version >= 31 ? 10 : 1);
+ /* For protocol 31: setting an I/O timeout ensures that if something
+ * inexplicably weird happens, we won't hang around forever. For older
+ * protocols: we can't tell the other side to die, so we linger a brief
+ * time (to try to give our error messages time to arrive) and then let
+ * the "unexpectedly" closed socket tell them to die. */
+ set_io_timeout(protocol_version >= 31 ? 30 : 1);
while (1)
read_buf(iobuf.in_fd, buf, sizeof buf);
if (convert > 0 && ic_send == (iconv_t)-1)
convert = 0;
if (convert > 0) {
- /* Ensuring double-size room leaves space for a potential conversion. */
+ /* Ensuring double-size room leaves space for maximal conversion expansion. */
if (iobuf.msg.len + len*2 + 4 > iobuf.msg.size)
perform_io(len*2 + 4, PIO_NEED_MSGROOM);
} else
pos -= iobuf.msg.size;
hdr = iobuf.msg.buf + pos;
- iobuf.msg.len += 4; /* Leave room for the coming header bytes. */
+ iobuf.msg.len += 4; /* Allocate room for the coming header bytes. */
#ifdef ICONV_OPTION
if (convert > 0) {
SIVAL(hdr, 0, ((MPLEX_BASE + (int)code)<<24) + len);
/* If the header used any overflow bytes, move them to the start. */
if ((pos = hdr+4 - iobuf.msg.buf) > iobuf.msg.size) {
- size_t siz = pos - iobuf.msg.size;
+ int siz = (int)(pos - iobuf.msg.size);
if (DEBUG_GTE(IO, 4))
- rprintf(FINFO, "[%s] wrap-bytes moved: %d (send_msg)\n", who_am_i(), (int)siz);
- memcpy(iobuf.msg.buf, hdr+4 - siz, siz);
+ rprintf(FINFO, "[%s] wrap-bytes moved: %d (send_msg)\n", who_am_i(), siz);
+ memcpy(iobuf.msg.buf, iobuf.msg.buf + iobuf.msg.size, siz);
}
if (want_debug && convert > 0)
if (iobuf.out.buf) {
if (iobuf.out_fd == -1)
iobuf.out_fd = f_out;
- assert(f_out == iobuf.out_fd);
+ else
+ assert(f_out == iobuf.out_fd);
return False;
}
if (iobuf.in.buf) {
if (iobuf.in_fd == -1)
iobuf.in_fd = f_in;
- assert(f_in == iobuf.in_fd);
+ else
+ assert(f_in == iobuf.in_fd);
return False;
}
if (msg_bytes != 4 || am_sender)
goto invalid_msg;
data = perform_io(4, PIO_INPUT_AND_CONSUME);
- io_error |= IVAL(data, 0);
+ val = IVAL(data, 0);
+ io_error |= val;
if (!am_generator)
- send_msg(MSG_IO_ERROR, data, 4, 0);
+ send_msg_int(MSG_IO_ERROR, val);
break;
case MSG_IO_TIMEOUT:
if (msg_bytes != 4 || am_server || am_generator)
exit_cleanup(RERR_STREAMIO);
}
data = perform_io(4, PIO_INPUT_AND_CONSUME);
+ val = IVAL(data, 0);
if (am_generator)
- got_flist_entry_status(FES_SUCCESS, IVAL(data, 0));
+ got_flist_entry_status(FES_SUCCESS, val);
else
- successful_send(IVAL(data, 0));
+ successful_send(val);
break;
case MSG_NO_SEND:
if (msg_bytes != 4)
goto invalid_msg;
data = perform_io(4, PIO_INPUT_AND_CONSUME);
+ val = IVAL(data, 0);
if (am_generator)
- got_flist_entry_status(FES_NO_SEND, IVAL(data, 0));
+ got_flist_entry_status(FES_NO_SEND, val);
else
- send_msg(MSG_NO_SEND, data, 4, 0);
+ send_msg_int(MSG_NO_SEND, val);
break;
case MSG_ERROR_SOCKET:
case MSG_ERROR_UTF8: