From 9a7cde0c9be168900d3914857c85d71bc472608f Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Sun, 26 Sep 2010 20:43:30 +0000 Subject: [PATCH] Two new options: - server option "exit-unattached" makes the server exit when no clients are attached, even if sessions are present; - session option "destroy-unattached" destroys a session once no clients are attached to it. These are useful for preventing tmux remaining in the background where it is undesirable and when using tmux as a login shell to keep a limit on new sessions. --- cmd-set-option.c | 2 ++ cmd-switch-client.c | 1 + server-client.c | 1 + server-fn.c | 19 +++++++++++++++++++ server.c | 10 ++++++---- tmux.1 | 6 ++++++ tmux.c | 2 ++ tmux.h | 1 + 8 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cmd-set-option.c b/cmd-set-option.c index a3ca635c..684f1b04 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -75,6 +75,7 @@ const char *set_option_bell_action_list[] = { const struct set_option_entry set_option_table[] = { { "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL }, + { "exit-unattached", SET_OPTION_FLAG, 0, 0, NULL }, { "quiet", SET_OPTION_FLAG, 0, 0, NULL }, { NULL, 0, 0, 0, NULL } }; @@ -87,6 +88,7 @@ const struct set_option_entry set_session_option_table[] = { { "default-path", SET_OPTION_STRING, 0, 0, NULL }, { "default-shell", SET_OPTION_STRING, 0, 0, NULL }, { "default-terminal", SET_OPTION_STRING, 0, 0, NULL }, + { "destroy-unattached", SET_OPTION_FLAG, 0, 0, NULL }, { "detach-on-destroy", SET_OPTION_FLAG, 0, 0, NULL }, { "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL }, { "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL }, diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 913bb501..bce42c2a 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -152,6 +152,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx) c->session = s; recalculate_sizes(); + server_check_unattached(); server_redraw_client(c); return (0); diff --git a/server-client.c b/server-client.c index 27a5d207..427f8dfb 100644 --- a/server-client.c +++ b/server-client.c @@ -185,6 +185,7 @@ server_client_lost(struct client *c) c->flags |= CLIENT_DEAD; recalculate_sizes(); + server_check_unattached(); server_update_socket(); } diff --git a/server-fn.c b/server-fn.c index 03c89cf5..af443e8f 100644 --- a/server-fn.c +++ b/server-fn.c @@ -404,6 +404,25 @@ server_destroy_session(struct session *s) recalculate_sizes(); } +void +server_check_unattached (void) +{ + struct session *s; + u_int i; + + /* + * If any sessions are no longer attached and have destroy-unattached + * set, collect them. + */ + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { + s = ARRAY_ITEM(&sessions, i); + if (s == NULL || !(s->flags & SESSION_UNATTACHED)) + continue; + if (options_get_number (&s->options, "destroy-unattached")) + session_destroy(s); + } +} + void server_set_identify(struct client *c) { diff --git a/server.c b/server.c index d5514f62..7dfd5be6 100644 --- a/server.c +++ b/server.c @@ -222,15 +222,17 @@ server_loop(void) } } -/* Check if the server should be shutting down (no more clients or windows). */ +/* Check if the server should be shutting down (no more clients or sessions). */ int server_should_shutdown(void) { u_int i; - for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { - if (ARRAY_ITEM(&sessions, i) != NULL) - return (0); + if (!options_get_number(&global_options, "exit-unattached")) { + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { + if (ARRAY_ITEM(&sessions, i) != NULL) + return (0); + } } for (i = 0; i < ARRAY_LENGTH(&clients); i++) { if (ARRAY_ITEM(&clients, i) != NULL) diff --git a/tmux.1 b/tmux.1 index d9b76ae1..bfd05c55 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1587,6 +1587,9 @@ Set the time in milliseconds for which waits after an escape is input to determine if it is part of a function or meta key sequences. The default is 500 milliseconds. +.It Ic exit-unattached +If enabled, the server will exit when there are no attached clients, rather +than when there are no attached sessions. .It Ic quiet Enable or disable the display of various informational messages (see also the .Fl q @@ -1659,6 +1662,9 @@ to work correctly, this be set to .Ql screen or a derivative of it. +.It Ic destroy-unattached +If enabled and the session is no longer attached to any clients, it is +destroyed. .It Ic detach-on-destroy If on (the default), the client is detached when the session it is attached to is destroyed. diff --git a/tmux.c b/tmux.c index 9274236e..2b01f2b7 100644 --- a/tmux.c +++ b/tmux.c @@ -331,6 +331,7 @@ main(int argc, char **argv) oo = &global_options; options_set_number(oo, "quiet", quiet); options_set_number(oo, "escape-time", 500); + options_set_number(oo, "exit-unattached", 0); options_init(&global_s_options, NULL); so = &global_s_options; @@ -341,6 +342,7 @@ main(int argc, char **argv) options_set_string(so, "default-path", "%s", ""); options_set_string(so, "default-shell", "%s", getshell()); options_set_string(so, "default-terminal", "screen"); + options_set_number(so, "destroy-unattached", 0); options_set_number(so, "detach-on-destroy", 1); options_set_number(so, "display-panes-active-colour", 1); options_set_number(so, "display-panes-colour", 4); diff --git a/tmux.h b/tmux.h index 257c0816..762f0d26 100644 --- a/tmux.h +++ b/tmux.h @@ -1661,6 +1661,7 @@ void server_unlink_window(struct session *, struct winlink *); void server_destroy_pane(struct window_pane *); void server_destroy_session_group(struct session *); void server_destroy_session(struct session *); +void server_check_unattached (void); void server_set_identify(struct client *); void server_clear_identify(struct client *); void server_update_event(struct client *);