aboutsummaryrefslogtreecommitdiff
path: root/server-client.c
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 /server-client.c
parent147b5ae5145dc29e9bf4d0ebbc635939b6fdc60b (diff)
parent44657bf932b068aff5ce1019a4e8a2e7b00b5321 (diff)
downloadrtmux-da1f6fc2c8477c99e986061bcdd7c3e854a60076.tar.gz
rtmux-da1f6fc2c8477c99e986061bcdd7c3e854a60076.tar.bz2
rtmux-da1f6fc2c8477c99e986061bcdd7c3e854a60076.zip
Merge branch 'obsd-master'
Conflicts: Makefile client.c server-client.c server.c tmux.c tmux.h
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c261
1 files changed, 107 insertions, 154 deletions
diff --git a/server-client.c b/server-client.c
index f818c2fe..924bcc04 100644
--- a/server-client.c
+++ b/server-client.c
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <sys/uio.h>
#include <errno.h>
#include <event.h>
@@ -41,10 +42,10 @@ void server_client_set_title(struct client *);
void server_client_reset_state(struct client *);
int server_client_assume_paste(struct session *);
-int server_client_msg_dispatch(struct client *);
-void server_client_msg_command(struct client *, struct imsg *);
-void server_client_msg_identify(struct client *, struct imsg *);
-void server_client_msg_shell(struct client *);
+void server_client_dispatch(struct imsg *, void *);
+void server_client_dispatch_command(struct client *, struct imsg *);
+void server_client_dispatch_identify(struct client *, struct imsg *);
+void server_client_dispatch_shell(struct client *);
/* Check if this client is inside this server. */
int
@@ -86,8 +87,7 @@ server_client_create(int fd)
c = xcalloc(1, sizeof *c);
c->references = 1;
- imsg_init(&c->ibuf, fd);
- server_update_event(c);
+ c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c);
if (gettimeofday(&c->creation_time, NULL) != 0)
fatal("gettimeofday failed");
@@ -219,10 +219,8 @@ server_client_lost(struct client *c)
environ_free(&c->environ);
- close(c->ibuf.fd);
- imsg_clear(&c->ibuf);
- if (event_initialized(&c->event))
- event_del(&c->event);
+ proc_remove_peer(c->peer);
+ c->peer = NULL;
server_client_unref(c);
@@ -256,40 +254,6 @@ server_client_free(unused int fd, unused short events, void *arg)
free(c);
}
-/* Process a single client event. */
-void
-server_client_callback(int fd, short events, void *data)
-{
- struct client *c = data;
-
- if (c->flags & CLIENT_DEAD)
- return;
-
- if (fd == c->ibuf.fd) {
- if (events & EV_WRITE && msgbuf_write(&c->ibuf.w) <= 0 &&
- errno != EAGAIN)
- goto client_lost;
-
- if (c->flags & CLIENT_BAD) {
- if (c->ibuf.w.queued == 0)
- goto client_lost;
- return;
- }
-
- if (events & EV_READ && server_client_msg_dispatch(c) != 0)
- goto client_lost;
- }
-
- server_push_stdout(c);
- server_push_stderr(c);
-
- server_update_event(c);
- return;
-
-client_lost:
- server_client_lost(c);
-}
-
/* Check for mouse keys. */
int
server_client_check_mouse(struct client *c)
@@ -524,7 +488,7 @@ server_client_assume_paste(struct session *s)
struct timeval tv;
int t;
- if ((t = options_get_number(&s->options, "assume-paste-time")) == 0)
+ if ((t = options_get_number(s->options, "assume-paste-time")) == 0)
return (0);
timersub(&s->activity_time, &s->last_activity_time, &tv);
@@ -590,7 +554,7 @@ server_client_handle_key(struct client *c, int key)
m->valid = 1;
m->key = key;
- if (!options_get_number(&s->options, "mouse"))
+ if (!options_get_number(s->options, "mouse"))
goto forward;
} else
m->valid = 0;
@@ -627,7 +591,7 @@ retry:
* If this is a repeating key, start the timer. Otherwise reset
* the client back to the root table.
*/
- xtimeout = options_get_number(&s->options, "repeat-time");
+ xtimeout = options_get_number(s->options, "repeat-time");
if (xtimeout != 0 && bd->can_repeat) {
c->flags |= CLIENT_REPEAT;
@@ -669,8 +633,8 @@ retry:
* No match, but in the root table. Prefix switches to the prefix table
* and everything else is passed through.
*/
- if (key == options_get_number(&s->options, "prefix") ||
- key == options_get_number(&s->options, "prefix2")) {
+ if (key == options_get_number(s->options, "prefix") ||
+ key == options_get_number(s->options, "prefix2")) {
server_client_key_table(c, "prefix");
server_status_client(c);
return;
@@ -757,7 +721,7 @@ server_client_check_focus(struct window_pane *wp)
int push;
/* Are focus events off? */
- if (!options_get_number(&global_options, "focus-events"))
+ if (!options_get_number(global_options, "focus-events"))
return;
/* Do we need to push the focus state? */
@@ -817,7 +781,7 @@ server_client_reset_state(struct client *c)
struct window *w = c->session->curw->window;
struct window_pane *wp = w->active;
struct screen *s = wp->screen;
- struct options *oo = &c->session->options;
+ struct options *oo = c->session->options;
int status, mode, o;
if (c->flags & CLIENT_SUSPENDED)
@@ -889,7 +853,7 @@ server_client_check_exit(struct client *c)
if (EVBUFFER_LENGTH(c->stderr_data) != 0)
return;
- server_write_client(c, MSG_EXIT, &c->retval, sizeof c->retval);
+ proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval);
c->flags &= ~CLIENT_EXIT;
}
@@ -906,7 +870,7 @@ server_client_check_redraw(struct client *c)
return;
if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
- if (options_get_number(&s->options, "set-titles"))
+ if (options_get_number(s->options, "set-titles"))
server_client_set_title(c);
if (c->message_string != NULL)
@@ -966,7 +930,7 @@ server_client_set_title(struct client *c)
char *title;
struct format_tree *ft;
- template = options_get_string(&s->options, "set-titles-string");
+ template = options_get_string(s->options, "set-titles-string");
ft = format_create();
format_defaults(ft, c, NULL, NULL, NULL);
@@ -983,123 +947,112 @@ server_client_set_title(struct client *c)
}
/* Dispatch message from client. */
-int
-server_client_msg_dispatch(struct client *c)
+void
+server_client_dispatch(struct imsg *imsg, void *arg)
{
- struct imsg imsg;
+ struct client *c = arg;
struct msg_stdin_data stdindata;
const char *data;
- ssize_t n, datalen;
+ ssize_t datalen;
struct session *s;
- if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
- return (-1);
+ if (c->flags & CLIENT_DEAD)
+ return;
- for (;;) {
- if ((n = imsg_get(&c->ibuf, &imsg)) == -1)
- return (-1);
- if (n == 0)
- return (0);
-
- data = imsg.data;
- datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
-
- if (imsg.hdr.peerid != PROTOCOL_VERSION) {
- server_write_client(c, MSG_VERSION, NULL, 0);
- c->flags |= CLIENT_BAD;
- if (imsg.fd != -1)
- close(imsg.fd);
- imsg_free(&imsg);
- continue;
- }
+ if (imsg == NULL) {
+ server_client_lost(c);
+ return;
+ }
- log_debug("got %u from client %p", imsg.hdr.type, c);
- switch (imsg.hdr.type) {
- case MSG_IDENTIFY_FLAGS:
- case MSG_IDENTIFY_TERM:
- case MSG_IDENTIFY_TTYNAME:
- case MSG_IDENTIFY_CWD:
- case MSG_IDENTIFY_STDIN:
- case MSG_IDENTIFY_ENVIRON:
- case MSG_IDENTIFY_CLIENTPID:
- case MSG_IDENTIFY_DONE:
- server_client_msg_identify(c, &imsg);
- break;
- case MSG_COMMAND:
- server_client_msg_command(c, &imsg);
- break;
- case MSG_STDIN:
- if (datalen != sizeof stdindata)
- fatalx("bad MSG_STDIN size");
- memcpy(&stdindata, data, sizeof stdindata);
+ data = imsg->data;
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
- if (c->stdin_callback == NULL)
- break;
- if (stdindata.size <= 0)
- c->stdin_closed = 1;
- else {
- evbuffer_add(c->stdin_data, stdindata.data,
- stdindata.size);
- }
- c->stdin_callback(c, c->stdin_closed,
- c->stdin_callback_data);
- break;
- case MSG_RESIZE:
- if (datalen != 0)
- fatalx("bad MSG_RESIZE size");
+ switch (imsg->hdr.type) {
+ case MSG_IDENTIFY_FLAGS:
+ case MSG_IDENTIFY_TERM:
+ case MSG_IDENTIFY_TTYNAME:
+ case MSG_IDENTIFY_CWD:
+ case MSG_IDENTIFY_STDIN:
+ case MSG_IDENTIFY_ENVIRON:
+ case MSG_IDENTIFY_CLIENTPID:
+ case MSG_IDENTIFY_DONE:
+ server_client_dispatch_identify(c, imsg);
+ break;
+ case MSG_COMMAND:
+ server_client_dispatch_command(c, imsg);
+ break;
+ case MSG_STDIN:
+ if (datalen != sizeof stdindata)
+ fatalx("bad MSG_STDIN size");
+ memcpy(&stdindata, data, sizeof stdindata);
- if (c->flags & CLIENT_CONTROL)
- break;
- if (tty_resize(&c->tty)) {
- recalculate_sizes();
- server_redraw_client(c);
- }
+ if (c->stdin_callback == NULL)
break;
- case MSG_EXITING:
- if (datalen != 0)
- fatalx("bad MSG_EXITING size");
+ if (stdindata.size <= 0)
+ c->stdin_closed = 1;
+ else {
+ evbuffer_add(c->stdin_data, stdindata.data,
+ stdindata.size);
+ }
+ c->stdin_callback(c, c->stdin_closed,
+ c->stdin_callback_data);
+ break;
+ case MSG_RESIZE:
+ if (datalen != 0)
+ fatalx("bad MSG_RESIZE size");
- c->session = NULL;
- tty_close(&c->tty);
- server_write_client(c, MSG_EXITED, NULL, 0);
+ if (c->flags & CLIENT_CONTROL)
break;
- case MSG_WAKEUP:
- case MSG_UNLOCK:
- if (datalen != 0)
- fatalx("bad MSG_WAKEUP size");
-
- if (!(c->flags & CLIENT_SUSPENDED))
- break;
- c->flags &= ~CLIENT_SUSPENDED;
-
- if (c->tty.fd == -1) /* exited in the meantime */
- break;
- s = c->session;
+ if (tty_resize(&c->tty)) {
+ recalculate_sizes();
+ server_redraw_client(c);
+ }
+ break;
+ case MSG_EXITING:
+ if (datalen != 0)
+ fatalx("bad MSG_EXITING size");
- if (gettimeofday(&c->activity_time, NULL) != 0)
- fatal("gettimeofday failed");
- if (s != NULL)
- session_update_activity(s, &c->activity_time);
+ c->session = NULL;
+ tty_close(&c->tty);
+ proc_send(c->peer, MSG_EXITED, -1, NULL, 0);
+ break;
+ case MSG_WAKEUP:
+ case MSG_UNLOCK:
+ if (datalen != 0)
+ fatalx("bad MSG_WAKEUP size");
- tty_start_tty(&c->tty);
- server_redraw_client(c);
- recalculate_sizes();
+ if (!(c->flags & CLIENT_SUSPENDED))
break;
- case MSG_SHELL:
- if (datalen != 0)
- fatalx("bad MSG_SHELL size");
+ c->flags &= ~CLIENT_SUSPENDED;
- server_client_msg_shell(c);
+ if (c->tty.fd == -1) /* exited in the meantime */
break;
- }
+ s = c->session;
+
+ if (gettimeofday(&c->activity_time, NULL) != 0)
+ fatal("gettimeofday failed");
+ if (s != NULL)
+ session_update_activity(s, &c->activity_time);
+
+ tty_start_tty(&c->tty);
+ server_redraw_client(c);
+ recalculate_sizes();
+ break;
+ case MSG_SHELL:
+ if (datalen != 0)
+ fatalx("bad MSG_SHELL size");
- imsg_free(&imsg);
+ server_client_dispatch_shell(c);
+ break;
}
+
+ server_push_stdout(c);
+ server_push_stderr(c);
}
/* Handle command message. */
void
-server_client_msg_command(struct client *c, struct imsg *imsg)
+server_client_dispatch_command(struct client *c, struct imsg *imsg)
{
struct msg_command_data data;
char *buf;
@@ -1152,7 +1105,7 @@ error:
/* Handle identify message. */
void
-server_client_msg_identify(struct client *c, struct imsg *imsg)
+server_client_dispatch_identify(struct client *c, struct imsg *imsg)
{
const char *data;
size_t datalen;
@@ -1231,7 +1184,7 @@ server_client_msg_identify(struct client *c, struct imsg *imsg)
if (c->flags & CLIENT_CONTROLCONTROL)
evbuffer_add_printf(c->stdout_data, "\033P1000p");
- server_write_client(c, MSG_STDIN, NULL, 0);
+ proc_send(c->peer, MSG_STDIN, -1, NULL, 0);
c->tty.fd = -1;
c->tty.log_fd = -1;
@@ -1262,14 +1215,14 @@ server_client_msg_identify(struct client *c, struct imsg *imsg)
/* Handle shell message. */
void
-server_client_msg_shell(struct client *c)
+server_client_dispatch_shell(struct client *c)
{
const char *shell;
- shell = options_get_string(&global_s_options, "default-shell");
+ shell = options_get_string(global_s_options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
- server_write_client(c, MSG_SHELL, shell, strlen(shell) + 1);
+ proc_send_s(c->peer, MSG_SHELL, shell);
- c->flags |= CLIENT_BAD; /* it will die after exec */
+ proc_kill_peer(c->peer);
}