diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-06-18 08:34:23 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-06-18 08:34:23 +0000 |
commit | c50abd069038115a9946520c2d8d0a103fcbbe48 (patch) | |
tree | 800c9dea4847a4ec80db9734c944277cc5150f6a /usr.bin/tmux | |
parent | 1edc1e683741f2cac0146a729e56c9ecfdd6018b (diff) |
Add a flag to make a client wait for an empty line before exiting in
control mode to avoid stray commands ending up in the shell.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/client.c | 40 | ||||
-rw-r--r-- | usr.bin/tmux/control.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 7 | ||||
-rw-r--r-- | usr.bin/tmux/server.c | 4 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 6 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 4 |
6 files changed, 51 insertions, 13 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c index 3c3106194d7..228f4ac6531 100644 --- a/usr.bin/tmux/client.c +++ b/usr.bin/tmux/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.147 2020/06/10 07:27:10 nicm Exp $ */ +/* $OpenBSD: client.c,v 1.148 2020/06/18 08:34:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -35,7 +35,7 @@ static struct tmuxproc *client_proc; static struct tmuxpeer *client_peer; -static int client_flags; +static uint64_t client_flags; static enum { CLIENT_EXIT_NONE, CLIENT_EXIT_DETACHED, @@ -247,7 +247,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat) pid_t ppid; enum msgtype msg; struct termios tio, saved_tio; - size_t size; + size_t size, linesize = 0; + ssize_t linelen; + char *line = NULL; /* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */ signal(SIGCHLD, SIG_IGN); @@ -276,13 +278,14 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat) free(pr->error); } - /* Save the flags. */ - client_flags = flags; - /* Create client process structure (starts logging). */ client_proc = proc_start("client"); proc_set_signals(client_proc, client_signal); + /* Save the flags. */ + client_flags = flags; + log_debug("flags are %#llx", client_flags); + /* Initialize the client socket and start the server. */ fd = client_connect(base, socket_path, client_flags); if (fd == -1) { @@ -406,8 +409,19 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat) printf("%%exit %s\n", client_exit_message()); else printf("%%exit\n"); + fflush(stdout); + if (client_flags & CLIENT_CONTROL_WAITEXIT) { + setvbuf(stdin, NULL, _IOLBF, 0); + for (;;) { + linelen = getline(&line, &linesize, stdin); + if (linelen <= 1) + break; + } + free(line); + } if (client_flags & CLIENT_CONTROLCONTROL) { printf("\033\\"); + fflush(stdout); tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio); } } else if (client_exitreason != CLIENT_EXIT_NONE) @@ -870,6 +884,13 @@ client_dispatch_wait(struct imsg *imsg) client_exitval = 1; proc_exit(client_proc); break; + case MSG_FLAGS: + if (datalen != sizeof client_flags) + fatalx("bad MSG_FLAGS string"); + + memcpy(&client_flags, data, sizeof client_flags); + log_debug("new flags are %#llx", client_flags); + break; case MSG_SHELL: if (datalen == 0 || data[datalen - 1] != '\0') fatalx("bad MSG_SHELL string"); @@ -916,6 +937,13 @@ client_dispatch_attached(struct imsg *imsg) datalen = imsg->hdr.len - IMSG_HEADER_SIZE; switch (imsg->hdr.type) { + case MSG_FLAGS: + if (datalen != sizeof client_flags) + fatalx("bad MSG_FLAGS string"); + + memcpy(&client_flags, data, sizeof client_flags); + log_debug("new flags are %#llx", client_flags); + break; case MSG_DETACH: case MSG_DETACHKILL: if (datalen == 0 || data[datalen - 1] != '\0') diff --git a/usr.bin/tmux/control.c b/usr.bin/tmux/control.c index ca0b37d5230..a5050335936 100644 --- a/usr.bin/tmux/control.c +++ b/usr.bin/tmux/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.42 2020/06/12 08:35:01 nicm Exp $ */ +/* $OpenBSD: control.c,v 1.43 2020/06/18 08:34:22 nicm Exp $ */ /* * Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -695,6 +695,7 @@ control_discard(struct client *c) RB_FOREACH(cp, control_panes, &cs->panes) control_discard_pane(c, cp); + bufferevent_disable(cs->read_event, EV_READ); } /* Stop control mode. */ diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 44b7632a445..43f479b0332 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.357 2020/06/10 07:27:10 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.358 2020/06/18 08:34:22 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -2370,6 +2370,8 @@ server_client_control_flags(struct client *c, const char *next) } if (strcmp(next, "no-output") == 0) return (CLIENT_CONTROL_NOOUTPUT); + if (strcmp(next, "wait-exit") == 0) + return (CLIENT_CONTROL_WAITEXIT); return (0); } @@ -2409,6 +2411,7 @@ server_client_set_flags(struct client *c, const char *flags) control_reset_offsets(c); } free(copy); + proc_send(c->peer, MSG_FLAGS, -1, &c->flags, sizeof c->flags); } /* Get client flags. This is only flags useful to show to users. */ @@ -2427,6 +2430,8 @@ server_client_get_flags(struct client *c) strlcat(s, "ignore-size,", sizeof s); if (c->flags & CLIENT_CONTROL_NOOUTPUT) strlcat(s, "no-output,", sizeof s); + if (c->flags & CLIENT_CONTROL_WAITEXIT) + strlcat(s, "wait-exit,", sizeof s); if (c->flags & CLIENT_CONTROL_PAUSEAFTER) { xsnprintf(tmp, sizeof tmp, "pause-after=%u,", c->pause_age / 1000); diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index 3b8f4529c97..f8d0a17bf29 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.193 2020/06/01 09:43:01 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.194 2020/06/18 08:34:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -45,7 +45,7 @@ struct clients clients; struct tmuxproc *server_proc; static int server_fd = -1; -static int server_client_flags; +static uint64_t server_client_flags; static int server_exit; static struct event server_ev_accept; diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 49c1479a9ad..53159bb7d68 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.785 2020/06/16 08:18:34 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.786 2020/06/18 08:34:22 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 16 2020 $ +.Dd $Mdocdate: June 18 2020 $ .Dt TMUX 1 .Os .Sh NAME @@ -989,6 +989,8 @@ output is paused once the pane is behind in control mode .It read-only the client is read-only +.It wait-exit +wait for an empty line input before exiting in control mode .El .Pp A leading diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 5a33fb29003..b4168c7212f 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1070 2020/06/16 08:18:34 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1071 2020/06/18 08:34:22 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -515,6 +515,7 @@ enum msgtype { MSG_UNLOCK, MSG_WAKEUP, MSG_EXEC, + MSG_FLAGS, MSG_READ_OPEN = 300, MSG_READ, @@ -1644,6 +1645,7 @@ struct client { #define CLIENT_NOFORK 0x40000000 #define CLIENT_ACTIVEPANE 0x80000000ULL #define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL +#define CLIENT_CONTROL_WAITEXIT 0x200000000ULL #define CLIENT_ALLREDRAWFLAGS \ (CLIENT_REDRAWWINDOW| \ CLIENT_REDRAWSTATUS| \ |