Mercurial > dropbear
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 */ |