comparison common-channel.c @ 109:2e9d1f29c50f

merge of 50be59810e462f9f44f55e421227d6aa0b31982b and 69b007796063cb5f042be7cca2d479e90db869c3
author Matt Johnston <matt@ucc.asn.au>
date Fri, 27 Aug 2004 14:39:01 +0000
parents 10f4d3319780
children 8c2b3506f112
comparison
equal deleted inserted replaced
108:10f4d3319780 109:2e9d1f29c50f
190 if (channel->outfd >= 0 && FD_ISSET(channel->outfd, readfd)) { 190 if (channel->outfd >= 0 && FD_ISSET(channel->outfd, readfd)) {
191 send_msg_channel_data(channel, 0, 0); 191 send_msg_channel_data(channel, 0, 0);
192 } 192 }
193 193
194 /* read from program/pipe stderr */ 194 /* read from program/pipe stderr */
195 if (channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) { 195 if (channel->extrabuf == NULL &&
196 channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) {
196 send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR); 197 send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
197 } 198 }
198 199
199 /* if we can read from the infd, it might be closed, so we try to 200 /* if we can read from the infd, it might be closed, so we try to
200 * see if it has errors */ 201 * see if it has errors */
243 244
244 245
245 /* do all the EOF/close type stuff checking for a channel */ 246 /* do all the EOF/close type stuff checking for a channel */
246 static void checkclose(struct Channel *channel) { 247 static void checkclose(struct Channel *channel) {
247 248
249 TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d",
250 channel->infd, channel->outfd,
251 channel->errfd, channel->sentclosed, channel->recvclosed));
252 TRACE(("writebuf %d extrabuf %s extrabuf %d",
253 cbuf_getused(channel->writebuf),
254 channel->writebuf,
255 channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)));
256
248 if (!channel->sentclosed) { 257 if (!channel->sentclosed) {
249 258
250 /* check for exited - currently only used for server sessions, 259 /* check for exited - currently only used for server sessions,
251 * if the shell has exited etc */ 260 * if the shell has exited etc */
252 if (channel->type->checkclose) { 261 if (channel->type->checkclose) {
255 } 264 }
256 } 265 }
257 266
258 if (!channel->senteof 267 if (!channel->senteof
259 && channel->outfd == FD_CLOSED 268 && channel->outfd == FD_CLOSED
260 && channel->errfd == FD_CLOSED) { 269 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
261 send_msg_channel_eof(channel); 270 send_msg_channel_eof(channel);
262 } 271 }
263 272
264 if (channel->infd == FD_CLOSED 273 if (channel->infd == FD_CLOSED
265 && channel->outfd == FD_CLOSED 274 && channel->outfd == FD_CLOSED
266 && channel->errfd == FD_CLOSED) { 275 && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
267 send_msg_channel_close(channel); 276 send_msg_channel_close(channel);
268 } 277 }
269 } 278 }
270 279
271 /* When either party wishes to terminate the channel, it sends 280 /* When either party wishes to terminate the channel, it sends
381 channel->recvdonelen += len; 390 channel->recvdonelen += len;
382 391
383 if (fd == channel->infd && len == maxlen && channel->recveof) { 392 if (fd == channel->infd && len == maxlen && channel->recveof) {
384 /* Check if we're closing up */ 393 /* Check if we're closing up */
385 closeinfd(channel); 394 closeinfd(channel);
395 TRACE(("leave writechannel: recveof set"));
386 return; 396 return;
387 TRACE(("leave writechannel: recveof set"));
388
389 } 397 }
390 398
391 /* Window adjust handling */ 399 /* Window adjust handling */
392 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { 400 if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
393 /* Set it back to max window */ 401 /* Set it back to max window */
431 } 439 }
432 } 440 }
433 441
434 /* For checking FD status (ie closure etc) - we don't actually 442 /* For checking FD status (ie closure etc) - we don't actually
435 * read data from infd */ 443 * read data from infd */
436 TRACE(("infd = %d, outfd %d, bufused %d", channel->infd, channel->outfd, 444 TRACE(("infd = %d, outfd %d, errfd %d, bufused %d",
445 channel->infd, channel->outfd,
446 channel->errfd,
437 cbuf_getused(channel->writebuf) )); 447 cbuf_getused(channel->writebuf) ));
438 if (channel->infd >= 0 && channel->infd != channel->outfd) { 448 if (channel->infd >= 0 && channel->infd != channel->outfd) {
439 FD_SET(channel->infd, readfd); 449 FD_SET(channel->infd, readfd);
440 } 450 }
441 451
532 542
533 /* close the FDs in case they haven't been done 543 /* close the FDs in case they haven't been done
534 * yet (ie they were shutdown etc */ 544 * yet (ie they were shutdown etc */
535 close(channel->infd); 545 close(channel->infd);
536 close(channel->outfd); 546 close(channel->outfd);
537 if (channel->errfd >= 0) { 547 close(channel->errfd);
538 close(channel->errfd); 548
539 }
540 channel->typedata = NULL; 549 channel->typedata = NULL;
541 550
542 deletechannel(channel); 551 deletechannel(channel);
543 552
544 TRACE(("leave removechannel")); 553 TRACE(("leave removechannel"));
617 TRACE(("leave send_msg_channel_data: no window")); 626 TRACE(("leave send_msg_channel_data: no window"));
618 return; /* the data will get written later */ 627 return; /* the data will get written later */
619 } 628 }
620 629
621 /* read the data */ 630 /* read the data */
631 TRACE(("maxlen %d", maxlen));
622 buf = buf_new(maxlen); 632 buf = buf_new(maxlen);
633 TRACE(("buf pos %d data %x", buf->pos, buf->data));
623 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); 634 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
624 if (len <= 0) { 635 if (len <= 0) {
625 /* on error/eof, send eof */ 636 /* on error/eof, send eof */
626 if (len == 0 || errno != EINTR) { 637 if (len == 0 || errno != EINTR) {
627 closeoutfd(channel, fd); 638 closeoutfd(channel, fd);
628 TRACE(("leave send_msg_channel_data: read err %d", channel->index));
629 } 639 }
630 buf_free(buf); 640 buf_free(buf);
631 buf = NULL; 641 buf = NULL;
642 TRACE(("leave send_msg_channel_data: read err or EOF for fd %d",
643 channel->index));
632 return; 644 return;
633 } 645 }
634 buf_incrlen(buf, len); 646 buf_incrlen(buf, len);
635 647
636 buf_putbyte(ses.writepayload, 648 buf_putbyte(ses.writepayload,
712 cbuf_incrwrite(cbuf, buflen); 724 cbuf_incrwrite(cbuf, buflen);
713 buf_incrpos(ses.payload, buflen); 725 buf_incrpos(ses.payload, buflen);
714 len -= buflen; 726 len -= buflen;
715 } 727 }
716 728
717 assert(channel->recvwindow > datalen); 729 assert(channel->recvwindow >= datalen);
718 channel->recvwindow -= datalen; 730 channel->recvwindow -= datalen;
719 assert(channel->recvwindow <= RECV_MAXWINDOW); 731 assert(channel->recvwindow <= RECV_MAXWINDOW);
720 732
721 TRACE(("leave recv_msg_channel_data")); 733 TRACE(("leave recv_msg_channel_data"));
722 } 734 }
925 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()")); 937 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"));
926 return DROPBEAR_FAILURE; 938 return DROPBEAR_FAILURE;
927 } 939 }
928 940
929 /* set fd non-blocking */ 941 /* set fd non-blocking */
930 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { 942 setnonblocking(fd);
931 TRACE(("leave send_msg_channel_open_init() - FAILED in fcntl()"));
932 return DROPBEAR_FAILURE;
933 }
934 943
935 chan->infd = chan->outfd = fd; 944 chan->infd = chan->outfd = fd;
936 ses.maxfd = MAX(ses.maxfd, fd); 945 ses.maxfd = MAX(ses.maxfd, fd);
937 946
938 /* now open the channel connection */ 947 /* now open the channel connection */
1032 } else { 1041 } else {
1033 close(fd); 1042 close(fd);
1034 closein = closeout = 1; 1043 closein = closeout = 1;
1035 } 1044 }
1036 1045
1037 if (closeout && fd == channel->errfd) {
1038 channel->errfd = FD_CLOSED;
1039 }
1040 if (closeout && fd == channel->outfd) { 1046 if (closeout && fd == channel->outfd) {
1041 channel->outfd = FD_CLOSED; 1047 channel->outfd = FD_CLOSED;
1042 } 1048 }
1049 if (closeout && (channel->extrabuf == NULL) && (fd == channel->errfd)) {
1050 channel->errfd = FD_CLOSED;
1051 }
1052
1043 if (closein && fd == channel->infd) { 1053 if (closein && fd == channel->infd) {
1044 channel->infd = FD_CLOSED; 1054 channel->infd = FD_CLOSED;
1045 } 1055 }
1056 if (closein && (channel->extrabuf != NULL) && (fd == channel->errfd)) {
1057 channel->errfd = FD_CLOSED;
1058 }
1046 } 1059 }
1047 1060
1048 #endif /* USING_LISTENERS */ 1061 #endif /* USING_LISTENERS */