diff options
Diffstat (limited to 'svr-chansession.c')
-rw-r--r-- | svr-chansession.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/svr-chansession.c b/svr-chansession.c index b6544e6..23cac85 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -59,7 +59,6 @@ static void send_msg_chansess_exitstatus(struct Channel * channel, struct ChanSess * chansess); static void send_msg_chansess_exitsignal(struct Channel * channel, struct ChanSess * chansess); -static int sesscheckclose(struct Channel *channel); static void get_termmodes(struct ChanSess *chansess); @@ -68,7 +67,7 @@ extern char** environ; static int sesscheckclose(struct Channel *channel) { struct ChanSess *chansess = (struct ChanSess*)channel->typedata; - return chansess->exit.exitpid >= 0; + return chansess->exit.exitpid != -1; } /* Handler for childs exiting, store the state for return to the client */ @@ -121,9 +120,21 @@ static void sesssigchild_handler(int UNUSED(dummy)) { /* we use this to determine how pid exited */ exit->exitsignal = -1; } + + /* Make sure that the main select() loop wakes up */ + while (1) { + /* EAGAIN means the pipe's full, so don't need to write anything */ + /* isserver is just a random byte to write */ + if (write(ses.signal_pipe[1], &ses.isserver, 1) == 1 || errno == EAGAIN) { + break; + } + if (errno == EINTR) { + continue; + } + dropbear_exit("error writing signal pipe"); + } } - sa_chld.sa_handler = sesssigchild_handler; sa_chld.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sa_chld, NULL); @@ -245,16 +256,17 @@ static void closechansess(struct Channel *channel) { unsigned int i; struct logininfo *li; - chansess = (struct ChanSess*)channel->typedata; + TRACE(("enter closechansess")) - send_exitsignalstatus(channel); + chansess = (struct ChanSess*)channel->typedata; - TRACE(("enter closechansess")) if (chansess == NULL) { TRACE(("leave closechansess: chansess == NULL")) return; } + send_exitsignalstatus(channel); + m_free(chansess->cmd); m_free(chansess->term); |