diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 2400b3b4..304fe910 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -129,7 +129,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item) memcpy(&cdata->mouse, &shared->mouse, sizeof cdata->mouse); job_run(shellcmd, s, cwd, NULL, cmd_if_shell_callback, - cmd_if_shell_free, cdata); + cmd_if_shell_free, cdata, 0); free(shellcmd); if (args_has(args, 'b')) diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 0d73dd2b..8de8736a 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -111,7 +111,7 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) cdata->item = item; job_run(cdata->cmd, s, cwd, NULL, cmd_run_shell_callback, - cmd_run_shell_free, cdata); + cmd_run_shell_free, cdata, 0); if (args_has(args, 'b')) return (CMD_RETURN_NORMAL); diff --git a/format.c b/format.c index 0cd3503c..bf76fcf0 100644 --- a/format.c +++ b/format.c @@ -295,7 +295,7 @@ format_job_get(struct format_tree *ft, const char *cmd) t = time(NULL); if (fj->job == NULL && (force || fj->last != t)) { fj->job = job_run(expanded, NULL, NULL, format_job_update, - format_job_complete, NULL, fj); + format_job_complete, NULL, fj, JOB_NOWAIT); if (fj->job == NULL) { free(fj->out); xasprintf(&fj->out, "<'%s' didn't start>", fj->cmd); diff --git a/job.c b/job.c index 866e36c7..5cbe31cd 100644 --- a/job.c +++ b/job.c @@ -44,7 +44,7 @@ struct joblist all_jobs = LIST_HEAD_INITIALIZER(all_jobs); struct job * job_run(const char *cmd, struct session *s, const char *cwd, job_update_cb updatecb, job_complete_cb completecb, job_free_cb freecb, - void *data) + void *data, int flags) { struct job *job; struct environ *env; @@ -111,6 +111,7 @@ job_run(const char *cmd, struct session *s, const char *cwd, job = xmalloc(sizeof *job); job->state = JOB_RUNNING; + job->flags = flags; job->cmd = xstrdup(cmd); job->pid = pid; diff --git a/server-client.c b/server-client.c index d2c6ebf9..4da9f08a 100644 --- a/server-client.c +++ b/server-client.c @@ -1279,6 +1279,8 @@ server_client_check_exit(struct client *c) if (EVBUFFER_LENGTH(c->stderr_data) != 0) return; + if (c->flags & CLIENT_ATTACHED) + notify_client("client-detached", c); proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval); c->flags &= ~CLIENT_EXIT; } diff --git a/server.c b/server.c index b1d3312a..5d321ccb 100644 --- a/server.c +++ b/server.c @@ -244,6 +244,7 @@ server_loop(void) { struct client *c; u_int items; + struct job *job; do { items = cmdq_next(NULL); @@ -276,6 +277,11 @@ server_loop(void) if (!TAILQ_EMPTY(&clients)) return (0); + LIST_FOREACH(job, &all_jobs, entry) { + if ((~job->flags & JOB_NOWAIT) && job->state == JOB_RUNNING) + return (0); + } + return (1); } @@ -291,8 +297,11 @@ server_send_exit(void) TAILQ_FOREACH_SAFE(c, &clients, entry, c1) { if (c->flags & CLIENT_SUSPENDED) server_client_lost(c); - else + else { + if (c->flags & CLIENT_ATTACHED) + notify_client("client-detached", c); proc_send(c->peer, MSG_SHUTDOWN, -1, NULL, 0); + } c->session = NULL; } diff --git a/tmux.h b/tmux.h index d7b9f334..5d5be8bb 100644 --- a/tmux.h +++ b/tmux.h @@ -622,6 +622,9 @@ struct job { JOB_CLOSED } state; + int flags; +#define JOB_NOWAIT 0x1 + char *cmd; pid_t pid; int status; @@ -1649,7 +1652,7 @@ extern const struct options_table_entry options_table[]; /* job.c */ extern struct joblist all_jobs; struct job *job_run(const char *, struct session *, const char *, - job_update_cb, job_complete_cb, job_free_cb, void *); + job_update_cb, job_complete_cb, job_free_cb, void *, int); void job_free(struct job *); void job_died(struct job *, int); diff --git a/window-copy.c b/window-copy.c index 31140ab3..6eb3d435 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1677,7 +1677,7 @@ window_copy_copy_pipe(struct window_pane *wp, struct session *s, return; expanded = format_single(NULL, arg, NULL, s, NULL, wp); - job = job_run(expanded, s, NULL, NULL, NULL, NULL, NULL); + job = job_run(expanded, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT); bufferevent_write(job->event, buf, len); free(expanded);