comparison common-channel.c @ 773:a9f2a6ae4eb5

merge
author Matt Johnston <matt@ucc.asn.au>
date Sun, 14 Apr 2013 22:49:19 +0800
parents 7577a3afc42d
children 35183e8a7851
comparison
equal deleted inserted replaced
772:7fc0aeada79c 773:a9f2a6ae4eb5
271 271
272 /* EOF/close handling */ 272 /* EOF/close handling */
273 static void check_close(struct Channel *channel) { 273 static void check_close(struct Channel *channel) {
274 int close_allowed = 0; 274 int close_allowed = 0;
275 275
276 TRACE(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d", 276 TRACE2(("check_close: writefd %d, readfd %d, errfd %d, sent_close %d, recv_close %d",
277 channel->writefd, channel->readfd, 277 channel->writefd, channel->readfd,
278 channel->errfd, channel->sent_close, channel->recv_close)) 278 channel->errfd, channel->sent_close, channel->recv_close))
279 TRACE(("writebuf size %d extrabuf size %d", 279 TRACE2(("writebuf size %d extrabuf size %d",
280 channel->writebuf ? cbuf_getused(channel->writebuf) : 0, 280 channel->writebuf ? cbuf_getused(channel->writebuf) : 0,
281 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0)) 281 channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
282 282
283 if (!channel->flushing 283 if (!channel->flushing
284 && !channel->close_handler_done 284 && !channel->close_handler_done
559 TRACE(("CLOSE readfd %d", channel->readfd)) 559 TRACE(("CLOSE readfd %d", channel->readfd))
560 close(channel->readfd); 560 close(channel->readfd);
561 TRACE(("CLOSE errfd %d", channel->errfd)) 561 TRACE(("CLOSE errfd %d", channel->errfd))
562 close(channel->errfd); 562 close(channel->errfd);
563 563
564 channel->typedata = NULL; 564 if (!channel->close_handler_done
565 && channel->type->closehandler) {
566 channel->type->closehandler(channel);
567 channel->close_handler_done = 1;
568 }
565 569
566 ses.channels[channel->index] = NULL; 570 ses.channels[channel->index] = NULL;
567 m_free(channel); 571 m_free(channel);
568 ses.chancount--; 572 ses.chancount--;
569 573
623 maxlen = MIN(channel->transwindow, channel->transmaxpacket); 627 maxlen = MIN(channel->transwindow, channel->transmaxpacket);
624 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 628 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and
625 * exttype if is extended */ 629 * exttype if is extended */
626 maxlen = MIN(maxlen, 630 maxlen = MIN(maxlen,
627 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0)); 631 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
628 TRACE(("maxlen %d", maxlen)) 632 TRACE(("maxlen %zd", maxlen))
629 if (maxlen == 0) { 633 if (maxlen == 0) {
630 TRACE(("leave send_msg_channel_data: no window")) 634 TRACE(("leave send_msg_channel_data: no window"))
631 return; 635 return;
632 } 636 }
633 637
641 size_pos = ses.writepayload->pos; 645 size_pos = ses.writepayload->pos;
642 buf_putint(ses.writepayload, 0); 646 buf_putint(ses.writepayload, 0);
643 647
644 /* read the data */ 648 /* read the data */
645 len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen); 649 len = read(fd, buf_getwriteptr(ses.writepayload, maxlen), maxlen);
650
646 if (len <= 0) { 651 if (len <= 0) {
647 if (len == 0 || errno != EINTR) { 652 if (len == 0 || errno != EINTR) {
648 /* This will also get hit in the case of EAGAIN. The only 653 /* This will also get hit in the case of EAGAIN. The only
649 time we expect to receive EAGAIN is when we're flushing a FD, 654 time we expect to receive EAGAIN is when we're flushing a FD,
650 in which case it can be treated the same as EOF */ 655 in which case it can be treated the same as EOF */
651 close_chan_fd(channel, fd, SHUT_RD); 656 close_chan_fd(channel, fd, SHUT_RD);
652 } 657 }
653 ses.writepayload->len = ses.writepayload->pos = 0; 658 buf_setpos(ses.writepayload, 0);
659 buf_setlen(ses.writepayload, 0);
654 TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d", 660 TRACE(("leave send_msg_channel_data: len %d read err %d or EOF for fd %d",
655 len, errno, fd)) 661 len, errno, fd))
656 return; 662 return;
663 }
664
665 if (channel->read_mangler) {
666 channel->read_mangler(channel, buf_getwriteptr(ses.writepayload, len), &len);
667 if (len == 0) {
668 buf_setpos(ses.writepayload, 0);
669 buf_setlen(ses.writepayload, 0);
670 return;
671 }
657 } 672 }
658 673
659 TRACE(("send_msg_channel_data: len %d fd %d", len, fd)) 674 TRACE(("send_msg_channel_data: len %d fd %d", len, fd))
660 buf_incrwritepos(ses.writepayload, len); 675 buf_incrwritepos(ses.writepayload, len);
661 /* ... real size here */ 676 /* ... real size here */