From 392e13534961b80984711f82230d9f34ca4a81bb Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 21 Jan 2009 22:47:31 +0000 Subject: [PATCH] Handle SIGTERM (and kill-server which uses it), a bit more neatly - tidy up properly and print a nicer message. Same effect though :-) --- CHANGES | 4 +++- client-msg.c | 17 ++++++++++++++++- client.c | 7 ++++++- server.c | 43 ++++++++++++++++++++++++++++++++++++++++--- tmux.c | 3 ++- tmux.h | 8 +++++--- 6 files changed, 72 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 7cc1d5fa..3fb14b6f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ 21 January 2009 +* Handle SIGTERM (and kill-server which uses it), a bit more neatly - tidy + up properly and print a nicer message. Same effect though :-). * new-window now supports -k to kill target window if it exists. * Bring back split-window -p and -l options to specify the height a percentage or as a number of lines. @@ -995,7 +997,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.229 2009-01-21 22:21:49 nicm Exp $ +$Id: CHANGES,v 1.230 2009-01-21 22:47:31 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/client-msg.c b/client-msg.c index 7f2f3dca..182b26f2 100644 --- a/client-msg.c +++ b/client-msg.c @@ -1,4 +1,4 @@ -/* $Id: client-msg.c,v 1.17 2009-01-18 12:09:42 nicm Exp $ */ +/* $Id: client-msg.c,v 1.18 2009-01-21 22:47:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -27,6 +27,7 @@ int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **); int client_msg_fn_error(struct hdr *, struct client_ctx *, char **); +int client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **); int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **); int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **); int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **); @@ -40,6 +41,7 @@ struct client_msg client_msg_table[] = { { MSG_ERROR, client_msg_fn_error }, { MSG_EXIT, client_msg_fn_exit }, { MSG_EXITED, client_msg_fn_exited }, + { MSG_SHUTDOWN, client_msg_fn_shutdown }, { MSG_SUSPEND, client_msg_fn_suspend }, }; @@ -94,6 +96,19 @@ client_msg_fn_detach( return (0); } +int +client_msg_fn_shutdown( + struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) +{ + if (hdr->size != 0) + fatalx("bad MSG_SHUTDOWN size"); + + client_write_server(cctx, MSG_EXITING, NULL, 0); + cctx->flags |= CCTX_SHUTDOWN; + + return (0); +} + int client_msg_fn_exit( struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) diff --git a/client.c b/client.c index fa51727c..811d7567 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.41 2009-01-19 17:16:09 nicm Exp $ */ +/* $Id: client.c,v 1.42 2009-01-21 22:47:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -184,6 +184,11 @@ out: return (1); } + if (cctx->flags & CCTX_SHUTDOWN) { + printf("[server exited]\n"); + return (0); + } + if (cctx->flags & CCTX_EXIT) { printf("[exited]\n"); return (0); diff --git a/server.c b/server.c index fd2d5cd5..8a577b04 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.110 2009-01-20 19:35:03 nicm Exp $ */ +/* $Id: server.c,v 1.111 2009-01-21 22:47:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -43,6 +43,7 @@ struct clients clients; int server_main(const char *, int); +void server_shutdown(void); void server_fill_windows(struct pollfd **); void server_handle_windows(struct pollfd **); void server_fill_clients(struct pollfd **); @@ -224,7 +225,11 @@ server_main(const char *srv_path, int srv_fd) last = time(NULL); pfds = NULL; - while (!sigterm) { + for (;;) { + /* If sigterm, kill all windows and clients. */ + if (sigterm) + server_shutdown(); + /* Initialise pollfd array. */ nfds = 1; for (i = 0; i < ARRAY_LENGTH(&windows); i++) { @@ -247,7 +252,7 @@ server_main(const char *srv_path, int srv_fd) /* Update socket permissions. */ xtimeout = INFTIM; - if (server_update_socket(srv_path) != 0) + if (sigterm || server_update_socket(srv_path) != 0) xtimeout = 100; /* Do the poll. */ @@ -326,6 +331,34 @@ server_main(const char *srv_path, int srv_fd) return (0); } +/* Kill all clients. */ +void +server_shutdown(void) +{ + struct session *s; + struct client *c; + u_int i; + + for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { + s = ARRAY_ITEM(&sessions, i); + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c != NULL && c->session == s) { + s = NULL; + break; + } + } + if (s != NULL) + session_destroy(s); + } + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + c = ARRAY_ITEM(&clients, i); + if (c != NULL) + server_write_client(c, MSG_SHUTDOWN, NULL, 0); + } +} + /* Fill window pollfds. */ void server_fill_windows(struct pollfd **pfd) @@ -575,6 +608,10 @@ server_accept_client(int srv_fd) return (NULL); fatal("accept failed"); } + if (sigterm) { + close(fd); + return (NULL); + } return (server_create_client(fd)); } diff --git a/tmux.c b/tmux.c index d129a6a0..515029ce 100644 --- a/tmux.c +++ b/tmux.c @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.100 2009-01-20 19:35:03 nicm Exp $ */ +/* $Id: tmux.c,v 1.101 2009-01-21 22:47:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -402,6 +402,7 @@ main(int argc, char **argv) switch (hdr.type) { case MSG_EXIT: + case MSG_SHUTDOWN: n = 0; goto out; case MSG_ERROR: diff --git a/tmux.h b/tmux.h index 34366f82..327552e9 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.246 2009-01-21 19:38:51 nicm Exp $ */ +/* $Id: tmux.h,v 1.247 2009-01-21 22:47:31 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -19,7 +19,7 @@ #ifndef TMUX_H #define TMUX_H -#define PROTOCOL_VERSION -10 +#define PROTOCOL_VERSION -11 /* Shut up gcc warnings about empty if bodies. */ #define RB_AUGMENT(x) do {} while (0) @@ -360,8 +360,9 @@ enum hdrtype { MSG_PRINT, MSG_READY, MSG_RESIZE, - MSG_UNLOCK, + MSG_SHUTDOWN, MSG_SUSPEND, + MSG_UNLOCK, MSG_WAKEUP, }; @@ -794,6 +795,7 @@ struct client_ctx { #define CCTX_DETACH 0x1 #define CCTX_EXIT 0x2 +#define CCTX_SHUTDOWN 0x4 int flags; };