aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client.c4
-rw-r--r--cmd-capture-pane.c2
-rw-r--r--cmd-load-buffer.c2
-rw-r--r--cmd-queue.c6
-rw-r--r--cmd-save-buffer.c2
-rw-r--r--control.c4
-rw-r--r--input.c21
-rw-r--r--server-client.c90
-rw-r--r--server-fn.c44
-rw-r--r--server.c2
-rw-r--r--tmux.c2
-rw-r--r--tmux.h4
12 files changed, 116 insertions, 67 deletions
diff --git a/client.c b/client.c
index ccc58fb4..f3724d17 100644
--- a/client.c
+++ b/client.c
@@ -289,7 +289,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
*
* "sendfd" is dropped later in client_dispatch_wait().
*/
- if (pledge("stdio unix sendfd proc exec tty", NULL) != 0)
+ if (0 && pledge("stdio unix sendfd proc exec tty", NULL) != 0)
fatal("pledge failed");
#endif
@@ -545,7 +545,7 @@ client_dispatch_wait(struct imsg *imsg)
* get the first message from the server.
*/
if (!pledge_applied) {
- if (pledge("stdio unix proc exec tty", NULL) != 0)
+ if (0 && pledge("stdio unix proc exec tty", NULL) != 0)
fatal("pledge failed");
pledge_applied = 1;
};
diff --git a/cmd-capture-pane.c b/cmd-capture-pane.c
index 8958a12d..6a7af47a 100644
--- a/cmd-capture-pane.c
+++ b/cmd-capture-pane.c
@@ -203,7 +203,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
free(buf);
if (args_has(args, 'P') && len > 0)
evbuffer_add(c->stdout_data, "\n", 1);
- server_push_stdout(c);
+ server_client_push_stdout(c);
} else {
bufname = NULL;
if (args_has(args, 'b'))
diff --git a/cmd-load-buffer.c b/cmd-load-buffer.c
index 40bea9b7..5ac2edc3 100644
--- a/cmd-load-buffer.c
+++ b/cmd-load-buffer.c
@@ -160,7 +160,7 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
free(saved);
}
evbuffer_add_printf(c->stderr_data, "%s", cause);
- server_push_stderr(c);
+ server_client_push_stderr(c);
free(pdata);
free(cause);
}
diff --git a/cmd-queue.c b/cmd-queue.c
index 5015981c..2d896212 100644
--- a/cmd-queue.c
+++ b/cmd-queue.c
@@ -85,7 +85,7 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
} else
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
evbuffer_add(c->stdout_data, "\n", 1);
- server_push_stdout(c);
+ server_client_push_stdout(c);
} else {
w = c->session->curw->window;
if (w->active->mode != &window_copy_mode) {
@@ -125,7 +125,7 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
}
evbuffer_add(c->stderr_data, msg, msglen);
evbuffer_add(c->stderr_data, "\n", 1);
- server_push_stderr(c);
+ server_client_push_stderr(c);
c->retval = 1;
} else {
*msg = toupper((u_char) *msg);
@@ -146,7 +146,7 @@ cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
(long) cmdq->time, cmdq->number, flags);
- server_push_stdout(c);
+ server_client_push_stdout(c);
}
/* Add command list to queue and begin processing if needed. */
diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c
index 87afe7ee..8c731365 100644
--- a/cmd-save-buffer.c
+++ b/cmd-save-buffer.c
@@ -129,7 +129,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
do_stdout:
evbuffer_add(c->stdout_data, bufdata, bufsize);
- server_push_stdout(c);
+ server_client_push_stdout(c);
return (CMD_RETURN_NORMAL);
do_print:
diff --git a/control.c b/control.c
index 11fa2d80..f7264944 100644
--- a/control.c
+++ b/control.c
@@ -37,7 +37,7 @@ control_write(struct client *c, const char *fmt, ...)
va_end(ap);
evbuffer_add(c->stdout_data, "\n", 1);
- server_push_stdout(c);
+ server_client_push_stdout(c);
}
/* Write a buffer, adding a terminal newline. Empties buffer. */
@@ -46,7 +46,7 @@ control_write_buffer(struct client *c, struct evbuffer *buffer)
{
evbuffer_add_buffer(c->stdout_data, buffer);
evbuffer_add(c->stdout_data, "\n", 1);
- server_push_stdout(c);
+ server_client_push_stdout(c);
}
/* Control input callback. Read lines and fire commands. */
diff --git a/input.c b/input.c
index c56cdc35..babdecdb 100644
--- a/input.c
+++ b/input.c
@@ -1921,9 +1921,12 @@ input_exit_rename(struct input_ctx *ictx)
int
input_utf8_open(struct input_ctx *ictx)
{
- log_debug("%s", __func__);
+ struct utf8_data *ud = &ictx->utf8data;
+
+ utf8_open(ud, ictx->ch);
+
+ log_debug("%s %hhu", __func__, ud->size);
- utf8_open(&ictx->utf8data, ictx->ch);
return (0);
}
@@ -1931,9 +1934,12 @@ input_utf8_open(struct input_ctx *ictx)
int
input_utf8_add(struct input_ctx *ictx)
{
+ struct utf8_data *ud = &ictx->utf8data;
+
+ utf8_append(ud, ictx->ch);
+
log_debug("%s", __func__);
- utf8_append(&ictx->utf8data, ictx->ch);
return (0);
}
@@ -1941,11 +1947,14 @@ input_utf8_add(struct input_ctx *ictx)
int
input_utf8_close(struct input_ctx *ictx)
{
- log_debug("%s", __func__);
+ struct utf8_data *ud = &ictx->utf8data;
+
+ utf8_append(ud, ictx->ch);
- utf8_append(&ictx->utf8data, ictx->ch);
+ log_debug("%s %hhu '%*s' (width %hhu)", __func__, ud->size,
+ (int)ud->size, ud->data, ud->width);
- utf8_copy(&ictx->cell.cell.data, &ictx->utf8data);
+ utf8_copy(&ictx->cell.cell.data, ud);
screen_write_cell(&ictx->ctx, &ictx->cell.cell);
return (0);
diff --git a/server-client.c b/server-client.c
index 3e900afa..6c8b121a 100644
--- a/server-client.c
+++ b/server-client.c
@@ -1043,9 +1043,6 @@ server_client_dispatch(struct imsg *imsg, void *arg)
server_client_dispatch_shell(c);
break;
}
-
- server_push_stdout(c);
- server_push_stderr(c);
}
/* Handle command message. */
@@ -1227,3 +1224,90 @@ server_client_dispatch_shell(struct client *c)
proc_kill_peer(c->peer);
}
+
+/* Event callback to push more stdout data if any left. */
+static void
+server_client_stdout_cb(unused int fd, unused short events, void *arg)
+{
+ struct client *c = arg;
+
+ if (~c->flags & CLIENT_DEAD)
+ server_client_push_stdout(c);
+ server_client_unref(c);
+}
+
+/* Push stdout to client if possible. */
+void
+server_client_push_stdout(struct client *c)
+{
+ struct msg_stdout_data data;
+ size_t sent, left;
+
+ left = EVBUFFER_LENGTH(c->stdout_data);
+ while (left != 0) {
+ sent = left;
+ if (sent > sizeof data.data)
+ sent = sizeof data.data;
+ memcpy(data.data, EVBUFFER_DATA(c->stdout_data), sent);
+ data.size = sent;
+
+ if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) != 0)
+ break;
+ evbuffer_drain(c->stdout_data, sent);
+
+ left = EVBUFFER_LENGTH(c->stdout_data);
+ log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
+ sent, left);
+ }
+ if (left != 0) {
+ c->references++;
+ event_once(-1, EV_TIMEOUT, server_client_stdout_cb, c, NULL);
+ log_debug("%s: client %p, queued", __func__, c);
+ }
+}
+
+/* Event callback to push more stderr data if any left. */
+static void
+server_client_stderr_cb(unused int fd, unused short events, void *arg)
+{
+ struct client *c = arg;
+
+ if (~c->flags & CLIENT_DEAD)
+ server_client_push_stderr(c);
+ server_client_unref(c);
+}
+
+/* Push stderr to client if possible. */
+void
+server_client_push_stderr(struct client *c)
+{
+ struct msg_stderr_data data;
+ size_t sent, left;
+
+ if (c->stderr_data == c->stdout_data) {
+ server_client_push_stdout(c);
+ return;
+ }
+
+ left = EVBUFFER_LENGTH(c->stderr_data);
+ while (left != 0) {
+ sent = left;
+ if (sent > sizeof data.data)
+ sent = sizeof data.data;
+ memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent);
+ data.size = sent;
+
+ if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0)
+ break;
+ evbuffer_drain(c->stderr_data, sent);
+
+ left = EVBUFFER_LENGTH(c->stderr_data);
+ log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
+ sent, left);
+ }
+ if (left != 0) {
+ c->references++;
+ event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL);
+ log_debug("%s: client %p, queued", __func__, c);
+ }
+}
diff --git a/server-fn.c b/server-fn.c
index 6a7c881c..7c3dada7 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -451,50 +451,6 @@ server_callback_identify(unused int fd, unused short events, void *data)
server_clear_identify(c);
}
-/* Push stdout to client if possible. */
-void
-server_push_stdout(struct client *c)
-{
- struct msg_stdout_data data;
- size_t size;
-
- size = EVBUFFER_LENGTH(c->stdout_data);
- if (size == 0)
- return;
- if (size > sizeof data.data)
- size = sizeof data.data;
-
- memcpy(data.data, EVBUFFER_DATA(c->stdout_data), size);
- data.size = size;
-
- if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) == 0)
- evbuffer_drain(c->stdout_data, size);
-}
-
-/* Push stderr to client if possible. */
-void
-server_push_stderr(struct client *c)
-{
- struct msg_stderr_data data;
- size_t size;
-
- if (c->stderr_data == c->stdout_data) {
- server_push_stdout(c);
- return;
- }
- size = EVBUFFER_LENGTH(c->stderr_data);
- if (size == 0)
- return;
- if (size > sizeof data.data)
- size = sizeof data.data;
-
- memcpy(data.data, EVBUFFER_DATA(c->stderr_data), size);
- data.size = size;
-
- if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) == 0)
- evbuffer_drain(c->stderr_data, size);
-}
-
/* Set stdin callback. */
int
server_set_stdin_callback(struct client *c, void (*cb)(struct client *, int,
diff --git a/server.c b/server.c
index 4e2304b3..190dcfac 100644
--- a/server.c
+++ b/server.c
@@ -176,7 +176,7 @@ server_start(struct event_base *base, int lockfd, char *lockfile)
tty_create_log();
#ifdef __OpenBSD__
- if (pledge("stdio rpath wpath cpath fattr unix recvfd proc exec tty "
+ if (0 && pledge("stdio rpath wpath cpath fattr unix recvfd proc exec tty "
"ps", NULL) != 0)
fatal("pledge failed");
#endif
diff --git a/tmux.c b/tmux.c
index c88b119d..9e5ddb66 100644
--- a/tmux.c
+++ b/tmux.c
@@ -261,7 +261,7 @@ main(int argc, char **argv)
usage();
#ifdef __OpenBSD__
- if (pledge("stdio rpath wpath cpath flock fattr unix sendfd recvfd "
+ if (0 && pledge("stdio rpath wpath cpath flock fattr unix sendfd recvfd "
"proc exec tty ps", NULL) != 0)
err(1, "pledge");
#endif
diff --git a/tmux.h b/tmux.h
index 7439a844..5c94b0f7 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1784,6 +1784,8 @@ int server_client_open(struct client *, char **);
void server_client_unref(struct client *);
void server_client_lost(struct client *);
void server_client_loop(void);
+void server_client_push_stdout(struct client *);
+void server_client_push_stderr(struct client *);
/* server-fn.c */
void server_fill_environ(struct session *, struct environ *);
@@ -1809,8 +1811,6 @@ void server_destroy_session(struct session *);
void server_check_unattached(void);
void server_set_identify(struct client *);
void server_clear_identify(struct client *);
-void server_push_stdout(struct client *);
-void server_push_stderr(struct client *);
int server_set_stdin_callback(struct client *, void (*)(struct client *,
int, void *), void *, char **);
void server_unzoom_window(struct window *);