summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--common-channel.c37
-rw-r--r--svr-chansession.c7
2 files changed, 14 insertions, 30 deletions
diff --git a/common-channel.c b/common-channel.c
index e8175ae..688ee56 100644
--- a/common-channel.c
+++ b/common-channel.c
@@ -263,10 +263,12 @@ static void check_close(struct Channel *channel) {
channel->writebuf,
channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
- if (!channel->sent_close
- && channel->writefd == FD_CLOSED
- && (channel->errfd == FD_CLOSED || channel->extrabuf == NULL)) {
- send_msg_channel_close(channel);
+ /* A bit of a hack for closing up server session channels */
+ if (channel->writefd >= 0
+ && channel->type->check_close
+ && channel->type->check_close(channel)) {
+ TRACE(("channel->type->check_close got hit"))
+ close_chan_fd(channel, channel->writefd, SHUT_WR);
}
if (channel->recv_close && !write_pending(channel)) {
@@ -278,31 +280,15 @@ static void check_close(struct Channel *channel) {
return;
}
-#if 0
- // The only use of check_close is "return channel->writefd == -1;" for a server
- // chansession. Should be able to handle that with just the general
- // socket close handling...?
- if (channel->type->check_close) {
- if (channel->type->check_close(channel)) {
- close_write_fd(channel);
- close_read_fd(channel, channel->readfd);
- close_read_fd(channel, channel->errfd);
- }
+ if (channel->recv_eof && !write_pending(channel)) {
+ close_chan_fd(channel, channel->writefd, SHUT_WR);
}
-#endif
if (!channel->sent_eof
&& channel->readfd == FD_CLOSED
&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
send_msg_channel_eof(channel);
}
-
- if (!channel->sent_close
- && channel->writefd == FD_CLOSED
- && channel->readfd == FD_CLOSED
- && (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
- send_msg_channel_close(channel);
- }
}
@@ -395,13 +381,6 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
cbuf_incrread(cbuf, len);
channel->recvdonelen += len;
- /* We're closing out */
- if (channel->recv_eof && cbuf_getused(cbuf) == 0) {
- TRACE(("leave writechannel"))
- close_chan_fd(channel, fd, SHUT_WR);
- return;
- }
-
/* Window adjust handling */
if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
/* Set it back to max window */
diff --git a/svr-chansession.c b/svr-chansession.c
index 57ec118..99a67e9 100644
--- a/svr-chansession.c
+++ b/svr-chansession.c
@@ -65,6 +65,11 @@ static void get_termmodes(struct ChanSess *chansess);
/* required to clear environment */
extern char** environ;
+static int sesscheckclose(struct Channel *channel) {
+ struct ChanSess *chansess = (struct ChanSess*)channel->typedata;
+ return chansess->exit.exitpid != -1;
+}
+
/* Handler for childs exiting, store the state for return to the client */
/* There's a particular race we have to watch out for: if the forked child
@@ -962,7 +967,7 @@ const struct ChanType svrchansess = {
0, /* sepfds */
"session", /* name */
newchansess, /* inithandler */
- NULL, /* checkclosehandler */
+ sesscheckclose, /* checkclosehandler */
chansessionrequest, /* reqhandler */
closechansess, /* closehandler */
};