=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/server-client.c,v retrieving revision 1.161 retrieving revision 1.162 diff -c -r1.161 -r1.162 *** src/usr.bin/tmux/server-client.c 2015/10/26 23:16:18 1.161 --- src/usr.bin/tmux/server-client.c 2015/10/27 13:23:24 1.162 *************** *** 1,4 **** ! /* $OpenBSD: server-client.c,v 1.161 2015/10/26 23:16:18 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: server-client.c,v 1.162 2015/10/27 13:23:24 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott *************** *** 18,27 **** --- 18,29 ---- #include #include + #include #include #include #include + #include #include #include #include *************** *** 42,51 **** 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 *); /* Check if this client is inside this server. */ int --- 44,53 ---- void server_client_reset_state(struct client *); int server_client_assume_paste(struct session *); ! 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 *************** *** 87,94 **** c = xcalloc(1, sizeof *c); c->references = 1; ! imsg_init(&c->ibuf, fd); ! server_update_event(c); if (gettimeofday(&c->creation_time, NULL) != 0) fatal("gettimeofday failed"); --- 89,95 ---- c = xcalloc(1, sizeof *c); c->references = 1; ! c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c); if (gettimeofday(&c->creation_time, NULL) != 0) fatal("gettimeofday failed"); *************** *** 220,229 **** environ_free(&c->environ); ! close(c->ibuf.fd); ! imsg_clear(&c->ibuf); ! if (event_initialized(&c->event)) ! event_del(&c->event); server_client_unref(c); --- 221,228 ---- environ_free(&c->environ); ! proc_remove_peer(c->peer); ! c->peer = NULL; server_client_unref(c); *************** *** 257,296 **** 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) --- 256,261 ---- *************** *** 880,886 **** if (EVBUFFER_LENGTH(c->stderr_data) != 0) return; ! server_write_client(c, MSG_EXIT, &c->retval, sizeof c->retval); c->flags &= ~CLIENT_EXIT; } --- 845,851 ---- if (EVBUFFER_LENGTH(c->stderr_data) != 0) return; ! proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval); c->flags &= ~CLIENT_EXIT; } *************** *** 974,1096 **** } /* Dispatch message from client. */ ! int ! server_client_msg_dispatch(struct client *c) { ! struct imsg imsg; struct msg_stdin_data stdindata; const char *data; ! ssize_t n, datalen; struct session *s; ! if ((n = imsg_read(&c->ibuf)) == -1 || n == 0) ! return (-1); ! 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); } } /* Handle command message. */ void ! server_client_msg_command(struct client *c, struct imsg *imsg) { struct msg_command_data data; char *buf; --- 939,1050 ---- } /* Dispatch message from client. */ ! void ! server_client_dispatch(struct imsg *imsg, void *arg) { ! struct client *c = arg; struct msg_stdin_data stdindata; const char *data; ! ssize_t datalen; struct session *s; ! if (c->flags & CLIENT_DEAD) ! return; ! 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_dispatch_command(struct client *c, struct imsg *imsg) { struct msg_command_data data; char *buf; *************** *** 1143,1149 **** /* Handle identify message. */ void ! server_client_msg_identify(struct client *c, struct imsg *imsg) { const char *data; size_t datalen; --- 1097,1103 ---- /* Handle identify message. */ void ! server_client_dispatch_identify(struct client *c, struct imsg *imsg) { const char *data; size_t datalen; *************** *** 1217,1223 **** if (c->flags & CLIENT_CONTROLCONTROL) evbuffer_add_printf(c->stdout_data, "\033P1000p"); ! server_write_client(c, MSG_STDIN, NULL, 0); c->tty.fd = -1; c->tty.log_fd = -1; --- 1171,1177 ---- if (c->flags & CLIENT_CONTROLCONTROL) evbuffer_add_printf(c->stdout_data, "\033P1000p"); ! proc_send(c->peer, MSG_STDIN, -1, NULL, 0); c->tty.fd = -1; c->tty.log_fd = -1; *************** *** 1248,1261 **** /* Handle shell message. */ void ! server_client_msg_shell(struct client *c) { const char *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); ! c->flags |= CLIENT_BAD; /* it will die after exec */ } --- 1202,1215 ---- /* Handle shell message. */ void ! server_client_dispatch_shell(struct client *c) { const char *shell; shell = options_get_string(&global_s_options, "default-shell"); if (*shell == '\0' || areshell(shell)) shell = _PATH_BSHELL; ! proc_send_s(c->peer, MSG_SHELL, shell); ! proc_kill_peer(c->peer); }