summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2015-10-27 23:27:26 +0000
committerThomas Adam <thomas@xteddy.org>2015-10-27 23:27:26 +0000
commitda1f6fc2c8477c99e986061bcdd7c3e854a60076 (patch)
treef5934e2f96c43f80bad7e3a219230d6337c9d208
parent147b5ae5145dc29e9bf4d0ebbc635939b6fdc60b (diff)
parent44657bf932b068aff5ce1019a4e8a2e7b00b5321 (diff)
Merge branch 'obsd-master'
Conflicts: Makefile client.c server-client.c server.c tmux.c tmux.h
-rw-r--r--Makefile.am1
-rw-r--r--alerts.c24
-rw-r--r--client.c516
-rw-r--r--cmd-attach-session.c22
-rw-r--r--cmd-break-pane.c2
-rw-r--r--cmd-choose-buffer.c2
-rw-r--r--cmd-detach-client.c13
-rw-r--r--cmd-find.c14
-rw-r--r--cmd-move-window.c2
-rw-r--r--cmd-new-session.c17
-rw-r--r--cmd-new-window.c4
-rw-r--r--cmd-rename-window.c2
-rw-r--r--cmd-send-keys.c4
-rw-r--r--cmd-set-option.c24
-rw-r--r--cmd-show-options.c14
-rw-r--r--cmd-split-window.c6
-rw-r--r--cmd-switch-client.c2
-rw-r--r--format.c12
-rw-r--r--input-keys.c2
-rw-r--r--input.c6
-rw-r--r--layout-set.c8
-rw-r--r--names.c4
-rw-r--r--options.c28
-rw-r--r--paste.c2
-rw-r--r--proc.c251
-rw-r--r--resize.c8
-rw-r--r--screen-redraw.c6
-rw-r--r--server-client.c261
-rw-r--r--server-fn.c78
-rw-r--r--server.c76
-rw-r--r--session.c19
-rw-r--r--signal.c14
-rw-r--r--status.c56
-rw-r--r--tmux.17
-rw-r--r--tmux.c36
-rw-r--r--tmux.h51
-rw-r--r--tty-keys.c2
-rw-r--r--tty-term.c2
-rw-r--r--tty.c8
-rw-r--r--window-choose.c6
-rw-r--r--window-clock.c4
-rw-r--r--window-copy.c34
-rw-r--r--window.c22
43 files changed, 860 insertions, 812 deletions
diff --git a/Makefile.am b/Makefile.am
index 8b39ccfc..9cf3bc87 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,6 +154,7 @@ dist_tmux_SOURCES = \
options-table.c \
options.c \
paste.c \
+ proc.c \
resize.c \
screen-redraw.c \
screen-write.c \
diff --git a/alerts.c b/alerts.c
index 806e565b..f1477030 100644
--- a/alerts.c
+++ b/alerts.c
@@ -80,11 +80,11 @@ alerts_enabled(struct window *w, int flags)
struct session *s;
if (flags & WINDOW_ACTIVITY) {
- if (options_get_number(&w->options, "monitor-activity"))
+ if (options_get_number(w->options, "monitor-activity"))
return (1);
}
if (flags & WINDOW_SILENCE) {
- if (options_get_number(&w->options, "monitor-silence") != 0)
+ if (options_get_number(w->options, "monitor-silence") != 0)
return (1);
}
if (~flags & WINDOW_BELL)
@@ -92,7 +92,7 @@ alerts_enabled(struct window *w, int flags)
RB_FOREACH(s, sessions, &sessions) {
if (!session_has(s, w))
continue;
- if (options_get_number(&s->options, "bell-action") != BELL_NONE)
+ if (options_get_number(s->options, "bell-action") != BELL_NONE)
return (1);
}
return (0);
@@ -116,7 +116,7 @@ alerts_reset(struct window *w)
event_del(&w->alerts_timer);
timerclear(&tv);
- tv.tv_sec = options_get_number(&w->options, "monitor-silence");
+ tv.tv_sec = options_get_number(w->options, "monitor-silence");
log_debug("@%u alerts timer reset %u", w->id, (u_int)tv.tv_sec);
if (tv.tv_sec != 0)
@@ -160,11 +160,11 @@ alerts_check_bell(struct session *s, struct winlink *wl)
if (s->curw->window == w)
w->flags &= ~WINDOW_BELL;
- action = options_get_number(&s->options, "bell-action");
+ action = options_get_number(s->options, "bell-action");
if (action == BELL_NONE)
return (0);
- visual = options_get_number(&s->options, "visual-bell");
+ visual = options_get_number(s->options, "visual-bell");
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s || c->flags & CLIENT_CONTROL)
continue;
@@ -201,14 +201,14 @@ alerts_check_activity(struct session *s, struct winlink *wl)
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
return (0);
- if (!options_get_number(&w->options, "monitor-activity"))
+ if (!options_get_number(w->options, "monitor-activity"))
return (0);
- if (options_get_number(&s->options, "bell-on-alert"))
+ if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_ACTIVITY;
- if (options_get_number(&s->options, "visual-activity")) {
+ if (options_get_number(s->options, "visual-activity")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
@@ -233,14 +233,14 @@ alerts_check_silence(struct session *s, struct winlink *wl)
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
return (0);
- if (options_get_number(&w->options, "monitor-silence") == 0)
+ if (options_get_number(w->options, "monitor-silence") == 0)
return (0);
- if (options_get_number(&s->options, "bell-on-alert"))
+ if (options_get_number(s->options, "bell-on-alert"))
alerts_ring_bell(s);
wl->flags |= WINLINK_SILENCE;
- if (options_get_number(&s->options, "visual-silence")) {
+ if (options_get_number(s->options, "visual-silence")) {
TAILQ_FOREACH(c, &clients, entry) {
if (c->session != s)
continue;
diff --git a/client.c b/client.c
index 6c9f0fcd..66bc0dab 100644
--- a/client.c
+++ b/client.c
@@ -33,10 +33,10 @@
#include "tmux.h"
-int client_flags;
-struct imsgbuf client_ibuf;
-struct event client_event;
-struct event client_stdin;
+struct tmuxproc *client_proc;
+struct tmuxpeer *client_peer;
+int client_flags;
+struct event client_stdin;
enum {
CLIENT_EXIT_NONE,
CLIENT_EXIT_DETACHED,
@@ -47,24 +47,21 @@ enum {
CLIENT_EXIT_EXITED,
CLIENT_EXIT_SERVER_EXITED,
} client_exitreason = CLIENT_EXIT_NONE;
-int client_exitval;
-enum msgtype client_exittype;
-const char *client_exitsession;
-int client_attached;
+int client_exitval;
+enum msgtype client_exittype;
+const char *client_exitsession;
+int client_attached;
__dead void client_exec(const char *);
int client_get_lock(char *);
int client_connect(struct event_base *, char *, int);
void client_send_identify(const char *, const char *);
-int client_write_one(enum msgtype, int, const void *, size_t);
-int client_write_server(enum msgtype, const void *, size_t);
-void client_update_event(void);
-void client_signal(int, short, void *);
void client_stdin_callback(int, short, void *);
void client_write(int, const char *, size_t);
-void client_callback(int, short, void *);
-int client_dispatch_attached(void);
-int client_dispatch_wait(void);
+void client_signal(int);
+void client_dispatch(struct imsg *, void *);
+void client_dispatch_attached(struct imsg *);
+void client_dispatch_wait(struct imsg *);
const char *client_exit_message(void);
/*
@@ -222,6 +219,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
struct termios tio, saved_tio;
size_t size;
+ /* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
+ signal(SIGCHLD, SIG_IGN);
+
/* Save the flags. */
client_flags = flags;
@@ -254,9 +254,6 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
cmd_list_free(cmdlist);
}
- /* Establish signal handlers. */
- set_signals(client_signal);
-
/* Initialize the client socket and start the server. */
fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER);
if (fd == -1) {
@@ -270,6 +267,10 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
return (1);
}
+ /* Build process state. */
+ client_proc = proc_start("client", base, 0, client_signal);
+ client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL);
+
/* Save these before pledge(). */
if ((cwd = getcwd(path, sizeof path)) == NULL)
cwd = "/";
@@ -291,21 +292,11 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
#endif
/* Free stuff that is not used in the client. */
- options_free(&global_options);
- options_free(&global_s_options);
- options_free(&global_w_options);
+ options_free(global_options);
+ options_free(global_s_options);
+ options_free(global_w_options);
environ_free(&global_environ);
- /* Set process title, log and signals now this is the client. */
-#ifdef HAVE_SETPROCTITLE
- setproctitle("client (%s)", socket_path);
-#endif
- logfile("client");
-
- /* Create imsg. */
- imsg_init(&client_ibuf, fd);
- event_set(&client_event, fd, EV_READ, client_callback, NULL);
-
/* Create stdin handler. */
setblocking(STDIN_FILENO, 0);
event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
@@ -351,18 +342,17 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
size += sizeof *data;
/* Send the command. */
- if (client_write_server(msg, data, size) != 0) {
+ if (proc_send(client_peer, msg, -1, data, size) != 0) {
fprintf(stderr, "failed to send command\n");
free(data);
return (1);
}
free(data);
} else if (msg == MSG_SHELL)
- client_write_server(msg, NULL, 0);
+ proc_send(client_peer, msg, -1, NULL, 0);
- /* Set the event and dispatch. */
- client_update_event();
- event_dispatch();
+ /* Start main loop. */
+ proc_loop(client_proc, NULL);
/* Print the exit message, if any, and exit. */
if (client_attached) {
@@ -394,144 +384,29 @@ client_send_identify(const char *ttynam, const char *cwd)
int fd, flags = client_flags;
pid_t pid;
- client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
+ proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
if ((s = getenv("TERM")) == NULL)
s = "";
- client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
+ proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
- client_write_one(MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1);
- client_write_one(MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1);
+ proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1);
+ proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1);
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
- client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
+ proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
pid = getpid();
- client_write_one(MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
+ proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
for (ss = environ; *ss != NULL; ss++) {
sslen = strlen(*ss) + 1;
if (sslen <= MAX_IMSGSIZE - IMSG_HEADER_SIZE)
- client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
- }
-
- client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
-}
-
-/* Helper to send one message. */
-int
-client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
-{
- int retval;
-
- retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd,
- (void *)buf, len);
- if (retval != 1)
- return (-1);
- return (0);
-}
-
-/* Write a message to the server without a file descriptor. */
-int
-client_write_server(enum msgtype type, const void *buf, size_t len)
-{
- int retval;
-
- retval = client_write_one(type, -1, buf, len);
- if (retval == 0)
- client_update_event();
- return (retval);
-}
-
-/* Update client event based on whether it needs to read or read and write. */
-void
-client_update_event(void)
-{
- short events;
-
- event_del(&client_event);
- events = EV_READ;
- if (client_ibuf.w.queued > 0)
- events |= EV_WRITE;
- event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
- event_add(&client_event, NULL);
-}
-
-/* Callback to handle signals in the client. */
-void
-client_signal(int sig, unused short events, unused void *arg)
-{
- struct sigaction sigact;
- int status;
-
- if (sig == SIGCHLD)
- waitpid(WAIT_ANY, &status, WNOHANG);
- else if (!client_attached) {
- if (sig == SIGTERM)
- event_loopexit(NULL);
- } else {
- switch (sig) {
- case SIGHUP:
- client_exitreason = CLIENT_EXIT_LOST_TTY;
- client_exitval = 1;
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case SIGTERM:
- client_exitreason = CLIENT_EXIT_TERMINATED;
- client_exitval = 1;
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case SIGWINCH:
- client_write_server(MSG_RESIZE, NULL, 0);
- break;
- case SIGCONT:
- memset(&sigact, 0, sizeof sigact);
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = SA_RESTART;
- sigact.sa_handler = SIG_IGN;
- if (sigaction(SIGTSTP, &sigact, NULL) != 0)
- fatal("sigaction failed");
- client_write_server(MSG_WAKEUP, NULL, 0);
- break;
- }
+ proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
}
- client_update_event();
-}
-
-/* Callback for client imsg read events. */
-void
-client_callback(unused int fd, short events, unused void *arg)
-{
- ssize_t n;
- int retval;
-
- if (events & EV_READ) {
- if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
- goto lost_server;
- if (client_attached)
- retval = client_dispatch_attached();
- else
- retval = client_dispatch_wait();
- if (retval != 0) {
- event_loopexit(NULL);
- return;
- }
- }
-
- if (events & EV_WRITE) {
- if (msgbuf_write(&client_ibuf.w) <= 0 && errno != EAGAIN)
- goto lost_server;
- }
-
- client_update_event();
- return;
-
-lost_server:
- client_exitreason = CLIENT_EXIT_LOST_SERVER;
- client_exitval = 1;
- event_loopexit(NULL);
+ proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
}
/* Callback for client stdin read events. */
@@ -544,10 +419,9 @@ client_stdin_callback(unused int fd, unused short events, unused void *arg)
if (data.size < 0 && (errno == EINTR || errno == EAGAIN))
return;
- client_write_server(MSG_STDIN, &data, sizeof data);
+ proc_send(client_peer, MSG_STDIN, -1, &data, sizeof data);
if (data.size <= 0)
event_del(&client_stdin);
- client_update_event();
}
/* Force write to file descriptor. */
@@ -597,13 +471,65 @@ client_exec(const char *shell)
fatal("execl failed");
}
+/* Callback to handle signals in the client. */
+void
+client_signal(int sig)
+{
+ struct sigaction sigact;
+ int status;
+
+ if (sig == SIGCHLD)
+ waitpid(WAIT_ANY, &status, WNOHANG);
+ else if (!client_attached) {
+ if (sig == SIGTERM)
+ proc_exit(client_proc);
+ } else {
+ switch (sig) {
+ case SIGHUP:
+ client_exitreason = CLIENT_EXIT_LOST_TTY;
+ client_exitval = 1;
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ break;
+ case SIGTERM:
+ client_exitreason = CLIENT_EXIT_TERMINATED;
+ client_exitval = 1;
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ break;
+ case SIGWINCH:
+ proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
+ break;
+ case SIGCONT:
+ memset(&sigact, 0, sizeof sigact);
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = SA_RESTART;
+ sigact.sa_handler = SIG_IGN;
+ if (sigaction(SIGTSTP, &sigact, NULL) != 0)
+ fatal("sigaction failed");
+ proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0);
+ break;
+ }
+ }
+}
+
+/* Callback for client read events. */
+void
+client_dispatch(struct imsg *imsg, unused void *arg)
+{
+ if (imsg == NULL) {
+ client_exitreason = CLIENT_EXIT_LOST_SERVER;
+ client_exitval = 1;
+ } else if (client_attached)
+ client_dispatch_attached(imsg);
+ else
+ client_dispatch_wait(imsg);
+}
+
/* Dispatch imsgs when in wait state (before MSG_READY). */
-int
-client_dispatch_wait(void)
+void
+client_dispatch_wait(struct imsg *imsg)
{
- struct imsg imsg;
char *data;
- ssize_t n, datalen;
+ ssize_t datalen;
struct msg_stdout_data stdoutdata;
struct msg_stderr_data stderrdata;
int retval;
@@ -623,163 +549,141 @@ client_dispatch_wait(void)
};
#endif
- for (;;) {
- if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
- fatalx("imsg_get failed");
- if (n == 0)
- return (0);
-
- data = imsg.data;
- datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
-
- log_debug("got %u from server", imsg.hdr.type);
- switch (imsg.hdr.type) {
- case MSG_EXIT:
- case MSG_SHUTDOWN:
- if (datalen != sizeof retval && datalen != 0)
- fatalx("bad MSG_EXIT size");
- if (datalen == sizeof retval) {
- memcpy(&retval, data, sizeof retval);
- client_exitval = retval;
- }
- imsg_free(&imsg);
- return (-1);
- case MSG_READY:
- if (datalen != 0)
- fatalx("bad MSG_READY size");
-
- event_del(&client_stdin);
- client_attached = 1;
- client_write_server(MSG_RESIZE, NULL, 0);
- break;
- case MSG_STDIN:
- if (datalen != 0)
- fatalx("bad MSG_STDIN size");
-
- event_add(&client_stdin, NULL);
- break;
- case MSG_STDOUT:
- if (datalen != sizeof stdoutdata)
- fatalx("bad MSG_STDOUT size");
- memcpy(&stdoutdata, data, sizeof stdoutdata);
-
- client_write(STDOUT_FILENO, stdoutdata.data,
- stdoutdata.size);
- break;
- case MSG_STDERR:
- if (datalen != sizeof stderrdata)
- fatalx("bad MSG_STDERR size");
- memcpy(&stderrdata, data, sizeof stderrdata);
+ data = imsg->data;
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+
+ switch (imsg->hdr.type) {
+ case MSG_EXIT:
+ case MSG_SHUTDOWN:
+ if (datalen != sizeof retval && datalen != 0)
+ fatalx("bad MSG_EXIT size");
+ if (datalen == sizeof retval) {
+ memcpy(&retval, data, sizeof retval);
+ client_exitval = retval;
+ }
+ proc_exit(client_proc);
+ break;
+ case MSG_READY:
+ if (datalen != 0)
+ fatalx("bad MSG_READY size");
- client_write(STDERR_FILENO, stderrdata.data,
- stderrdata.size);
- break;
- case MSG_VERSION:
- if (datalen != 0)
- fatalx("bad MSG_VERSION size");
+ event_del(&client_stdin);
+ client_attached = 1;
+ proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
+ break;
+ case MSG_STDIN:
+ if (datalen != 0)
+ fatalx("bad MSG_STDIN size");
- fprintf(stderr, "protocol version mismatch "
- "(client %d, server %u)\n", PROTOCOL_VERSION,
- imsg.hdr.peerid);
- client_exitval = 1;
+ event_add(&client_stdin, NULL);
+ break;
+ case MSG_STDOUT:
+ if (datalen != sizeof stdoutdata)
+ fatalx("bad MSG_STDOUT size");
+ memcpy(&stdoutdata, data, sizeof stdoutdata);
- imsg_free(&imsg);
- return (-1);
- case MSG_SHELL:
- if (datalen == 0 || data[datalen - 1] != '\0')
- fatalx("bad MSG_SHELL string");
-
- clear_signals(0);
- client_exec(data);
- /* NOTREACHED */
- case MSG_DETACH:
- case MSG_DETACHKILL:
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case MSG_EXITED:
- imsg_free(&imsg);
- return (-1);
- }
+ client_write(STDOUT_FILENO, stdoutdata.data,
+ stdoutdata.size);
+ break;
+ case MSG_STDERR:
+ if (datalen != sizeof stderrdata)
+ fatalx("bad MSG_STDERR size");
+ memcpy(&stderrdata, data, sizeof stderrdata);
- imsg_free(&imsg);
+ client_write(STDERR_FILENO, stderrdata.data,
+ stderrdata.size);
+ break;
+ case MSG_VERSION:
+ if (datalen != 0)
+ fatalx("bad MSG_VERSION size");
+
+ fprintf(stderr, "protocol version mismatch "
+ "(client %d, server %u)\n", PROTOCOL_VERSION,
+ imsg->hdr.peerid);
+ client_exitval = 1;
+ proc_exit(client_proc);
+ break;
+ case MSG_SHELL:
+ if (datalen == 0 || data[datalen - 1] != '\0')
+ fatalx("bad MSG_SHELL string");
+
+ clear_signals(0);
+ client_exec(data);
+ /* NOTREACHED */
+ case MSG_DETACH:
+ case MSG_DETACHKILL:
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ break;
+ case MSG_EXITED:
+ proc_exit(client_proc);
+ break;
}
}
/* Dispatch imsgs in attached state (after MSG_READY). */
-int
-client_dispatch_attached(void)
+void
+client_dispatch_attached(struct imsg *imsg)
{
- struct imsg imsg;
struct sigaction sigact;
char *data;
- ssize_t n, datalen;
-
- for (;;) {
- if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
- fatalx("imsg_get failed");
- if (n == 0)
- return (0);
-
- data = imsg.data;
- datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
-
- log_debug("got %u from server", imsg.hdr.type);
- switch (imsg.hdr.type) {
- case MSG_DETACH:
- case MSG_DETACHKILL:
- if (datalen == 0 || data[datalen - 1] != '\0')
- fatalx("bad MSG_DETACH string");
-
- client_exitsession = xstrdup(data);
- client_exittype = imsg.hdr.type;
- if (imsg.hdr.type == MSG_DETACHKILL)
- client_exitreason = CLIENT_EXIT_DETACHED_HUP;
- else
- client_exitreason = CLIENT_EXIT_DETACHED;
- client_write_server(MSG_EXITING, NULL, 0);
- break;
- case MSG_EXIT:
- if (datalen != 0 && datalen != sizeof (int))
- fatalx("bad MSG_EXIT size");
+ ssize_t datalen;
- client_write_server(MSG_EXITING, NULL, 0);
- client_exitreason = CLIENT_EXIT_EXITED;
- break;
- case MSG_EXITED:
- if (datalen != 0)
- fatalx("bad MSG_EXITED size");
+ data = imsg->data;
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
- imsg_free(&imsg);
- return (-1);
- case MSG_SHUTDOWN:
- if (datalen != 0)
- fatalx("bad MSG_SHUTDOWN size");
+ switch (imsg->hdr.type) {
+ case MSG_DETACH:
+ case MSG_DETACHKILL:
+ if (datalen == 0 || data[datalen - 1] != '\0')
+ fatalx("bad MSG_DETACH string");
- client_write_server(MSG_EXITING, NULL, 0);
- client_exitreason = CLIENT_EXIT_SERVER_EXITED;
- client_exitval = 1;
- break;
- case MSG_SUSPEND:
- if (datalen != 0)
- fatalx("bad MSG_SUSPEND size");
+ client_exitsession = xstrdup(data);
+ client_exittype = imsg->hdr.type;
+ if (imsg->hdr.type == MSG_DETACHKILL)
+ client_exitreason = CLIENT_EXIT_DETACHED_HUP;
+ else
+ client_exitreason = CLIENT_EXIT_DETACHED;
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ break;
+ case MSG_EXIT:
+ if (datalen != 0 && datalen != sizeof (int))
+ fatalx("bad MSG_EXIT size");
- memset(&sigact, 0, sizeof sigact);
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = SA_RESTART;
- sigact.sa_handler = SIG_DFL;
- if (sigaction(SIGTSTP, &sigact, NULL) != 0)
- fatal("sigaction failed");
- kill(getpid(), SIGTSTP);
- break;
- case MSG_LOCK:
- if (datalen == 0 || data[datalen - 1] != '\0')
- fatalx("bad MSG_LOCK string");
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ client_exitreason = CLIENT_EXIT_EXITED;
+ break;
+ case MSG_EXITED:
+ if (datalen != 0)
+ fatalx("bad MSG_EXITED size");
- system(data);
- client_write_server(MSG_UNLOCK, NULL, 0);
- break;
- }
+ proc_exit(client_proc);
+ break;
+ case MSG_SHUTDOWN:
+ if (datalen != 0)
+ fatalx("bad MSG_SHUTDOWN size");
- imsg_free(&imsg);
+ proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
+ client_exitreason = CLIENT_EXIT_SERVER_EXITED;
+ client_exitval = 1;
+ break;
+ case MSG_SUSPEND:
+ if (datalen != 0)
+ fatalx("bad MSG_SUSPEND size");
+
+ memset(&sigact, 0, sizeof sigact);
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = SA_RESTART;
+ sigact.sa_handler = SIG_DFL;
+ if (sigaction(SIGTSTP, &sigact, NULL) != 0)
+ fatal("sigaction failed");
+ kill(getpid(), SIGTSTP);
+ break;
+ case MSG_LOCK:
+ if (datalen == 0 || data[datalen - 1] != '\0')
+ fatalx("bad MSG_LOCK string");
+
+ system(data);
+ proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0);
+ break;
}
}
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index a7ef1cd9..a3623ec4 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -113,21 +113,15 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
if (c->session != NULL) {
if (dflag) {
- /*
- * Can't use server_write_session in case attaching to
- * the same session as currently attached to.
- */
TAILQ_FOREACH(c_loop, &clients, entry) {
if (c_loop->session != s || c == c_loop)
continue;
- server_write_client(c, MSG_DETACH,
- c_loop->session->name,
- strlen(c_loop->session->name) + 1);
+ proc_send_s(c->peer, MSG_DETACH, s->name);
}
}
if (!Eflag) {
- update = options_get_string(&s->options,
+ update = options_get_string(s->options,
"update-environment");
environ_update(update, &c->environ, &s->environ);
}
@@ -150,12 +144,15 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
c->flags |= CLIENT_READONLY;
if (dflag) {
- server_write_session(s, MSG_DETACH, s->name,
- strlen(s->name) + 1);
+ TAILQ_FOREACH(c_loop, &clients, entry) {
+ if (c_loop->session != s || c == c_loop)
+ continue;
+ proc_send_s(c->peer, MSG_DETACH, s->name);
+ }
}
if (!Eflag) {
- update = options_get_string(&s->options,
+ update = options_get_string(s->options,
"update-environment");
environ_update(update, &c->environ, &s->environ);
}
@@ -168,7 +165,8 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
server_redraw_client(c);
s->curw->flags &= ~WINLINK_ALERTFLAGS;
- server_write_ready(c);
+ if (~c->flags & CLIENT_CONTROL)
+ proc_send(c->peer, MSG_READY, -1, NULL, 0);
cmdq->client_exit = 0;
}
recalculate_sizes();
diff --git a/cmd-break-pane.c b/cmd-break-pane.c
index 2aa5c5b7..39179cc7 100644
--- a/cmd-break-pane.c
+++ b/cmd-break-pane.c
@@ -84,7 +84,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
layout_init(w, wp);
if (idx == -1)
- idx = -1 - options_get_number(&dst_s->options, "base-index");
+ idx = -1 - options_get_number(dst_s->options, "base-index");
wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
if (!args_has(self->args, 'd'))
session_select(dst_s, wl->idx);
diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c
index b4590306..e790de6b 100644
--- a/c