Mercurial > dropbear
comparison common-channel.c @ 1075:cc6116cc0b5c
Avoid channel writev() when there is nothing to write
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 21 Mar 2015 22:43:08 +0800 |
parents | 10f198d4a308 |
children | acf444bcb115 |
comparison
equal
deleted
inserted
replaced
1074:10f198d4a308 | 1075:cc6116cc0b5c |
---|---|
471 iov[io_count].iov_base = (void*)moredata; | 471 iov[io_count].iov_base = (void*)moredata; |
472 iov[io_count].iov_len = *morelen; | 472 iov[io_count].iov_len = *morelen; |
473 io_count++; | 473 io_count++; |
474 } | 474 } |
475 | 475 |
476 if (io_count == 0) { | |
477 /* writechannel may sometimes be called twice in a main loop iteration. | |
478 From common_recv_msg_channel_data() then channelio(). | |
479 The second call may not have any data to write, so we just return. */ | |
480 TRACE(("leave writechannel, no data")) | |
481 return; | |
482 } | |
483 | |
476 if (morelen) { | 484 if (morelen) { |
477 /* Default return value, none consumed */ | 485 /* Default return value, none consumed */ |
478 *morelen = 0; | 486 *morelen = 0; |
479 } | 487 } |
480 | 488 |
481 written = writev(fd, iov, io_count); | 489 written = writev(fd, iov, io_count); |
482 | 490 |
483 if (written < 0) { | 491 if (written < 0) { |
484 if (errno != EINTR && errno != EAGAIN) { | 492 if (errno != EINTR && errno != EAGAIN) { |
485 TRACE(("errno %d", errno)) | 493 TRACE(("channel IO write error fd %d %s", fd, strerror(errno))) |
486 close_chan_fd(channel, fd, SHUT_WR); | 494 close_chan_fd(channel, fd, SHUT_WR); |
487 } | 495 } |
488 } else { | 496 } else { |
489 int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written); | 497 int cbuf_written = MIN(circ_len1+circ_len2, (unsigned int)written); |
490 cbuf_incrread(cbuf, cbuf_written); | 498 cbuf_incrread(cbuf, cbuf_written); |
828 | 836 |
829 dropbear_assert(channel->recvwindow >= datalen); | 837 dropbear_assert(channel->recvwindow >= datalen); |
830 channel->recvwindow -= datalen; | 838 channel->recvwindow -= datalen; |
831 dropbear_assert(channel->recvwindow <= opts.recv_window); | 839 dropbear_assert(channel->recvwindow <= opts.recv_window); |
832 | 840 |
841 /* Attempt to write the data immediately without having to put it in the circular buffer */ | |
833 consumed = datalen; | 842 consumed = datalen; |
834 writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed); | 843 writechannel(channel, fd, cbuf, buf_getptr(ses.payload, datalen), &consumed); |
835 | 844 |
836 datalen -= consumed; | 845 datalen -= consumed; |
837 buf_incrpos(ses.payload, consumed); | 846 buf_incrpos(ses.payload, consumed); |