Merge branch 'obsd-master'

Conflicts:
	Makefile
	client.c
	server-client.c
	server.c
	tmux.c
	tmux.h
This commit is contained in:
Thomas Adam
2015-10-27 23:27:26 +00:00
43 changed files with 872 additions and 824 deletions

View File

@ -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;
}
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);
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");
if (c->flags & CLIENT_CONTROL)
break;
if (tty_resize(&c->tty)) {
recalculate_sizes();
server_redraw_client(c);
}
break;
case MSG_EXITING:
if (datalen != 0)
fatalx("bad MSG_EXITING size");
c->session = NULL;
tty_close(&c->tty);
server_write_client(c, MSG_EXITED, NULL, 0);
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 (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");
server_client_msg_shell(c);
break;
}
imsg_free(&imsg);
if (imsg == NULL) {
server_client_lost(c);
return;
}
data = imsg->data;
datalen = imsg->hdr.len - IMSG_HEADER_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->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");
if (c->flags & CLIENT_CONTROL)
break;
if (tty_resize(&c->tty)) {
recalculate_sizes();
server_redraw_client(c);
}
break;
case MSG_EXITING:
if (datalen != 0)
fatalx("bad MSG_EXITING size");
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");
if (!(c->flags & CLIENT_SUSPENDED))
break;
c->flags &= ~CLIENT_SUSPENDED;
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");
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);
}