diff options
author | Thomas Adam <thomas@xteddy.org> | 2015-10-27 23:27:26 +0000 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2015-10-27 23:27:26 +0000 |
commit | da1f6fc2c8477c99e986061bcdd7c3e854a60076 (patch) | |
tree | f5934e2f96c43f80bad7e3a219230d6337c9d208 | |
parent | 147b5ae5145dc29e9bf4d0ebbc635939b6fdc60b (diff) | |
parent | 44657bf932b068aff5ce1019a4e8a2e7b00b5321 (diff) |
Merge branch 'obsd-master'
Conflicts:
Makefile
client.c
server-client.c
server.c
tmux.c
tmux.h
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | alerts.c | 24 | ||||
-rw-r--r-- | client.c | 516 | ||||
-rw-r--r-- | cmd-attach-session.c | 22 | ||||
-rw-r--r-- | cmd-break-pane.c | 2 | ||||
-rw-r--r-- | cmd-choose-buffer.c | 2 | ||||
-rw-r--r-- | cmd-detach-client.c | 13 | ||||
-rw-r--r-- | cmd-find.c | 14 | ||||
-rw-r--r-- | cmd-move-window.c | 2 | ||||
-rw-r--r-- | cmd-new-session.c | 17 | ||||
-rw-r--r-- | cmd-new-window.c | 4 | ||||
-rw-r--r-- | cmd-rename-window.c | 2 | ||||
-rw-r--r-- | cmd-send-keys.c | 4 | ||||
-rw-r--r-- | cmd-set-option.c | 24 | ||||
-rw-r--r-- | cmd-show-options.c | 14 | ||||
-rw-r--r-- | cmd-split-window.c | 6 | ||||
-rw-r--r-- | cmd-switch-client.c | 2 | ||||
-rw-r--r-- | format.c | 12 | ||||
-rw-r--r-- | input-keys.c | 2 | ||||
-rw-r--r-- | input.c | 6 | ||||
-rw-r--r-- | layout-set.c | 8 | ||||
-rw-r--r-- | names.c | 4 | ||||
-rw-r--r-- | options.c | 28 | ||||
-rw-r--r-- | paste.c | 2 | ||||
-rw-r--r-- | proc.c | 251 | ||||
-rw-r--r-- | resize.c | 8 | ||||
-rw-r--r-- | screen-redraw.c | 6 | ||||
-rw-r--r-- | server-client.c | 261 | ||||
-rw-r--r-- | server-fn.c | 78 | ||||
-rw-r--r-- | server.c | 76 | ||||
-rw-r--r-- | session.c | 19 | ||||
-rw-r--r-- | signal.c | 14 | ||||
-rw-r--r-- | status.c | 56 | ||||
-rw-r--r-- | tmux.1 | 7 | ||||
-rw-r--r-- | tmux.c | 36 | ||||
-rw-r--r-- | tmux.h | 51 | ||||
-rw-r--r-- | tty-keys.c | 2 | ||||
-rw-r--r-- | tty-term.c | 2 | ||||
-rw-r--r-- | tty.c | 8 | ||||
-rw-r--r-- | window-choose.c | 6 | ||||
-rw-r--r-- | window-clock.c | 4 | ||||
-rw-r--r-- | window-copy.c | 34 | ||||
-rw-r--r-- | window.c | 22 |
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 \ @@ -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; @@ -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); |