From d75dd2ab1c792ea06c2777a31cb83cb3ba4c47a7 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 11:47:52 +0000 Subject: Add formats for window flags. --- format.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 168ff5b9..e870cd0a 100644 --- a/format.c +++ b/format.c @@ -151,6 +151,7 @@ void format_add(struct format_tree *ft, const char *key, const char *fmt, ...) { struct format_entry *fe; + struct format_entry *fe_now; va_list ap; fe = xmalloc(sizeof *fe); @@ -160,7 +161,13 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...) xvasprintf(&fe->value, fmt, ap); va_end(ap); - RB_INSERT(format_tree, ft, fe); + fe_now = RB_INSERT(format_tree, ft, fe); + if (fe_now != NULL) { + free(fe_now->value); + fe_now->value = fe->value; + free(fe->key); + free(fe); + } } /* Find a format entry. */ @@ -346,8 +353,10 @@ format_client(struct format_tree *ft, struct client *c) format_add(ft, "client_cwd", "%s", c->cwd); format_add(ft, "client_height", "%u", c->tty.sy); format_add(ft, "client_width", "%u", c->tty.sx); - format_add(ft, "client_tty", "%s", c->tty.path); - format_add(ft, "client_termname", "%s", c->tty.termname); + if (c->tty.path != NULL) + format_add(ft, "client_tty", "%s", c->tty.path); + if (c->tty.termname != NULL) + format_add(ft, "client_termname", "%s", c->tty.termname); t = c->creation_time.tv_sec; format_add(ft, "client_created", "%lld", (long long) t); @@ -401,6 +410,15 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) format_add(ft, "window_active", "%d", wl == s->curw); format_add(ft, "window_panes", "%u", window_count_panes(w)); + format_add(ft, "window_bell_flag", "%u", + !!(wl->flags & WINLINK_BELL)); + format_add(ft, "window_content_flag", "%u", + !!(wl->flags & WINLINK_CONTENT)); + format_add(ft, "window_activity_flag", "%u", + !!(wl->flags & WINLINK_ACTIVITY)); + format_add(ft, "window_silence_flag", "%u", + !!(wl->flags & WINLINK_SILENCE)); + free(flags); free(layout); } -- cgit From 40811eb8d45c1b6d93da2ebae6c4bc821d2b9836 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 11:50:20 +0000 Subject: Add length limit operator for formats. --- format.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index e870cd0a..72e42ba0 100644 --- a/format.c +++ b/format.c @@ -18,6 +18,8 @@ #include +#include +#include #include #include #include @@ -188,18 +190,40 @@ format_find(struct format_tree *ft, const char *key) * #{?blah,a,b} is replace with a if blah exists and is nonzero else b. */ int -format_replace(struct format_tree *ft, - const char *key, size_t keylen, char **buf, size_t *len, size_t *off) +format_replace(struct format_tree *ft, const char *key, size_t keylen, + char **buf, size_t *len, size_t *off) { - char *copy, *ptr; + char *copy, *copy0, *endptr, *ptr; const char *value; size_t valuelen; + u_long limit = ULONG_MAX; /* Make a copy of the key. */ - copy = xmalloc(keylen + 1); + copy0 = copy = xmalloc(keylen + 1); memcpy(copy, key, keylen); copy[keylen] = '\0'; + /* Is there a length limit or whatnot? */ + if (!islower((u_char) *copy) && *copy != '?') { + while (*copy != ':' && *copy != '\0') { + switch (*copy) { + case '=': + errno = 0; + limit = strtoul(copy + 1, &endptr, 10); + if (errno == ERANGE && limit == ULONG_MAX) + goto fail; + copy = endptr; + break; + default: + copy++; + break; + } + } + if (*copy != ':') + goto fail; + copy++; + } + /* * Is this a conditional? If so, check it exists and extract either the * first or second element. If not, look up the key directly. @@ -230,6 +254,10 @@ format_replace(struct format_tree *ft, } valuelen = strlen(value); + /* Truncate the value if needed. */ + if (valuelen > limit) + valuelen = limit; + /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { *buf = xrealloc(*buf, 2, *len); @@ -238,11 +266,11 @@ format_replace(struct format_tree *ft, memcpy(*buf + *off, value, valuelen); *off += valuelen; - free(copy); + free(copy0); return (0); fail: - free(copy); + free(copy0); return (-1); } -- cgit From 2bf2f5d58ee060068e915873a191a1d0d6e5c18f Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 11:50:36 +0000 Subject: Allow nested format expansion. --- format.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 72e42ba0..1b460855 100644 --- a/format.c +++ b/format.c @@ -193,7 +193,7 @@ int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { - char *copy, *copy0, *endptr, *ptr; + char *copy, *copy0, *endptr, *ptr, *saved; const char *value; size_t valuelen; u_long limit = ULONG_MAX; @@ -247,10 +247,13 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, goto fail; value = ptr + 1; } + saved = format_expand(ft, value); + value = saved; } else { value = format_find(ft, copy); if (value == NULL) value = ""; + saved = NULL; } valuelen = strlen(value); @@ -266,6 +269,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, memcpy(*buf + *off, value, valuelen); *off += valuelen; + free(saved); free(copy0); return (0); @@ -278,10 +282,10 @@ fail: char * format_expand(struct format_tree *ft, const char *fmt) { - char *buf, *ptr; - const char *s; + char *buf; + const char *ptr, *s; size_t off, len, n; - int ch; + int ch, brackets; len = 64; buf = xmalloc(len); @@ -299,11 +303,16 @@ format_expand(struct format_tree *ft, const char *fmt) fmt++; ch = (u_char) *fmt++; - switch (ch) { case '{': - ptr = strchr(fmt, '}'); - if (ptr == NULL) + brackets = 1; + for (ptr = fmt; *ptr != '\0'; ptr++) { + if (*ptr == '{') + brackets++; + if (*ptr == '}' && --brackets == 0) + break; + } + if (*ptr != '}' || brackets != 0) break; n = ptr - fmt; -- cgit From 1a49ebaa9f5e5b90ebb27eb5acd0ff5653e34a46 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 12:04:01 +0000 Subject: First period not last for host_short, from Michael Scholz. --- format.c | 55 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 1b460855..8f86eba3 100644 --- a/format.c +++ b/format.c @@ -34,9 +34,10 @@ * string. */ -int format_replace(struct format_tree *, const char *, size_t, char **, - size_t *, size_t *); -void format_window_pane_tabs(struct format_tree *, struct window_pane *); +int format_replace(struct format_tree *, const char *, size_t, char **, + size_t *, size_t *); +char *format_get_command(struct window_pane *); +void format_window_pane_tabs(struct format_tree *, struct window_pane *); /* Format key-value replacement entry. */ RB_GENERATE(format_tree, format_entry, entry, format_cmp); @@ -120,7 +121,7 @@ format_create(void) if (gethostname(host, sizeof host) == 0) { format_add(ft, "host", "%s", host); - if ((ptr = strrchr(host, '.')) != NULL) + if ((ptr = strchr(host, '.')) != NULL) *ptr = '\0'; format_add(ft, "host_short", "%s", host); } @@ -348,6 +349,21 @@ format_expand(struct format_tree *ft, const char *fmt) return (buf); } +/* Get command name for format. */ +char * +format_get_command(struct window_pane *wp) +{ + char *cmd; + + cmd = get_proc_name(wp->fd, wp->tty); + if (cmd == NULL || *cmd == '\0') { + cmd = wp->cmd; + if (cmd == NULL || *cmd == '\0') + cmd = wp->shell; + } + return (parse_window_name(cmd)); +} + /* Set default format keys for a session. */ void format_session(struct format_tree *ft, struct session *s) @@ -427,26 +443,39 @@ format_client(struct format_tree *ft, struct client *c) format_add(ft, "client_last_session", "%s", s->name); } -/* Set default format keys for a winlink. */ +/* Set default format keys for a window. */ void -format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) +format_window(struct format_tree *ft, struct window *w) { - struct window *w = wl->window; - char *layout, *flags; + char *layout; layout = layout_dump(w); - flags = window_printable_flags(s, wl); format_add(ft, "window_id", "@%u", w->id); - format_add(ft, "window_index", "%d", wl->idx); format_add(ft, "window_name", "%s", w->name); format_add(ft, "window_width", "%u", w->sx); format_add(ft, "window_height", "%u", w->sy); - format_add(ft, "window_flags", "%s", flags); format_add(ft, "window_layout", "%s", layout); - format_add(ft, "window_active", "%d", wl == s->curw); format_add(ft, "window_panes", "%u", window_count_panes(w)); + free(layout); +} + +/* Set default format keys for a winlink. */ +void +format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) +{ + struct window *w = wl->window; + char *flags; + + flags = window_printable_flags(s, wl); + + format_window(ft, w); + + format_add(ft, "window_index", "%d", wl->idx); + format_add(ft, "window_flags", "%s", flags); + format_add(ft, "window_active", "%d", wl == s->curw); + format_add(ft, "window_bell_flag", "%u", !!(wl->flags & WINLINK_BELL)); format_add(ft, "window_content_flag", "%u", @@ -456,8 +485,8 @@ format_winlink(struct format_tree *ft, struct session *s, struct winlink *wl) format_add(ft, "window_silence_flag", "%u", !!(wl->flags & WINLINK_SILENCE)); + free(flags); - free(layout); } /* Add window pane tabs. */ -- cgit From 282c5f9644ed262ee15efbd3d072f7acc577da15 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 12:26:34 +0000 Subject: Alter how tmux handles the working directory to internally use file descriptors rather than strings. - Each session still has a current working directory. - New sessions still get their working directory from the client that created them or its attached session if any. - New windows are created by default in the session working directory. - The -c flag to new, neww, splitw allows the working directory to be overridden. - The -c flag to attach let's the session working directory be changed. - The default-path option has been removed. To get the equivalent to default-path '.', do: bind c neww -c $PWD To get the equivalent of default-path '~', do: bind c neww -c ~ This also changes the client identify protocol to be a set of messages rather than one as well as some other changes that should make it easier to make backwards-compatible protocol changes in future. --- format.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 8f86eba3..19c4dc15 100644 --- a/format.c +++ b/format.c @@ -403,7 +403,6 @@ format_client(struct format_tree *ft, struct client *c) time_t t; struct session *s; - format_add(ft, "client_cwd", "%s", c->cwd); format_add(ft, "client_height", "%u", c->tty.sy); format_add(ft, "client_width", "%u", c->tty.sx); if (c->tty.path != NULL) @@ -552,8 +551,6 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_pid", "%ld", (long) wp->pid); if (wp->cmd != NULL) format_add(ft, "pane_start_command", "%s", wp->cmd); - if (wp->cwd != NULL) - format_add(ft, "pane_start_path", "%s", wp->cwd); if ((cwd = get_proc_cwd(wp->fd)) != NULL) format_add(ft, "pane_current_path", "%s", cwd); if ((cmd = get_proc_name(wp->fd, wp->tty)) != NULL) { -- cgit From d0566a474aa43cb27c6a8fc62ff80ef32c7fe86e Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 12:39:24 +0000 Subject: Remove the KERN_PROC_CWD the proc_current_path format (which is the only thing that uses it now). --- format.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 19c4dc15..40957a59 100644 --- a/format.c +++ b/format.c @@ -518,7 +518,6 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) struct grid_line *gl; unsigned long long size; u_int i, idx; - const char *cwd; char *cmd; size = 0; @@ -551,9 +550,7 @@ format_window_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_pid", "%ld", (long) wp->pid); if (wp->cmd != NULL) format_add(ft, "pane_start_command", "%s", wp->cmd); - if ((cwd = get_proc_cwd(wp->fd)) != NULL) - format_add(ft, "pane_current_path", "%s", cwd); - if ((cmd = get_proc_name(wp->fd, wp->tty)) != NULL) { + if ((cmd = format_get_command(wp)) != NULL) { format_add(ft, "pane_current_command", "%s", cmd); free(cmd); } -- cgit From 0b77d17b35fad797b26632f3305dcd2c9b994a3f Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 10 Oct 2013 23:31:03 +0000 Subject: Fix leak in format_get_command. --- format.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 40957a59..14dcd000 100644 --- a/format.c +++ b/format.c @@ -353,7 +353,7 @@ format_expand(struct format_tree *ft, const char *fmt) char * format_get_command(struct window_pane *wp) { - char *cmd; + char *cmd, *out; cmd = get_proc_name(wp->fd, wp->tty); if (cmd == NULL || *cmd == '\0') { @@ -361,7 +361,9 @@ format_get_command(struct window_pane *wp) if (cmd == NULL || *cmd == '\0') cmd = wp->shell; } - return (parse_window_name(cmd)); + out = parse_window_name(cmd); + free(cmd); + return (out); } /* Set default format keys for a session. */ -- cgit From 98b81e983428c7770022c698a0c4ef3c7fc4ea36 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 11 Oct 2013 08:03:43 +0000 Subject: And get it right this time... don't leak if it is an empty string either. --- format.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'format.c') diff --git a/format.c b/format.c index 14dcd000..bfc40906 100644 --- a/format.c +++ b/format.c @@ -357,9 +357,12 @@ format_get_command(struct window_pane *wp) cmd = get_proc_name(wp->fd, wp->tty); if (cmd == NULL || *cmd == '\0') { - cmd = wp->cmd; - if (cmd == NULL || *cmd == '\0') - cmd = wp->shell; + free(cmd); + cmd = xstrdup(wp->cmd); + if (cmd == NULL || *cmd == '\0') { + free(cmd); + cmd = xstrdup(wp->shell); + } } out = parse_window_name(cmd); free(cmd); -- cgit From f703a30dfe2f3178202ccd5121128d4d3c4bbec8 Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 11 Oct 2013 14:39:22 +0100 Subject: Fixup osdep-* specific code get_proc_name() is osdep_get_name() outside of OpenBSD. --- format.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'format.c') diff --git a/format.c b/format.c index d8d34fe7..450e15f3 100644 --- a/format.c +++ b/format.c @@ -355,7 +355,7 @@ format_get_command(struct window_pane *wp) { char *cmd, *out; - cmd = get_proc_name(wp->fd, wp->tty); + cmd = osdep_get_name(wp->fd, wp->tty); if (cmd == NULL || *cmd == '\0') { free(cmd); cmd = xstrdup(wp->cmd); -- cgit