diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-05-16 16:07:56 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2020-05-16 16:07:56 +0000 |
commit | 3e697fabd80c0f7ca6d38cd29ff1cb120993a466 (patch) | |
tree | 638de34e5cb821be9ab02b94868108cc123eb2e0 | |
parent | 90963891c95c46dd2a21445906034c50d8c66f0a (diff) |
Add a -D flag to ask tmux not to daemonize, useful both for running a
debugger (lldb does not have follow-fork-mode) and for running with a
managed supervisor init system. GitHub issue 2190.
-rw-r--r-- | usr.bin/tmux/proc.c | 11 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 17 | ||||
-rw-r--r-- | usr.bin/tmux/server.c | 46 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 15 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.c | 11 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 3 | ||||
-rw-r--r-- | usr.bin/tmux/tty.c | 9 |
7 files changed, 80 insertions, 32 deletions
diff --git a/usr.bin/tmux/proc.c b/usr.bin/tmux/proc.c index 2192f0422a7..1a85abe457e 100644 --- a/usr.bin/tmux/proc.c +++ b/usr.bin/tmux/proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.c,v 1.16 2020/01/28 10:44:30 nicm Exp $ */ +/* $OpenBSD: proc.c,v 1.17 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -37,6 +37,7 @@ struct tmuxproc { void (*signalcb)(int); + struct event ev_sigint; struct event ev_sighup; struct event ev_sigchld; struct event ev_sigcont; @@ -221,10 +222,13 @@ proc_set_signals(struct tmuxproc *tp, void (*signalcb)(int)) sa.sa_flags = SA_RESTART; sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGTSTP, &sa, NULL); + sigaction(SIGTTIN, &sa, NULL); + sigaction(SIGTTOU, &sa, NULL); + signal_set(&tp->ev_sigint, SIGINT, proc_signal_cb, tp); + signal_add(&tp->ev_sigint, NULL); signal_set(&tp->ev_sighup, SIGHUP, proc_signal_cb, tp); signal_add(&tp->ev_sighup, NULL); signal_set(&tp->ev_sigchld, SIGCHLD, proc_signal_cb, tp); @@ -251,10 +255,10 @@ proc_clear_signals(struct tmuxproc *tp, int defaults) sa.sa_flags = SA_RESTART; sa.sa_handler = SIG_DFL; - sigaction(SIGINT, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGTSTP, &sa, NULL); + signal_del(&tp->ev_sigint); signal_del(&tp->ev_sighup); signal_del(&tp->ev_sigchld); signal_del(&tp->ev_sigcont); @@ -264,6 +268,7 @@ proc_clear_signals(struct tmuxproc *tp, int defaults) signal_del(&tp->ev_sigwinch); if (defaults) { + sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGCONT, &sa, NULL); diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 21454a9ad10..6d807fa994b 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.338 2020/05/16 15:47:22 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.339 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -238,11 +238,22 @@ server_client_create(int fd) int server_client_open(struct client *c, char **cause) { + const char *ttynam = _PATH_TTY; + if (c->flags & CLIENT_CONTROL) return (0); - if (strcmp(c->ttyname, "/dev/tty") == 0) { - *cause = xstrdup("can't use /dev/tty"); + if (strcmp(c->ttyname, ttynam) == 0|| + ((isatty(STDIN_FILENO) && + (ttynam = ttyname(STDIN_FILENO)) != NULL && + strcmp(c->ttyname, ttynam) == 0) || + (isatty(STDOUT_FILENO) && + (ttynam = ttyname(STDOUT_FILENO)) != NULL && + strcmp(c->ttyname, ttynam) == 0) || + (isatty(STDERR_FILENO) && + (ttynam = ttyname(STDERR_FILENO)) != NULL && + strcmp(c->ttyname, ttynam) == 0))) { + xasprintf(cause, "can't use %s", c->ttyname); return (-1); } diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index 842bc7fd346..0cfbb5fce48 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.190 2020/05/16 15:47:22 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.191 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -161,29 +161,35 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base, struct client *c; char *cause = NULL; - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) - fatal("socketpair failed"); - server_client_flags = flags; - sigfillset(&set); sigprocmask(SIG_BLOCK, &set, &oldset); - switch (fork()) { - case -1: - fatal("fork failed"); - case 0: - break; - default: - sigprocmask(SIG_SETMASK, &oldset, NULL); - close(pair[1]); - return (pair[0]); + + if (~flags & CLIENT_NOFORK) { + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) + fatal("socketpair failed"); + + switch (fork()) { + case -1: + fatal("fork failed"); + case 0: + break; + default: + sigprocmask(SIG_SETMASK, &oldset, NULL); + close(pair[1]); + return (pair[0]); + } + close(pair[0]); + if (daemon(1, 0) != 0) + fatal("daemon failed"); } - close(pair[0]); - if (daemon(1, 0) != 0) - fatal("daemon failed"); + + server_client_flags = flags; proc_clear_signals(client, 0); + if (event_reinit(base) != 0) fatalx("event_reinit failed"); server_proc = proc_start("server"); + proc_set_signals(server_proc, server_signal); sigprocmask(SIG_SETMASK, &oldset, NULL); @@ -205,7 +211,10 @@ server_start(struct tmuxproc *client, int flags, struct event_base *base, server_fd = server_create_socket(flags, &cause); if (server_fd != -1) server_update_socket(); - c = server_client_create(pair[1]); + if (~flags & CLIENT_NOFORK) + c = server_client_create(pair[1]); + else + options_set_number(global_options, "exit-empty", 0); if (lockfd >= 0) { unlink(lockfile); @@ -396,6 +405,7 @@ server_signal(int sig) log_debug("%s: %s", __func__, strsignal(sig)); switch (sig) { + case SIGINT: case SIGTERM: server_exit = 1; server_send_exit(); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index ea3c06f4565..bb8a2e3313e 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.766 2020/05/16 16:02:24 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.767 2020/05/16 16:07:55 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -23,7 +23,7 @@ .Sh SYNOPSIS .Nm tmux .Bk -words -.Op Fl 2CluvV +.Op Fl 2CDluvV .Op Fl c Ar shell-command .Op Fl f Ar file .Op Fl L Ar socket-name @@ -122,6 +122,17 @@ This option is for compatibility with when .Nm is used as a login shell. +.It Fl D +Do not start the +.Nm +server as a daemon. +This also turns the +.Ic exit-empty +option off. +With +.Fl D , +.Ar command +may not be specified. .It Fl f Ar file Specify an alternative configuration file. By default, diff --git a/usr.bin/tmux/tmux.c b/usr.bin/tmux/tmux.c index 214bbfebb4c..13346c966cf 100644 --- a/usr.bin/tmux/tmux.c +++ b/usr.bin/tmux/tmux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.c,v 1.200 2020/05/16 15:24:28 nicm Exp $ */ +/* $OpenBSD: tmux.c,v 1.201 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -57,7 +57,7 @@ static __dead void usage(void) { fprintf(stderr, - "usage: %s [-2CluvV] [-c shell-command] [-f file] [-L socket-name]\n" + "usage: %s [-2CDluvV] [-c shell-command] [-f file] [-L socket-name]\n" " [-S socket-path] [-T features] [command [flags]]\n", getprogname()); exit(1); @@ -336,7 +336,7 @@ main(int argc, char **argv) if (**argv == '-') flags = CLIENT_LOGIN; - while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:T:uUvV")) != -1) { + while ((opt = getopt(argc, argv, "2c:CDdf:lL:qS:T:uUvV")) != -1) { switch (opt) { case '2': tty_add_features(&feat, "256", ":,"); @@ -344,6 +344,9 @@ main(int argc, char **argv) case 'c': shell_command = optarg; break; + case 'D': + flags |= CLIENT_NOFORK; + break; case 'C': if (flags & CLIENT_CONTROL) flags |= CLIENT_CONTROLCONTROL; @@ -387,6 +390,8 @@ main(int argc, char **argv) if (shell_command != NULL && argc != 0) usage(); + if ((flags & CLIENT_NOFORK) && argc != 0) + usage(); if ((ptm_fd = getptmfd()) == -1) err(1, "getptmfd"); diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 0a7177f1ab5..18010db9aaa 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1037 2020/05/16 16:02:24 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1038 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1584,6 +1584,7 @@ struct client { #define CLIENT_DEFAULTSOCKET 0x8000000 #define CLIENT_STARTSERVER 0x10000000 #define CLIENT_REDRAWPANES 0x20000000 +#define CLIENT_NOFORK 0x40000000 #define CLIENT_ALLREDRAWFLAGS \ (CLIENT_REDRAWWINDOW| \ CLIENT_REDRAWSTATUS| \ diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c index 277cb95661a..f9ae50a3ff4 100644 --- a/usr.bin/tmux/tty.c +++ b/usr.bin/tmux/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.374 2020/05/16 15:36:57 nicm Exp $ */ +/* $OpenBSD: tty.c,v 1.375 2020/05/16 16:07:55 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -154,16 +154,21 @@ tty_read_callback(__unused int fd, __unused short events, void *data) { struct tty *tty = data; struct client *c = tty->client; + const char *name = c->name; size_t size = EVBUFFER_LENGTH(tty->in); int nread; nread = evbuffer_read(tty->in, tty->fd, -1); if (nread == 0 || nread == -1) { + if (nread == 0) + log_debug("%s: read closed", name); + else + log_debug("%s: read error: %s", name, strerror(errno)); event_del(&tty->event_in); server_client_lost(tty->client); return; } - log_debug("%s: read %d bytes (already %zu)", c->name, nread, size); + log_debug("%s: read %d bytes (already %zu)", name, nread, size); while (tty_keys_next(tty)) ; |