summaryrefslogtreecommitdiffstats
path: root/server-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c159
1 files changed, 38 insertions, 121 deletions
diff --git a/server-client.c b/server-client.c
index 2cbb5bf3..25f17f06 100644
--- a/server-client.c
+++ b/server-client.c
@@ -35,9 +35,6 @@ void server_client_check_exit(struct client *);
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 @@ server_client_create(int fd)
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 @@ server_client_lost(struct client *c)
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 @@ server_client_callback(int fd, short events, void *data)
goto client_lost;
}
+ server_push_stdout(c);
+ server_push_stderr(c);
+
server_update_event(c);
return;
@@ -603,11 +588,11 @@ server_client_check_exit(struct client *c)
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 (EVBUFFER_LENGTH(c->stdout_data) != 0)
return;
- if (c->stderr_fd != -1 && c->stderr_event != NULL &&
- EVBUFFER_LENGTH(c->stderr_event->output) != 0)
+ if (EVBUFFER_LENGTH(c->stderr_data) != 0)
return;
exitdata.retcode = c->retcode;
@@ -686,55 +671,6 @@ server_client_set_title(struct client *c)
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 @@ server_client_msg_dispatch(struct client *c)
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,42 +715,23 @@ server_client_msg_dispatch(struct client *c)
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");
-
- 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);
-
- 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);
+ case MSG_STDIN:
+ if (datalen != sizeof stdindata)
+ fatalx("bad MSG_STDIN size");
+ memcpy(&stdindata, imsg.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)
@@ -880,10 +798,11 @@ server_client_msg_error(struct cmd_ctx *ctx, const char *fmt, ...)
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 @@ server_client_msg_print(struct cmd_ctx *ctx, const char *fmt, ...)
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 @@ server_client_msg_info(struct cmd_ctx *ctx, const char *fmt, ...)
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 @@ void
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 @@ server_client_msg_identify(
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)