=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/server-client.c,v retrieving revision 1.72 retrieving revision 1.73 diff -u -r1.72 -r1.73 --- src/usr.bin/tmux/server-client.c 2012/05/06 07:38:17 1.72 +++ src/usr.bin/tmux/server-client.c 2012/05/21 18:27:42 1.73 @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.72 2012/05/06 07:38:17 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.73 2012/05/21 18:27:42 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -35,9 +35,6 @@ void server_client_check_redraw(struct client *); void server_client_set_title(struct client *); void server_client_reset_state(struct client *); -void server_client_in_callback(struct bufferevent *, short, void *); -void server_client_out_callback(struct bufferevent *, short, void *); -void server_client_err_callback(struct bufferevent *, short, void *); int server_client_msg_dispatch(struct client *); void server_client_msg_command(struct client *, struct msg_command_data *); @@ -67,9 +64,9 @@ fatal("gettimeofday failed"); memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); - c->stdin_event = NULL; - c->stdout_event = NULL; - c->stderr_event = NULL; + c->stdin_data = evbuffer_new (); + c->stdout_data = evbuffer_new (); + c->stderr_data = evbuffer_new (); c->tty.fd = -1; c->title = NULL; @@ -144,24 +141,9 @@ if (c->flags & CLIENT_TERMINAL) tty_free(&c->tty); - if (c->stdin_event != NULL) - bufferevent_free(c->stdin_event); - if (c->stdin_fd != -1) { - setblocking(c->stdin_fd, 1); - close(c->stdin_fd); - } - if (c->stdout_event != NULL) - bufferevent_free(c->stdout_event); - if (c->stdout_fd != -1) { - setblocking(c->stdout_fd, 1); - close(c->stdout_fd); - } - if (c->stderr_event != NULL) - bufferevent_free(c->stderr_event); - if (c->stderr_fd != -1) { - setblocking(c->stderr_fd, 1); - close(c->stderr_fd); - } + evbuffer_free (c->stdin_data); + evbuffer_free (c->stdout_data); + evbuffer_free (c->stderr_data); status_free_jobs(&c->status_new); status_free_jobs(&c->status_old); @@ -240,6 +222,9 @@ goto client_lost; } + server_push_stdout(c); + server_push_stderr(c); + server_update_event(c); return; @@ -603,12 +588,12 @@ if (!(c->flags & CLIENT_EXIT)) return; - if (c->stdout_fd != -1 && c->stdout_event != NULL && - EVBUFFER_LENGTH(c->stdout_event->output) != 0) + if (EVBUFFER_LENGTH(c->stdin_data) != 0) return; - if (c->stderr_fd != -1 && c->stderr_event != NULL && - EVBUFFER_LENGTH(c->stderr_event->output) != 0) + if (EVBUFFER_LENGTH(c->stdout_data) != 0) return; + if (EVBUFFER_LENGTH(c->stderr_data) != 0) + return; exitdata.retcode = c->retcode; server_write_client(c, MSG_EXIT, &exitdata, sizeof exitdata); @@ -686,55 +671,6 @@ xfree(title); } -/* - * Error callback for client stdin. Caller must increase reference count when - * enabling event! - */ -void -server_client_in_callback( - unused struct bufferevent *bufev, unused short what, void *data) -{ - struct client *c = data; - - c->references--; - if (c->flags & CLIENT_DEAD) - return; - - bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE); - setblocking(c->stdin_fd, 1); - close(c->stdin_fd); - c->stdin_fd = -1; - - if (c->stdin_callback != NULL) - c->stdin_callback(c, c->stdin_data); -} - -/* Error callback for client stdout. */ -void -server_client_out_callback( - unused struct bufferevent *bufev, unused short what, unused void *data) -{ - struct client *c = data; - - bufferevent_disable(c->stdout_event, EV_READ|EV_WRITE); - setblocking(c->stdout_fd, 1); - close(c->stdout_fd); - c->stdout_fd = -1; -} - -/* Error callback for client stderr. */ -void -server_client_err_callback( - unused struct bufferevent *bufev, unused short what, unused void *data) -{ - struct client *c = data; - - bufferevent_disable(c->stderr_event, EV_READ|EV_WRITE); - setblocking(c->stderr_fd, 1); - close(c->stderr_fd); - c->stderr_fd = -1; -} - /* Dispatch message from client. */ int server_client_msg_dispatch(struct client *c) @@ -743,6 +679,7 @@ struct msg_command_data commanddata; struct msg_identify_data identifydata; struct msg_environ_data environdata; + struct msg_stdin_data stdindata; ssize_t n, datalen; if ((n = imsg_read(&c->ibuf)) == -1 || n == 0) @@ -778,43 +715,24 @@ fatalx("MSG_IDENTIFY missing fd"); memcpy(&identifydata, imsg.data, sizeof identifydata); - c->stdin_fd = imsg.fd; - c->stdin_event = bufferevent_new(c->stdin_fd, - NULL, NULL, server_client_in_callback, c); - if (c->stdin_event == NULL) - fatalx("failed to create stdin event"); - setblocking(c->stdin_fd, 0); - server_client_msg_identify(c, &identifydata, imsg.fd); break; - case MSG_STDOUT: - if (datalen != 0) - fatalx("bad MSG_STDOUT size"); - if (imsg.fd == -1) - fatalx("MSG_STDOUT missing fd"); + case MSG_STDIN: + if (datalen != sizeof stdindata) + fatalx("bad MSG_STDIN size"); + memcpy(&stdindata, imsg.data, sizeof stdindata); - c->stdout_fd = imsg.fd; - c->stdout_event = bufferevent_new(c->stdout_fd, - NULL, NULL, server_client_out_callback, c); - if (c->stdout_event == NULL) - fatalx("failed to create stdout event"); - setblocking(c->stdout_fd, 0); - + 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_STDERR: - if (datalen != 0) - fatalx("bad MSG_STDERR size"); - if (imsg.fd == -1) - fatalx("MSG_STDERR missing fd"); - - c->stderr_fd = imsg.fd; - c->stderr_event = bufferevent_new(c->stderr_fd, - NULL, NULL, server_client_err_callback, c); - if (c->stderr_event == NULL) - fatalx("failed to create stderr event"); - setblocking(c->stderr_fd, 0); - - break; case MSG_RESIZE: if (datalen != 0) fatalx("bad MSG_RESIZE size"); @@ -880,10 +798,11 @@ va_list ap; va_start(ap, fmt); - evbuffer_add_vprintf(ctx->cmdclient->stderr_event->output, fmt, ap); + evbuffer_add_vprintf(ctx->cmdclient->stderr_data, fmt, ap); va_end(ap); - bufferevent_write(ctx->cmdclient->stderr_event, "\n", 1); + evbuffer_add(ctx->cmdclient->stderr_data, "\n", 1); + server_push_stderr(ctx->cmdclient); ctx->cmdclient->retcode = 1; } @@ -894,10 +813,11 @@ va_list ap; va_start(ap, fmt); - evbuffer_add_vprintf(ctx->cmdclient->stdout_event->output, fmt, ap); + evbuffer_add_vprintf(ctx->cmdclient->stdout_data, fmt, ap); va_end(ap); - bufferevent_write(ctx->cmdclient->stdout_event, "\n", 1); + evbuffer_add(ctx->cmdclient->stdout_data, "\n", 1); + server_push_stdout(ctx->cmdclient); } /* Callback to send print message to client, if not quiet. */ @@ -910,10 +830,11 @@ return; va_start(ap, fmt); - evbuffer_add_vprintf(ctx->cmdclient->stdout_event->output, fmt, ap); + evbuffer_add_vprintf(ctx->cmdclient->stdout_data, fmt, ap); va_end(ap); - bufferevent_write(ctx->cmdclient->stdout_event, "\n", 1); + evbuffer_add(ctx->cmdclient->stdout_data, "\n", 1); + server_push_stdout(ctx->cmdclient); } /* Handle command message. */ @@ -970,8 +891,6 @@ server_client_msg_identify( struct client *c, struct msg_identify_data *data, int fd) { - int tty_fd; - c->cwd = NULL; data->cwd[(sizeof data->cwd) - 1] = '\0'; if (*data->cwd != '\0') @@ -979,10 +898,8 @@ if (!isatty(fd)) return; - if ((tty_fd = dup(fd)) == -1) - fatal("dup failed"); data->term[(sizeof data->term) - 1] = '\0'; - tty_init(&c->tty, tty_fd, data->term); + tty_init(&c->tty, fd, data->term); if (data->flags & IDENTIFY_UTF8) c->tty.flags |= TTY_UTF8; if (data->flags & IDENTIFY_256COLOURS)