With csh, a tmux client gets SIGTERM before SIGCONT when killed with

"kill %%", so when the client tells the server it got SIGCONT, don't use
bits that may already have been freed when it got SIGTERM. Also don't
print anything on exit if we get SIGTERM while suspended. Reported by
Theo.
pull/2448/head
nicm 2020-10-30 18:54:23 +00:00
parent 9726c4454e
commit 95841ba16a
2 changed files with 8 additions and 3 deletions

View File

@ -36,6 +36,7 @@
static struct tmuxproc *client_proc;
static struct tmuxpeer *client_peer;
static uint64_t client_flags;
static int client_suspended;
static enum {
CLIENT_EXIT_NONE,
CLIENT_EXIT_DETACHED,
@ -221,7 +222,7 @@ static void
client_exit(void)
{
struct client_file *cf;
size_t left;
size_t left;
int waiting = 0;
RB_FOREACH (cf, client_files, &client_files) {
@ -763,6 +764,7 @@ client_signal(int sig)
struct sigaction sigact;
int status;
log_debug("%s: %s", __func__, strsignal(sig));
if (sig == SIGCHLD)
waitpid(WAIT_ANY, &status, WNOHANG);
else if (!client_attached) {
@ -776,7 +778,8 @@ client_signal(int sig)
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
break;
case SIGTERM:
client_exitreason = CLIENT_EXIT_TERMINATED;
if (!client_suspended)
client_exitreason = CLIENT_EXIT_TERMINATED;
client_exitval = 1;
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
break;
@ -791,6 +794,7 @@ client_signal(int sig)
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0);
client_suspended = 0;
break;
}
}
@ -1003,6 +1007,7 @@ client_dispatch_attached(struct imsg *imsg)
sigact.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
client_suspended = 1;
kill(getpid(), SIGTSTP);
break;
case MSG_LOCK:

View File

@ -2025,7 +2025,7 @@ server_client_dispatch(struct imsg *imsg, void *arg)
break;
c->flags &= ~CLIENT_SUSPENDED;
if (c->fd == -1) /* exited in the meantime */
if (c->fd == -1 || c->session == NULL) /* exited already */
break;
s = c->session;