mirror of
https://github.com/tmux/tmux.git
synced 2025-09-04 06:56:58 +00:00
Merge branch 'obsd-master'
Conflicts: Makefile client.c server-client.c server.c tmux.c tmux.h
This commit is contained in:
285
server-client.c
285
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user