diff --git a/format.c b/format.c index da9eb545..aa8396d7 100644 --- a/format.c +++ b/format.c @@ -1376,8 +1376,8 @@ void format_defaults_pane(struct format_tree *ft, struct window_pane *wp) { struct grid *gd = wp->base.grid; + int status = wp->status; u_int idx; - int status; if (ft->w == NULL) ft->w = wp->window; @@ -1399,8 +1399,7 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_input_off", "%d", !!(wp->flags & PANE_INPUTOFF)); format_add(ft, "pane_pipe", "%d", wp->pipe_fd != -1); - status = wp->status; - if (wp->fd == -1 && WIFEXITED(status)) + if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(status)) format_add(ft, "pane_dead_status", "%d", WEXITSTATUS(status)); format_add(ft, "pane_dead", "%d", wp->fd == -1); @@ -1411,8 +1410,10 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1); format_add(ft, "pane_at_left", "%d", wp->xoff == 0); format_add(ft, "pane_at_top", "%d", wp->yoff == 0); - format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == wp->window->sx); - format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == wp->window->sy); + format_add(ft, "pane_at_right", "%d", + wp->xoff + wp->sx == wp->window->sx); + format_add(ft, "pane_at_bottom", "%d", + wp->yoff + wp->sy == wp->window->sy); } format_add(ft, "pane_in_mode", "%d", wp->screen != &wp->base); diff --git a/server-fn.c b/server-fn.c index f5ede2c2..713e85b7 100644 --- a/server-fn.c +++ b/server-fn.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -278,11 +279,11 @@ void server_destroy_pane(struct window_pane *wp, int notify) { struct window *w = wp->window; - int old_fd; struct screen_write_ctx ctx; struct grid_cell gc; + time_t t; + char tim[26]; - old_fd = wp->fd; if (wp->fd != -1) { bufferevent_free(wp->event); close(wp->fd); @@ -290,9 +291,13 @@ server_destroy_pane(struct window_pane *wp, int notify) } if (options_get_number(w->options, "remain-on-exit")) { - if (old_fd == -1) + if (~wp->flags & PANE_STATUSREADY) return; + if (wp->flags & PANE_STATUSDRAWN) + return; + wp->flags |= PANE_STATUSDRAWN; + if (notify) notify_pane("pane-died", wp); @@ -301,11 +306,24 @@ server_destroy_pane(struct window_pane *wp, int notify) screen_write_cursormove(&ctx, 0, screen_size_y(ctx.s) - 1); screen_write_linefeed(&ctx, 1, 8); memcpy(&gc, &grid_default_cell, sizeof gc); - gc.attr |= GRID_ATTR_BRIGHT; - screen_write_puts(&ctx, &gc, "Pane is dead"); + + time(&t); + ctime_r(&t, tim); + + if (WIFEXITED(wp->status)) { + screen_write_nputs(&ctx, -1, &gc, + "Pane is dead (status %d, %s)", + WEXITSTATUS(wp->status), + tim); + } else if (WIFSIGNALED(wp->status)) { + screen_write_nputs(&ctx, -1, &gc, + "Pane is dead (signal %d, %s)", + WTERMSIG(wp->status), + tim); + } + screen_write_stop(&ctx); wp->flags |= PANE_REDRAW; - return; } diff --git a/server.c b/server.c index 753f6d01..82b5a6b8 100644 --- a/server.c +++ b/server.c @@ -424,6 +424,7 @@ server_child_exited(pid_t pid, int status) TAILQ_FOREACH(wp, &w->panes, entry) { if (wp->pid == pid) { wp->status = status; + wp->flags |= PANE_STATUSREADY; log_debug("%%%u exited", wp->id); wp->flags |= PANE_EXITED; diff --git a/tmux.h b/tmux.h index a661a6da..ad35c336 100644 --- a/tmux.h +++ b/tmux.h @@ -778,6 +778,8 @@ struct window_pane { #define PANE_INPUTOFF 0x40 #define PANE_CHANGED 0x80 #define PANE_EXITED 0x100 +#define PANE_STATUSREADY 0x200 +#define PANE_STATUSDRAWN 0x400 int argc; char **argv; diff --git a/window.c b/window.c index 1c97fb8d..2afd42d3 100644 --- a/window.c +++ b/window.c @@ -908,6 +908,7 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv, free((void *)wp->cwd); wp->cwd = xstrdup(cwd); } + wp->flags &= ~(PANE_STATUSREADY|PANE_STATUSDRAWN); cmd = cmd_stringify_argv(wp->argc, wp->argv); log_debug("spawn: %s -- %s", wp->shell, cmd);