From cc768d77ec89c43e5770588b36d584d5d18104d3 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 13:28:50 +0000 Subject: [PATCH 1/7] Revert to marking lines as wrapped on newlines, fixes problems with capturep -J. --- screen-write.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/screen-write.c b/screen-write.c index e38c9f53..37e2b548 100644 --- a/screen-write.c +++ b/screen-write.c @@ -795,6 +795,8 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped) gl = &s->grid->linedata[s->grid->hsize + s->cy]; if (wrapped) gl->flags |= GRID_LINE_WRAPPED; + else + gl->flags &= ~GRID_LINE_WRAPPED; if (s->cy == s->rlower) grid_view_scroll_region_up(s->grid, s->rupper, s->rlower); From 6308c48efd7a80dad5701721f76b9aafb9b814f8 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 13:36:29 +0000 Subject: [PATCH 2/7] Add a -s flag to show-environment to output Bourne shell commands a la ssh-agent. Mostly from Cam Hutchison with some changes by me. --- cmd-show-environment.c | 68 ++++++++++++++++++++++++++++++++---------- tmux.1 | 5 +++- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/cmd-show-environment.c b/cmd-show-environment.c index 7737752f..a61cf3f4 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -27,16 +27,61 @@ * Show environment. */ -enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *); +enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *); + +char *cmd_show_environment_escape(struct environ_entry *); +void cmd_show_environment_print(struct cmd *, struct cmd_q *, + struct environ_entry *); const struct cmd_entry cmd_show_environment_entry = { "show-environment", "showenv", - "gt:", 0, 1, - "[-g] " CMD_TARGET_SESSION_USAGE " [name]", + "gst:", 0, 1, + "[-gs] " CMD_TARGET_SESSION_USAGE " [name]", 0, cmd_show_environment_exec }; +char * +cmd_show_environment_escape(struct environ_entry *envent) +{ + const char *value = envent->value; + char c, *out, *ret; + + out = ret = xmalloc(strlen(value) * 2 + 1); /* at most twice the size */ + while ((c = *value++) != '\0') { + /* POSIX interprets $ ` " and \ in double quotes. */ + if (c == '$' || c == '`' || c == '"' || c == '\\') + *out++ = '\\'; + *out++ = c; + } + *out = '\0'; + + return ret; +} + +void +cmd_show_environment_print(struct cmd *self, struct cmd_q *cmdq, + struct environ_entry *envent) +{ + char *escaped; + + if (!args_has(self->args, 's')) { + if (envent->value != NULL) + cmdq_print(cmdq, "%s=%s", envent->name, envent->value); + else + cmdq_print(cmdq, "-%s", envent->name); + return; + } + + if (envent->value != NULL) { + escaped = cmd_show_environment_escape(envent); + cmdq_print(cmdq, "%s=\"%s\"; export %s;", envent->name, escaped, + envent->name); + free(escaped); + } else + cmdq_print(cmdq, "unset %s;", envent->name); +} + enum cmd_retval cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) { @@ -48,7 +93,8 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) if (args_has(self->args, 'g')) env = &global_environ; else { - if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) + s = cmd_find_session(cmdq, args_get(args, 't'), 0); + if (s == NULL) return (CMD_RETURN_ERROR); env = &s->environ; } @@ -59,19 +105,11 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "unknown variable: %s", args->argv[0]); return (CMD_RETURN_ERROR); } - if (envent->value != NULL) - cmdq_print(cmdq, "%s=%s", envent->name, envent->value); - else - cmdq_print(cmdq, "-%s", envent->name); + cmd_show_environment_print(self, cmdq, envent); return (CMD_RETURN_NORMAL); } - RB_FOREACH(envent, environ, env) { - if (envent->value != NULL) - cmdq_print(cmdq, "%s=%s", envent->name, envent->value); - else - cmdq_print(cmdq, "-%s", envent->name); - } - + RB_FOREACH(envent, environ, env) + cmd_show_environment_print(self, cmdq, envent); return (CMD_RETURN_NORMAL); } diff --git a/tmux.1 b/tmux.1 index f0dd569a..db5f314e 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3542,7 +3542,7 @@ flag unsets a variable. indicates the variable is to be removed from the environment before starting a new process. .It Xo Ic show-environment -.Op Fl g +.Op Fl gs .Op Fl t Ar target-session .Op Ar variable .Xc @@ -3556,6 +3556,9 @@ If is omitted, all variables are shown. Variables removed from the environment are prefixed with .Ql - . +If +.Fl s +is used, the output is formatted as a set of Bourne shell commands. .El .Sh STATUS LINE .Nm From 81069f66f96dd83025fc6f2990619eb861199e10 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 15:37:26 +0000 Subject: [PATCH 3/7] Add a format to show if client is a control client. From Bruno Sutic. --- format.c | 2 ++ tmux.1 | 1 + 2 files changed, 3 insertions(+) diff --git a/format.c b/format.c index 8a52b0e1..aff34abb 100644 --- a/format.c +++ b/format.c @@ -711,6 +711,8 @@ format_defaults_client(struct format_tree *ft, struct client *c) format_add(ft, "client_tty", "%s", c->tty.path); if (c->tty.termname != NULL) format_add(ft, "client_termname", "%s", c->tty.termname); + format_add(ft, "client_control_mode", "%d", + !!(c->flags & CLIENT_CONTROL)); t = c->creation_time.tv_sec; format_add(ft, "client_created", "%lld", (long long) t); diff --git a/tmux.1 b/tmux.1 index db5f314e..b4c608cb 100644 --- a/tmux.1 +++ b/tmux.1 @@ -3358,6 +3358,7 @@ The following variables are available, where appropriate: .It Li "client_activity_string" Ta "" Ta "String time client last had activity" .It Li "client_created" Ta "" Ta "Integer time client created" .It Li "client_created_string" Ta "" Ta "String time client created" +.It Li "client_control_mode" Ta "" Ta "1 if client is in control mode" .It Li "client_height" Ta "" Ta "Height of client" .It Li "client_last_session" Ta "" Ta "Name of the client's last session" .It Li "client_pid" Ta "" Ta "PID of client process" From c7374c31c4ba176e94825e8d734b5abe8a6879b1 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 15:49:31 +0000 Subject: [PATCH 4/7] Initialize cwd fd to -1 so that we don't close fd 0 if the client is destroyed before it is changed. Also allow ttyname() to fail. Fixes problems when running out of file descriptors reported by Bruno Sutic. --- server-client.c | 5 +++-- tmux.h | 2 +- tty.c | 9 +++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/server-client.c b/server-client.c index 9beef4bc..4c03de91 100644 --- a/server-client.c +++ b/server-client.c @@ -96,6 +96,8 @@ server_client_create(int fd) environ_init(&c->environ); + c->cwd = -1; + c->cmdq = cmdq_new(c); c->cmdq->client_exit = 1; @@ -1253,12 +1255,11 @@ server_client_msg_identify(struct client *c, struct imsg *imsg) if (c->fd == -1) return; - if (!isatty(c->fd)) { + if (tty_init(&c->tty, c, c->fd, c->term) != 0) { close(c->fd); c->fd = -1; return; } - tty_init(&c->tty, c, c->fd, c->term); if (c->flags & CLIENT_UTF8) c->tty.flags |= TTY_UTF8; if (c->flags & CLIENT_256COLOURS) diff --git a/tmux.h b/tmux.h index 663832e5..e082aeab 100644 --- a/tmux.h +++ b/tmux.h @@ -1600,7 +1600,7 @@ void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, void tty_puts(struct tty *, const char *); void tty_putc(struct tty *, u_char); void tty_putn(struct tty *, const void *, size_t, u_int); -void tty_init(struct tty *, struct client *, int, char *); +int tty_init(struct tty *, struct client *, int, char *); int tty_resize(struct tty *); int tty_set_size(struct tty *, u_int, u_int); void tty_set_class(struct tty *, u_int); diff --git a/tty.c b/tty.c index 63380c29..ffb36cb1 100644 --- a/tty.c +++ b/tty.c @@ -59,11 +59,14 @@ void tty_default_colours(struct grid_cell *, const struct window_pane *); #define tty_pane_full_width(tty, ctx) \ ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) -void +int tty_init(struct tty *tty, struct client *c, int fd, char *term) { char *path; + if (!isatty(fd)) + return (-1); + memset(tty, 0, sizeof *tty); tty->log_fd = -1; @@ -75,13 +78,15 @@ tty_init(struct tty *tty, struct client *c, int fd, char *term) tty->client = c; if ((path = ttyname(fd)) == NULL) - fatalx("ttyname failed"); + return (-1); tty->path = xstrdup(path); tty->cstyle = 0; tty->ccolour = xstrdup(""); tty->flags = 0; tty->term_flags = 0; + + return (0); } int From e45d624df288d914a1628d373ff245b03f7d600b Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 15:51:31 +0000 Subject: [PATCH 5/7] Fix line endings. --- server-client.c | 6 +++--- tmux.h | 2 +- tty.c | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/server-client.c b/server-client.c index 4c03de91..09348b05 100644 --- a/server-client.c +++ b/server-client.c @@ -96,8 +96,8 @@ server_client_create(int fd) environ_init(&c->environ); - c->cwd = -1; - + c->cwd = -1; + c->cmdq = cmdq_new(c); c->cmdq->client_exit = 1; @@ -1255,7 +1255,7 @@ server_client_msg_identify(struct client *c, struct imsg *imsg) if (c->fd == -1) return; - if (tty_init(&c->tty, c, c->fd, c->term) != 0) { + if (tty_init(&c->tty, c, c->fd, c->term) != 0) { close(c->fd); c->fd = -1; return; diff --git a/tmux.h b/tmux.h index e082aeab..3aceff9d 100644 --- a/tmux.h +++ b/tmux.h @@ -1600,7 +1600,7 @@ void tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, void tty_puts(struct tty *, const char *); void tty_putc(struct tty *, u_char); void tty_putn(struct tty *, const void *, size_t, u_int); -int tty_init(struct tty *, struct client *, int, char *); +int tty_init(struct tty *, struct client *, int, char *); int tty_resize(struct tty *); int tty_set_size(struct tty *, u_int, u_int); void tty_set_class(struct tty *, u_int); diff --git a/tty.c b/tty.c index ffb36cb1..374fb8c6 100644 --- a/tty.c +++ b/tty.c @@ -59,14 +59,14 @@ void tty_default_colours(struct grid_cell *, const struct window_pane *); #define tty_pane_full_width(tty, ctx) \ ((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx) -int +int tty_init(struct tty *tty, struct client *c, int fd, char *term) { char *path; - if (!isatty(fd)) - return (-1); - + if (!isatty(fd)) + return (-1); + memset(tty, 0, sizeof *tty); tty->log_fd = -1; @@ -78,15 +78,15 @@ tty_init(struct tty *tty, struct client *c, int fd, char *term) tty->client = c; if ((path = ttyname(fd)) == NULL) - return (-1); + return (-1); tty->path = xstrdup(path); tty->cstyle = 0; tty->ccolour = xstrdup(""); tty->flags = 0; tty->term_flags = 0; - - return (0); + + return (0); } int From 4e637b1b610f93d474a60daa4ab78afef66b29bc Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 18:10:26 +0000 Subject: [PATCH 6/7] Ignore environment variables that are too long to send to the server. --- client.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client.c b/client.c index 4b7bbb1f..63432926 100644 --- a/client.c +++ b/client.c @@ -350,6 +350,7 @@ client_send_identify(int flags) { const char *s; char **ss; + size_t sslen; int fd; pid_t pid; @@ -374,8 +375,11 @@ client_send_identify(int flags) pid = getpid(); client_write_one(MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid); - for (ss = environ; *ss != NULL; ss++) - client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, strlen(*ss) + 1); + for (ss = environ; *ss != NULL; ss++) { + sslen = strlen(*ss) + 1; + if (sslen <= MAX_IMSGSIZE - IMSG_HEADER_SIZE) + client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, sslen); + } client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0); From 8dcea2cc14448494d25a6a68618ae7088bef1b95 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 13 Jul 2015 18:45:18 +0000 Subject: [PATCH 7/7] Reset G0/G1 state when resetting everything else with send-keys -R. --- input.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/input.c b/input.c index d1ff17fe..095816c3 100644 --- a/input.c +++ b/input.c @@ -801,10 +801,7 @@ input_reset(struct window_pane *wp) { struct input_ctx *ictx = wp->ictx; - memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell); - memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); - ictx->old_cx = 0; - ictx->old_cy = 0; + input_reset_cell(ictx); if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base);