comparison common-channel.c @ 1077:26c1f9b8f82e coverity

merge main
author Matt Johnston <matt@ucc.asn.au>
date Tue, 14 Apr 2015 20:44:30 +0800
parents cc6116cc0b5c
children acf444bcb115
comparison
equal deleted inserted replaced
1062:210982935887 1077:26c1f9b8f82e
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 len %d", errno, len)) 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);
529 TRACE(("leave writechannel")) 537 TRACE(("leave writechannel"))
530 } 538 }
531 539
532 /* Set the file descriptors for the main select in session.c 540 /* Set the file descriptors for the main select in session.c
533 * This avoid channels which don't have any window available, are closed, etc*/ 541 * This avoid channels which don't have any window available, are closed, etc*/
534 void setchannelfds(fd_set *readfds, fd_set *writefds) { 542 void setchannelfds(fd_set *readfds, fd_set *writefds, int allow_reads) {
535 543
536 unsigned int i; 544 unsigned int i;
537 struct Channel * channel; 545 struct Channel * channel;
538 546
539 for (i = 0; i < ses.chansize; i++) { 547 for (i = 0; i < ses.chansize; i++) {
547 Avoid queueing data to send if we're in the middle of a 555 Avoid queueing data to send if we're in the middle of a
548 key re-exchange (!dataallowed), but still read from the 556 key re-exchange (!dataallowed), but still read from the
549 FD if there's the possibility of "~."" to kill an 557 FD if there's the possibility of "~."" to kill an
550 interactive session (the read_mangler) */ 558 interactive session (the read_mangler) */
551 if (channel->transwindow > 0 559 if (channel->transwindow > 0
552 && (ses.dataallowed || channel->read_mangler)) { 560 && ((ses.dataallowed && allow_reads) || channel->read_mangler)) {
553 561
554 if (channel->readfd >= 0) { 562 if (channel->readfd >= 0) {
555 FD_SET(channel->readfd, readfds); 563 FD_SET(channel->readfd, readfds);
556 } 564 }
557 565
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);