The branch, master has been updated
       via  56e1132db485aeb0730ce7782533ca441e63afef (commit)
       via  aeedb464a6ee038289ddcfefae437928ab020cb1 (commit)
       via  583b4ab72b7bf66fda8ab63a08fe435483de5e5a (commit)
       via  5a2d0533a84a13613fb356b66ed8ada2a65f6edf (commit)
       via  a5a873dcccaabd55dbb0ad32abafbf1049316392 (commit)
       via  ab73997cc5bd652370beef93db5fca439448734a (commit)
       via  9a453dd3546b2c3053e8e34bf4d6775b1a05d3a8 (commit)
       via  8d66f4fba4972d45be64d108c7c8d952f85016a8 (commit)
       via  89e80cabd56bf2f7fa783575fe9b1f6192fade42 (commit)
      from  0a88377086329786c438d4973365fdb21186f4e4 (commit)

- Log -----------------------------------------------------------------
commit 56e1132db485aeb0730ce7782533ca441e63afef
Merge: 0a88377 aeedb46
Author: Thomas Adam <[email protected]>
Commit: Thomas Adam <[email protected]>

    Merge branch 'obsd-master'

 client.c             |    6 ++--
 cmd-attach-session.c |    8 +---
 cmd-choose-client.c  |   24 +++++++-----
 cmd-detach-client.c  |   13 ++-----
 cmd-if-shell.c       |   15 ++++++--
 cmd-list-clients.c   |   15 ++++----
 cmd-run-shell.c      |   15 ++++++--
 cmd-set-option.c     |   52 ++++++++++++++++-----------
 cmd.c                |   26 +++++++------
 control-notify.c     |   28 ++++-----------
 grid.c               |    2 +-
 job.c                |    5 ++-
 notify.c             |    6 +--
 resize.c             |   14 +++----
 server-client.c      |   51 +++++----------------------
 server-fn.c          |   62 +++++++++-----------------------
 server-window.c      |   50 ++++++++++----------------
 server.c             |   95 ++++++++++++++++++--------------------------------
 session.c            |    6 ++--
 status.c             |    2 +-
 tmux.h               |   15 +++++---
 tty.c                |    6 +--
 window-copy.c        |    2 +-
 window.c             |   72 +++++++++++--------------------------
 24 files changed, 236 insertions(+), 354 deletions(-)

diff --cc client.c
index 1929b2a,e2ffa54..f3fdeca
--- a/client.c
+++ b/client.c
@@@ -258,6 -258,13 +258,9 @@@ client_main(int argc, char **argv, int 
                return (1);
        }
  
 -      /* Set process title, log and signals now this is the client. */
 -      setproctitle("client (%s)", socket_path);
 -      logfile("client");
 -
+       /* Establish signal handlers. */
+       set_signals(client_signal);
+ 
        /* Initialize the client socket and start the server. */
        fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
        if (fd == -1) {


commit aeedb464a6ee038289ddcfefae437928ab020cb1
Author: nicm <nicm>
Commit: nicm <nicm>

    Convert clients list into a TAILQ.
---
 cmd-attach-session.c |    8 +----
 cmd-choose-client.c  |   24 +++++++++-------
 cmd-detach-client.c  |   13 +++------
 cmd-list-clients.c   |   15 +++++-----
 cmd-set-option.c     |    6 +---
 cmd.c                |   26 +++++++++--------
 control-notify.c     |   28 +++++--------------
 notify.c             |    6 +---
 resize.c             |    7 ++---
 server-client.c      |   45 +++++-------------------------
 server-fn.c          |   58 ++++++++++-----------------------------
 server-window.c      |   24 +++++-----------
 server.c             |   73 +++++++++++++++++++------------------------------
 tmux.h               |    4 ++-
 tty.c                |    6 +---
 15 files changed, 119 insertions(+), 224 deletions(-)

diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index a67ec82..79e1461 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -51,7 +51,6 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int 
dflag, int rflag,
        struct window_pane      *wp = NULL;
        const char              *update;
        char                    *cause;
-       u_int                    i;
        int                      fd;
        struct format_tree      *ft;
        char                    *cp;
@@ -92,11 +91,8 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, 
int dflag, int rflag,
                         * Can't use server_write_session in case attaching to
                         * the same session as currently attached to.
                         */
-                       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                               c = ARRAY_ITEM(&clients, i);
-                               if (c == NULL || c->session != s)
-                                       continue;
-                               if (c == cmdq->client)
+                       TAILQ_FOREACH(c, &clients, entry) {
+                               if (c->session != s || c == cmdq->client)
                                        continue;
                                server_write_client(c, MSG_DETACH,
                                    c->session->name,
diff --git a/cmd-choose-client.c b/cmd-choose-client.c
index 3002f7b..49fe2a3 100644
--- a/cmd-choose-client.c
+++ b/cmd-choose-client.c
@@ -59,7 +59,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
        struct winlink                  *wl;
        const char                      *template;
        char                            *action;
-       u_int                            i, idx, cur;
+       u_int                            idx, cur;
 
        if ((c = cmd_current_client(cmdq)) == NULL) {
                cmdq_error(cmdq, "no client available");
@@ -81,24 +81,24 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
                action = xstrdup("detach-client -t '%%'");
 
        cur = idx = 0;
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c1 = ARRAY_ITEM(&clients, i);
-               if (c1 == NULL || c1->session == NULL || c1->tty.path == NULL)
+       TAILQ_FOREACH(c1, &clients, entry) {
+               if (c1->session == NULL || c1->tty.path == NULL)
                        continue;
                if (c1 == cmdq->client)
                        cur = idx;
-               idx++;
 
                cdata = window_choose_data_create(TREE_OTHER, c, c->session);
-               cdata->idx = i;
+               cdata->idx = idx;
 
                cdata->ft_template = xstrdup(template);
-               format_add(cdata->ft, "line", "%u", i);
+               format_add(cdata->ft, "line", "%u", idx);
                format_defaults(cdata->ft, c1, NULL, NULL, NULL);
 
                cdata->command = cmd_template_replace(action, c1->tty.path, 1);
 
                window_choose_add(wl->window->active, cdata);
+
+               idx++;
        }
        free(action);
 
@@ -112,15 +112,19 @@ void
 cmd_choose_client_callback(struct window_choose_data *cdata)
 {
        struct client   *c;
+       u_int            idx;
 
        if (cdata == NULL)
                return;
        if (cdata->start_client->flags & CLIENT_DEAD)
                return;
 
-       if (cdata->idx > ARRAY_LENGTH(&clients) - 1)
-               return;
-       c = ARRAY_ITEM(&clients, cdata->idx);
+       idx = 0;
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (idx == cdata->idx)
+                       break;
+               idx++;
+       }
        if (c == NULL || c->session == NULL)
                return;
 
diff --git a/cmd-detach-client.c b/cmd-detach-client.c
index 7f87d2c..4bae999 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -51,7 +51,6 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
        struct client   *c, *cloop;
        struct session  *s;
        enum msgtype     msgtype;
-       u_int            i;
 
        if (self->entry == &cmd_suspend_client_entry) {
                if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
@@ -72,9 +71,8 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
                if (s == NULL)
                        return (CMD_RETURN_ERROR);
 
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       cloop = ARRAY_ITEM(&clients, i);
-                       if (cloop == NULL || cloop->session != s)
+               TAILQ_FOREACH(cloop, &clients, entry) {
+                       if (cloop->session != s)
                                continue;
                        server_write_client(cloop, msgtype,
                            cloop->session->name,
@@ -88,11 +86,8 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
                return (CMD_RETURN_ERROR);
 
        if (args_has(args, 'a')) {
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       cloop = ARRAY_ITEM(&clients, i);
-                       if (cloop == NULL || cloop->session == NULL)
-                               continue;
-                       if (cloop == c)
+               TAILQ_FOREACH(cloop, &clients, entry) {
+                       if (cloop->session == NULL || cloop == c)
                                continue;
                        server_write_client(cloop, msgtype,
                            cloop->session->name,
diff --git a/cmd-list-clients.c b/cmd-list-clients.c
index 893a6d0..372b528 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -51,7 +51,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
        struct session          *s;
        struct format_tree      *ft;
        const char              *template;
-       u_int                    i;
+       u_int                    idx;
        char                    *line;
 
        if (args_has(args, 't')) {
@@ -64,16 +64,13 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
        if ((template = args_get(args, 'F')) == NULL)
                template = LIST_CLIENTS_TEMPLATE;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
-
-               if (s != NULL && s != c->session)
+       idx = 0;
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == NULL || (s != NULL && s != c->session))
                        continue;
 
                ft = format_create();
-               format_add(ft, "line", "%u", i);
+               format_add(ft, "line", "%u", idx);
                format_defaults(ft, c, NULL, NULL, NULL);
 
                line = format_expand(ft, template);
@@ -81,6 +78,8 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
                free(line);
 
                format_free(ft);
+
+               idx++;
        }
 
        return (CMD_RETURN_NORMAL);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index e0d1ae6..83d31b9 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -91,7 +91,6 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
        struct options                          *oo;
        struct window                           *w;
        const char                              *optstr, *valstr;
-       u_int                                    i;
 
        /* Get the option name and value. */
        optstr = args->argv[0];
@@ -186,9 +185,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
 
        /* Update sizes and redraw. May not need it but meh. */
        recalculate_sizes();
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c != NULL && c->session != NULL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != NULL)
                        server_redraw_client(c);
        }
 
diff --git a/cmd.c b/cmd.c
index 991e079..b81ffb3 100644
--- a/cmd.c
+++ b/cmd.c
@@ -116,10 +116,12 @@ const struct cmd_entry *cmd_table[] = {
        NULL
 };
 
+ARRAY_DECL(client_list, struct client *);
+
 int             cmd_session_better(struct session *, struct session *, int);
 struct session *cmd_choose_session_list(struct sessionslist *);
 struct session *cmd_choose_session(int);
-struct client  *cmd_choose_client(struct clients *);
+struct client  *cmd_choose_client(struct client_list *);
 struct client  *cmd_lookup_client(const char *);
 struct session *cmd_lookup_session(struct cmd_q *, const char *, int *);
 struct session *cmd_lookup_session_id(const char *);
@@ -452,8 +454,7 @@ cmd_current_client(struct cmd_q *cmdq)
 {
        struct session          *s;
        struct client           *c;
-       struct clients           cc;
-       u_int                    i;
+       struct client_list       cc;
 
        if (cmdq->client != NULL && cmdq->client->session != NULL)
                return (cmdq->client);
@@ -465,9 +466,7 @@ cmd_current_client(struct cmd_q *cmdq)
        s = cmd_current_session(cmdq, 0);
        if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
                ARRAY_INIT(&cc);
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       if ((c = ARRAY_ITEM(&clients, i)) == NULL)
-                               continue;
+               TAILQ_FOREACH(c, &clients, entry) {
                        if (s == c->session)
                                ARRAY_ADD(&cc, c);
                }
@@ -478,12 +477,17 @@ cmd_current_client(struct cmd_q *cmdq)
                        return (c);
        }
 
-       return (cmd_choose_client(&clients));
+       ARRAY_INIT(&cc);
+       TAILQ_FOREACH(c, &clients, entry)
+               ARRAY_ADD(&cc, c);
+       c = cmd_choose_client(&cc);
+       ARRAY_FREE(&cc);
+       return (c);
 }
 
 /* Choose the most recently used client from a list. */
 struct client *
-cmd_choose_client(struct clients *cc)
+cmd_choose_client(struct client_list *cc)
 {
        struct client   *c, *cbest;
        struct timeval  *tv = NULL;
@@ -615,11 +619,9 @@ cmd_lookup_client(const char *name)
 {
        struct client   *c;
        const char      *path;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL || c->tty.path == NULL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == NULL || c->tty.path == NULL)
                        continue;
                path = c->tty.path;
 
diff --git a/control-notify.c b/control-notify.c
index 747ef5b..943d670 100644
--- a/control-notify.c
+++ b/control-notify.c
@@ -64,11 +64,9 @@ control_notify_window_layout_changed(struct window *w)
        struct session          *s;
        struct format_tree      *ft;
        struct winlink          *wl;
-       u_int                    i;
        const char              *template;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                        continue;
                s = c->session;
@@ -100,10 +98,8 @@ control_notify_window_unlinked(unused struct session *s, 
struct window *w)
 {
        struct client   *c;
        struct session  *cs;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                        continue;
                cs = c->session;
@@ -120,10 +116,8 @@ control_notify_window_linked(unused struct session *s, 
struct window *w)
 {
        struct client   *c;
        struct session  *cs;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                        continue;
                cs = c->session;
@@ -140,10 +134,8 @@ control_notify_window_renamed(struct window *w)
 {
        struct client   *c;
        struct session  *cs;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c) || c->session == NULL)
                        continue;
                cs = c->session;
@@ -174,10 +166,8 @@ void
 control_notify_session_renamed(struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                        continue;
 
@@ -189,10 +179,8 @@ void
 control_notify_session_created(unused struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                        continue;
 
@@ -204,10 +192,8 @@ void
 control_notify_session_close(unused struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
+       TAILQ_FOREACH(c, &clients, entry) {
                if (!CONTROL_SHOULD_NOTIFY_CLIENT(c))
                        continue;
 
diff --git a/notify.c b/notify.c
index 75a16de..19bf17e 100644
--- a/notify.c
+++ b/notify.c
@@ -136,7 +136,6 @@ void
 notify_input(struct window_pane *wp, struct evbuffer *input)
 {
        struct client   *c;
-       u_int            i;
 
        /*
         * notify_input() is not queued and only does anything when
@@ -145,9 +144,8 @@ notify_input(struct window_pane *wp, struct evbuffer *input)
        if (!notify_enabled)
                return;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c != NULL && (c->flags & CLIENT_CONTROL))
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->flags & CLIENT_CONTROL)
                        control_notify_input(c, wp, input);
        }
 }
diff --git a/resize.c b/resize.c
index 330c37b..3606bfe 100644
--- a/resize.c
+++ b/resize.c
@@ -49,7 +49,7 @@ recalculate_sizes(void)
        struct client           *c;
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i, ssx, ssy, has, limit;
+       u_int                    ssx, ssy, has, limit;
        int                      flag, has_status, is_zoomed, forced;
 
        RB_FOREACH(s, sessions, &sessions) {
@@ -57,9 +57,8 @@ recalculate_sizes(void)
 
                s->attached = 0;
                ssx = ssy = UINT_MAX;
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       c = ARRAY_ITEM(&clients, i);
-                       if (c == NULL || c->flags & CLIENT_SUSPENDED)
+               TAILQ_FOREACH(c, &clients, entry) {
+                       if (c->flags & CLIENT_SUSPENDED)
                                continue;
                        if (c->session == s) {
                                if (c->tty.sx < ssx)
diff --git a/server-client.c b/server-client.c
index e2f65e7..a0f81b7 100644
--- a/server-client.c
+++ b/server-client.c
@@ -60,7 +60,6 @@ void
 server_client_create(int fd)
 {
        struct client   *c;
-       u_int            i;
 
        setblocking(fd, 0);
 
@@ -108,13 +107,7 @@ server_client_create(int fd)
 
        evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               if (ARRAY_ITEM(&clients, i) == NULL) {
-                       ARRAY_SET(&clients, i, c);
-                       return;
-               }
-       }
-       ARRAY_ADD(&clients, c);
+       TAILQ_INSERT_TAIL(&clients, c, entry);
        log_debug("new client %d", fd);
 }
 
@@ -148,10 +141,7 @@ server_client_lost(struct client *c)
        struct message_entry    *msg;
        u_int                    i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               if (ARRAY_ITEM(&clients, i) == c)
-                       ARRAY_SET(&clients, i, NULL);
-       }
+       TAILQ_REMOVE(&clients, c, entry);
        log_debug("lost client %d", c->ibuf.fd);
 
        /*
@@ -205,14 +195,7 @@ server_client_lost(struct client *c)
        if (event_initialized(&c->event))
                event_del(&c->event);
 
-       for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
-               if (ARRAY_ITEM(&dead_clients, i) == NULL) {
-                       ARRAY_SET(&dead_clients, i, c);
-                       break;
-               }
-       }
-       if (i == ARRAY_LENGTH(&dead_clients))
-               ARRAY_ADD(&dead_clients, c);
+       TAILQ_INSERT_TAIL(&dead_clients, c, entry);
        c->flags |= CLIENT_DEAD;
 
        server_add_accept(0); /* may be more file descriptors now */
@@ -263,16 +246,14 @@ server_client_status_timer(void)
        struct client   *c;
        struct session  *s;
        struct timeval   tv;
-       u_int            i;
        int              interval;
        time_t           difference;
 
        if (gettimeofday(&tv, NULL) != 0)
                fatal("gettimeofday failed");
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == NULL)
                        continue;
                if (c->message_string != NULL || c->prompt_string != NULL) {
                        /*
@@ -702,13 +683,8 @@ server_client_loop(void)
        struct client           *c;
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i;
-
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL)
-                       continue;
 
+       TAILQ_FOREACH(c, &clients, entry) {
                server_client_check_exit(c);
                if (c->session != NULL) {
                        server_client_check_redraw(c);
@@ -755,7 +731,6 @@ server_client_check_resize(struct window_pane *wp)
 void
 server_client_check_focus(struct window_pane *wp)
 {
-       u_int            i;
        struct client   *c;
        int              push;
 
@@ -783,12 +758,8 @@ server_client_check_focus(struct window_pane *wp)
         * If our window is the current window in any focused clients with an
         * attached session, we're focused.
         */
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
-
-               if (!(c->flags & CLIENT_FOCUSED))
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == NULL || !(c->flags & CLIENT_FOCUSED))
                        continue;
                if (c->session->flags & SESSION_UNATTACHED)
                        continue;
diff --git a/server-fn.c b/server-fn.c
index c5487aa..85067a8 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -77,12 +77,8 @@ server_write_session(struct session *s, enum msgtype type, 
const void *buf,
     size_t len)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
+       TAILQ_FOREACH(c, &clients, entry) {
                if (c->session == s)
                        server_write_client(c, type, buf, len);
        }
@@ -104,12 +100,8 @@ void
 server_redraw_session(struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
+       TAILQ_FOREACH(c, &clients, entry) {
                if (c->session == s)
                        server_redraw_client(c);
        }
@@ -132,12 +124,8 @@ void
 server_status_session(struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
+       TAILQ_FOREACH(c, &clients, entry) {
                if (c->session == s)
                        server_status_client(c);
        }
@@ -160,13 +148,9 @@ void
 server_redraw_window(struct window *w)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
-               if (c->session->curw->window == w)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != NULL && c->session->curw->window == w)
                        server_redraw_client(c);
        }
        w->flags |= WINDOW_REDRAW;
@@ -176,13 +160,9 @@ void
 server_redraw_window_borders(struct window *w)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
-               if (c->session->curw->window == w)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != NULL && c->session->curw->window == w)
                        c->flags |= CLIENT_BORDERS;
        }
 }
@@ -208,13 +188,10 @@ void
 server_lock(void)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL)
-                       continue;
-               server_lock_client(c);
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != NULL)
+                       server_lock_client(c);
        }
 }
 
@@ -222,13 +199,10 @@ void
 server_lock_session(struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL || c->session != s)
-                       continue;
-               server_lock_client(c);
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == s)
+                       server_lock_client(c);
        }
 }
 
@@ -430,16 +404,14 @@ server_destroy_session(struct session *s)
 {
        struct client   *c;
        struct session  *s_new;
-       u_int            i;
 
        if (!options_get_number(&s->options, "detach-on-destroy"))
                s_new = server_next_session(s);
        else
                s_new = NULL;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session != s)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != s)
                        continue;
                if (s_new == NULL) {
                        c->session = NULL;
diff --git a/server-window.c b/server-window.c
index f157da3..4385dd9 100644
--- a/server-window.c
+++ b/server-window.c
@@ -58,7 +58,6 @@ server_window_check_bell(struct session *s, struct winlink 
*wl)
 {
        struct client   *c;
        struct window   *w = wl->window;
-       u_int            i;
        int              action, visual;
 
        if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
@@ -74,9 +73,8 @@ server_window_check_bell(struct session *s, struct winlink 
*wl)
        action = options_get_number(&s->options, "bell-action");
        if (action == BELL_NONE)
                return (0);
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session != s || c->flags & CLIENT_CONTROL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != s || c->flags & CLIENT_CONTROL)
                        continue;
                if (!visual) {
                        if (c->session->curw->window == w || action == BELL_ANY)
@@ -98,7 +96,6 @@ server_window_check_activity(struct session *s, struct 
winlink *wl)
 {
        struct client   *c;
        struct window   *w = wl->window;
-       u_int            i;
 
        if (s->curw->window == w)
                w->flags &= ~WINDOW_ACTIVITY;
@@ -116,9 +113,8 @@ server_window_check_activity(struct session *s, struct 
winlink *wl)
        wl->flags |= WINLINK_ACTIVITY;
 
        if (options_get_number(&s->options, "visual-activity")) {
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       c = ARRAY_ITEM(&clients, i);
-                       if (c == NULL || c->session != s)
+               TAILQ_FOREACH(c, &clients, entry) {
+                       if (c->session != s)
                                continue;
                        status_message_set(c, "Activity in window %d", wl->idx);
                }
@@ -134,7 +130,6 @@ server_window_check_silence(struct session *s, struct 
winlink *wl)
        struct client   *c;
        struct window   *w = wl->window;
        struct timeval   timer;
-       u_int            i;
        int              silence_interval, timer_difference;
 
        if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
@@ -167,9 +162,8 @@ server_window_check_silence(struct session *s, struct 
winlink *wl)
        wl->flags |= WINLINK_SILENCE;
 
        if (options_get_number(&s->options, "visual-silence")) {
-               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-                       c = ARRAY_ITEM(&clients, i);
-                       if (c == NULL || c->session != s)
+               TAILQ_FOREACH(c, &clients, entry) {
+                       if (c->session != s)
                                continue;
                        status_message_set(c, "Silence in window %d", wl->idx);
                }
@@ -183,11 +177,9 @@ void
 ring_bell(struct session *s)
 {
        struct client   *c;
-       u_int            i;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c != NULL && c->session == s && !(c->flags & 
CLIENT_CONTROL))
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == s && !(c->flags & CLIENT_CONTROL))
                        tty_bell(&c->tty);
        }
 }
diff --git a/server.c b/server.c
index 1183d64..ba161c4 100644
--- a/server.c
+++ b/server.c
@@ -139,8 +139,8 @@ server_start(int lockfd, char *lockfile)
 
        RB_INIT(&windows);
        RB_INIT(&all_window_panes);
-       ARRAY_INIT(&clients);
-       ARRAY_INIT(&dead_clients);
+       TAILQ_INIT(&clients);
+       TAILQ_INIT(&dead_clients);
        RB_INIT(&sessions);
        RB_INIT(&dead_sessions);
        TAILQ_INIT(&session_groups);
@@ -166,7 +166,7 @@ server_start(int lockfd, char *lockfile)
        cfg_cmd_q->emptyfn = cfg_default_done;
        cfg_finished = 0;
        cfg_references = 1;
-       cfg_client = ARRAY_FIRST(&clients);
+       cfg_client = TAILQ_FIRST(&clients);
        if (cfg_client != NULL)
                cfg_client->references++;
 
@@ -212,16 +212,14 @@ int
 server_should_shutdown(void)
 {
        struct client   *c;
-       u_int            i;
 
        if (!options_get_number(&global_options, "exit-unattached")) {
                if (!RB_EMPTY(&sessions))
                        return (0);
        }
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c != NULL && c->session != NULL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session != NULL)
                        return (0);
        }
 
@@ -230,10 +228,8 @@ server_should_shutdown(void)
         * clients but don't actually exit until they've gone.
         */
        cmd_wait_for_flush();
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               if (ARRAY_ITEM(&clients, i) != NULL)
-                       return (0);
-       }
+       if (!TAILQ_EMPTY(&clients))
+               return (0);
 
        return (1);
 }
@@ -242,55 +238,42 @@ server_should_shutdown(void)
 void
 server_send_shutdown(void)
 {
-       struct client   *c;
-       struct session  *s, *next_s;
-       u_int            i;
+       struct client   *c, *c1;
+       struct session  *s, *s1;
 
        cmd_wait_for_flush();
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c != NULL) {
-                       if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
-                               server_client_lost(c);
-                       else
-                               server_write_client(c, MSG_SHUTDOWN, NULL, 0);
-                       c->session = NULL;
-               }
+       TAILQ_FOREACH_SAFE(c, &clients, entry, c1) {
+               if (c->flags & (CLIENT_BAD|CLIENT_SUSPENDED))
+                       server_client_lost(c);
+               else
+                       server_write_client(c, MSG_SHUTDOWN, NULL, 0);
+               c->session = NULL;
        }
 
-       s = RB_MIN(sessions, &sessions);
-       while (s != NULL) {
-               next_s = RB_NEXT(sessions, &sessions, s);
+       RB_FOREACH_SAFE(s, sessions, &sessions, s1)
                session_destroy(s);
-               s = next_s;
-       }
 }
 
 /* Free dead, unreferenced clients and sessions. */
 void
 server_clean_dead(void)
 {
-       struct session  *s, *next_s;
-       struct client   *c;
-       u_int            i;
-
-       s = RB_MIN(sessions, &dead_sessions);
-       while (s != NULL) {
-               next_s = RB_NEXT(sessions, &dead_sessions, s);
-               if (s->references == 0) {
-                       RB_REMOVE(sessions, &dead_sessions, s);
-                       free(s->name);
-                       free(s);
-               }
-               s = next_s;
+       struct session  *s, *s1;
+       struct client   *c, *c1;
+
+       RB_FOREACH_SAFE(s, sessions, &dead_sessions, s1) {
+               if (s->references != 0)
+                       continue;
+               RB_REMOVE(sessions, &dead_sessions, s);
+               free(s->name);
+               free(s);
        }
 
-       for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
-               c = ARRAY_ITEM(&dead_clients, i);
-               if (c == NULL || c->references != 0)
+       TAILQ_FOREACH_SAFE(c, &dead_clients, entry, c1) {
+               if (c->references != 0)
                        continue;
-               ARRAY_SET(&dead_clients, i, NULL);
+               TAILQ_REMOVE(&dead_clients, c, entry);
                free(c);
        }
 }
diff --git a/tmux.h b/tmux.h
index 9a6e4c8..c38149a 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1349,8 +1349,10 @@ struct client {
 
        struct cmd_q    *cmdq;
        int              references;
+
+       TAILQ_ENTRY(client) entry;
 };
-ARRAY_DECL(clients, struct client *);
+TAILQ_HEAD(clients, client);
 
 /* Parsed arguments structures. */
 struct args_entry {
diff --git a/tty.c b/tty.c
index a5067b1..aae7b89 100644
--- a/tty.c
+++ b/tty.c
@@ -708,7 +708,6 @@ tty_write(
 {
        struct window_pane      *wp = ctx->wp;
        struct client           *c;
-       u_int                    i;
 
        /* wp can be NULL if updating the screen but not the terminal. */
        if (wp == NULL)
@@ -719,9 +718,8 @@ tty_write(
        if (!window_pane_visible(wp) || wp->flags & PANE_DROP)
                return;
 
-       for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
-               c = ARRAY_ITEM(&clients, i);
-               if (c == NULL || c->session == NULL || c->tty.term == NULL)
+       TAILQ_FOREACH(c, &clients, entry) {
+               if (c->session == NULL || c->tty.term == NULL)
                        continue;
                if (c->flags & CLIENT_SUSPENDED)
                        continue;


commit 583b4ab72b7bf66fda8ab63a08fe435483de5e5a
Author: nicm <nicm>
Commit: nicm <nicm>

    Set working directory for run-shell and if-shell.
---
 cmd-if-shell.c  |   15 ++++++++++++---
 cmd-run-shell.c |   15 ++++++++++++---
 job.c           |    5 ++++-
 status.c        |    2 +-
 tmux.h          |    2 +-
 window-copy.c   |    2 +-
 6 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/cmd-if-shell.c b/cmd-if-shell.c
index cdd2135..a307bd2 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -66,16 +66,24 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        struct winlink                  *wl = NULL;
        struct window_pane              *wp = NULL;
        struct format_tree              *ft;
+       int                              cwd;
 
-       if (args_has(args, 't'))
+       if (args_has(args, 't')) {
                wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
-       else {
+               cwd = wp->cwd;
+       } else {
                c = cmd_find_client(cmdq, NULL, 1);
                if (c != NULL && c->session != NULL) {
                        s = c->session;
                        wl = s->curw;
                        wp = wl->window->active;
                }
+               if (cmdq->client != NULL && cmdq->client->session == NULL)
+                       cwd = cmdq->client->cwd;
+               else if (s != NULL)
+                       cwd = s->cwd;
+               else
+                       cwd = -1;
        }
 
        ft = format_create();
@@ -118,7 +126,8 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        cmdq->references++;
 
        cdata->references = 1;
-       job_run(shellcmd, s, cmd_if_shell_callback, cmd_if_shell_free, cdata);
+       job_run(shellcmd, s, cwd, cmd_if_shell_callback, cmd_if_shell_free,
+           cdata);
        free(shellcmd);
 
        if (cdata->bflag)
diff --git a/cmd-run-shell.c b/cmd-run-shell.c
index 5d6d178..134cbeb 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -80,16 +80,24 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        struct winlink                  *wl = NULL;
        struct window_pane              *wp = NULL;
        struct format_tree              *ft;
+       int                              cwd;
 
-       if (args_has(args, 't'))
+       if (args_has(args, 't')) {
                wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
-       else {
+               cwd = wp->cwd;
+       } else {
                c = cmd_find_client(cmdq, NULL, 1);
                if (c != NULL && c->session != NULL) {
                        s = c->session;
                        wl = s->curw;
                        wp = wl->window->active;
                }
+               if (cmdq->client != NULL && cmdq->client->session == NULL)
+                       cwd = cmdq->client->cwd;
+               else if (s != NULL)
+                       cwd = s->cwd;
+               else
+                       cwd = -1;
        }
 
        ft = format_create();
@@ -105,7 +113,8 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
        cdata->cmdq = cmdq;
        cmdq->references++;
 
-       job_run(shellcmd, s, cmd_run_shell_callback, cmd_run_shell_free, cdata);
+       job_run(shellcmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free,
+           cdata);
 
        if (cdata->bflag)
                return (CMD_RETURN_NORMAL);
diff --git a/job.c b/job.c
index c04a70b..5675eec 100644
--- a/job.c
+++ b/job.c
@@ -41,7 +41,7 @@ struct joblist        all_jobs = 
LIST_HEAD_INITIALIZER(all_jobs);
 
 /* Start a job running, if it isn't already. */
 struct job *
-job_run(const char *cmd, struct session *s,
+job_run(const char *cmd, struct session *s, int cwd,
     void (*callbackfn)(struct job *), void (*freefn)(void *), void *data)
 {
        struct job      *job;
@@ -67,6 +67,9 @@ job_run(const char *cmd, struct session *s,
        case 0:         /* child */
                clear_signals(1);
 
+               if (cwd != -1 && fchdir(cwd) != 0)
+                       chdir("/");
+
                environ_push(&env);
                environ_free(&env);
 
diff --git a/status.c b/status.c
index ae5d99a..fd0292c 100644
--- a/status.c
+++ b/status.c
@@ -515,7 +515,7 @@ status_find_job(struct client *c, char **iptr)
 
        /* If not found at all, start the job and add to the tree. */
        if (so == NULL) {
-               job_run(cmd, NULL, status_job_callback, status_job_free, c);
+               job_run(cmd, NULL, -1, status_job_callback, status_job_free, c);
                c->references++;
 
                so = xmalloc(sizeof *so);
diff --git a/tmux.h b/tmux.h
index a47218e..9a6e4c8 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1613,7 +1613,7 @@ int       options_table_find(const char *, const struct 
options_table_entry **,
 
 /* job.c */
 extern struct joblist all_jobs;
-struct job *job_run(const char *, struct session *,
+struct job *job_run(const char *, struct session *, int,
            void (*)(struct job *), void (*)(void *), void *);
 void   job_free(struct job *);
 void   job_died(struct job *, int);
diff --git a/window-copy.c b/window-copy.c
index eb00131..7d5bae4 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1465,7 +1465,7 @@ window_copy_copy_pipe(struct window_pane *wp, struct 
session *sess,
        format_defaults(ft, NULL, sess, NULL, wp);
        expanded = format_expand(ft, arg);
 
-       job = job_run(expanded, sess, NULL, NULL, NULL);
+       job = job_run(expanded, sess, -1, NULL, NULL, NULL);
        bufferevent_write(job->event, buf, len);
 
        free(expanded);


commit 5a2d0533a84a13613fb356b66ed8ada2a65f6edf
Author: nicm <nicm>
Commit: nicm <nicm>

    Allow choice options (multiple states) to be toggled between states 0
    and 1.
---
 cmd-set-option.c |   44 ++++++++++++++++++++++++++++----------------
 1 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/cmd-set-option.c b/cmd-set-option.c
index e236b95..e0d1ae6 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -289,9 +289,15 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
 {
        struct options_entry    *o;
 
-       if (oe->type != OPTIONS_TABLE_FLAG && value == NULL) {
-               cmdq_error(cmdq, "empty value");
-               return (-1);
+       switch (oe->type) {
+       case OPTIONS_TABLE_FLAG:
+       case OPTIONS_TABLE_CHOICE:
+               break;
+       default:
+               if (value == NULL) {
+                       cmdq_error(cmdq, "empty value");
+                       return (-1);
+               }
        }
 
        o = NULL;
@@ -455,21 +461,27 @@ cmd_set_option_choice(unused struct cmd *self, struct 
cmd_q *cmdq,
        const char      **choicep;
        int               n, choice = -1;
 
-       n = 0;
-       for (choicep = oe->choices; *choicep != NULL; choicep++) {
-               n++;
-               if (strncmp(*choicep, value, strlen(value)) != 0)
-                       continue;
-
-               if (choice != -1) {
-                       cmdq_error(cmdq, "ambiguous value: %s", value);
+       if (value == NULL) {
+               choice = options_get_number(oo, oe->name);
+               if (choice < 2)
+                       choice = !choice;
+       } else {
+               n = 0;
+               for (choicep = oe->choices; *choicep != NULL; choicep++) {
+                       n++;
+                       if (strncmp(*choicep, value, strlen(value)) != 0)
+                               continue;
+
+                       if (choice != -1) {
+                               cmdq_error(cmdq, "ambiguous value: %s", value);
+                               return (NULL);
+                       }
+                       choice = n - 1;
+               }
+               if (choice == -1) {
+                       cmdq_error(cmdq, "unknown value: %s", value);
                        return (NULL);
                }
-               choice = n - 1;
-       }
-       if (choice == -1) {
-               cmdq_error(cmdq, "unknown value: %s", value);
-               return (NULL);
        }
 
        return (options_set_number(oo, oe->name, choice));


commit a5a873dcccaabd55dbb0ad32abafbf1049316392
Author: nicm <nicm>
Commit: nicm <nicm>

    Set up signal handler earlier so that we don't get zombies, reported by
    sobrado@.
---
 client.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/client.c b/client.c
index d3ff05a..e2ffa54 100644
--- a/client.c
+++ b/client.c
@@ -262,6 +262,9 @@ client_main(int argc, char **argv, int flags)
        setproctitle("client (%s)", socket_path);
        logfile("client");
 
+       /* Establish signal handlers. */
+       set_signals(client_signal);
+
        /* Initialize the client socket and start the server. */
        fd = client_connect(socket_path, cmdflags & CMD_STARTSERVER);
        if (fd == -1) {
@@ -301,9 +304,6 @@ client_main(int argc, char **argv, int flags)
                tcsetattr(STDIN_FILENO, TCSANOW, &tio);
        }
 
-       /* Establish signal handlers. */
-       set_signals(client_signal);
-
        /* Send identify messages. */
        client_send_identify(flags);
 


commit ab73997cc5bd652370beef93db5fca439448734a
Author: deraadt <deraadt>
Commit: deraadt <deraadt>

    use reallocarray instead of calloc; avoid the zero before infill
    ok nicm
---
 grid.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/grid.c b/grid.c
index ef7c374..2dc266d 100644
--- a/grid.c
+++ b/grid.c
@@ -657,7 +657,7 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct 
grid *src, u_int sy,
 
                memcpy(dstl, srcl, sizeof *dstl);
                if (srcl->cellsize != 0) {
-                       dstl->celldata = xcalloc(
+                       dstl->celldata = xreallocarray(NULL,
                            srcl->cellsize, sizeof *dstl->celldata);
                        memcpy(dstl->celldata, srcl->celldata,
                            srcl->cellsize * sizeof *dstl->celldata);


commit 9a453dd3546b2c3053e8e34bf4d6775b1a05d3a8
Author: nicm <nicm>
Commit: nicm <nicm>

    Make session_has return a flag, returning the first winlink found is a
    recipe for errors.
---
 resize.c    |    2 +-
 server-fn.c |    4 ++--
 session.c   |    6 +++---
 tmux.h      |    2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/resize.c b/resize.c
index 5b89b09..330c37b 100644
--- a/resize.c
+++ b/resize.c
@@ -104,7 +104,7 @@ recalculate_sizes(void)
                        if (flag)
                                has = s->curw->window == w;
                        else
-                               has = session_has(s, w) != NULL;
+                               has = session_has(s, w);
                        if (has) {
                                if (s->sx < ssx)
                                        ssx = s->sx;
diff --git a/server-fn.c b/server-fn.c
index 83ea947..c5487aa 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -199,7 +199,7 @@ server_status_window(struct window *w)
         */
 
        RB_FOREACH(s, sessions, &sessions) {
-               if (session_has(s, w) != NULL)
+               if (session_has(s, w))
                        server_status_session(s);
        }
 }
@@ -268,7 +268,7 @@ server_kill_window(struct window *w)
                s = next_s;
                next_s = RB_NEXT(sessions, &sessions, s);
 
-               if (session_has(s, w) == NULL)
+               if (!session_has(s, w))
                        continue;
                server_unzoom_window(w);
                while ((wl = winlink_find_by_window(&s->windows, w)) != NULL) {
diff --git a/session.c b/session.c
index 03ddb10..c053572 100644
--- a/session.c
+++ b/session.c
@@ -309,16 +309,16 @@ session_detach(struct session *s, struct winlink *wl)
 }
 
 /* Return if session has window. */
-struct winlink *
+int
 session_has(struct session *s, struct window *w)
 {
        struct winlink  *wl;
 
        RB_FOREACH(wl, winlinks, &s->windows) {
                if (wl->window == w)
-                       return (wl);
+                       return (1);
        }
-       return (NULL);
+       return (0);
 }
 
 struct winlink *
diff --git a/tmux.h b/tmux.h
index e52b14f..a47218e 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2321,7 +2321,7 @@ struct winlink    *session_new(struct session *, const 
char *, int, char **,
 struct winlink *session_attach(struct session *, struct window *, int,
                     char **);
 int             session_detach(struct session *, struct winlink *);
-struct winlink *session_has(struct session *, struct window *);
+int             session_has(struct session *, struct window *);
 int             session_next(struct session *, int);
 int             session_previous(struct session *, int);
 int             session_select(struct session *, int);


commit 8d66f4fba4972d45be64d108c7c8d952f85016a8
Author: nicm <nicm>
Commit: nicm <nicm>

    Change the windows array into an RB tree and fix some places where we
    were only looking at the first winlink for a window in a session.
---
 cmd-set-option.c |    4 +--
 resize.c         |   11 ++++-----
 server-client.c  |    6 +----
 server-window.c  |   24 ++++++++-----------
 server.c         |   21 ++++-------------
 tmux.h           |    6 ++++-
 window.c         |   66 ++++++++++++++++++------------------------------------
 7 files changed, 49 insertions(+), 89 deletions(-)

diff --git a/cmd-set-option.c b/cmd-set-option.c
index 01d691d..e236b95 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -176,9 +176,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
 
        /* Start or stop timers when automatic-rename changed. */
        if (strcmp(oe->name, "automatic-rename") == 0) {
-               for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-                       if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                               continue;
+               RB_FOREACH(w, windows, &windows) {
                        if (options_get_number(&w->options, "automatic-rename"))
                                queue_window_name(w);
                        else if (event_initialized(&w->name_timer))
diff --git a/resize.c b/resize.c
index 9ad73c8..5b89b09 100644
--- a/resize.c
+++ b/resize.c
@@ -49,7 +49,7 @@ recalculate_sizes(void)
        struct client           *c;
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i, j, ssx, ssy, has, limit;
+       u_int                    i, ssx, ssy, has, limit;
        int                      flag, has_status, is_zoomed, forced;
 
        RB_FOREACH(s, sessions, &sessions) {
@@ -57,8 +57,8 @@ recalculate_sizes(void)
 
                s->attached = 0;
                ssx = ssy = UINT_MAX;
-               for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
-                       c = ARRAY_ITEM(&clients, j);
+               for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+                       c = ARRAY_ITEM(&clients, i);
                        if (c == NULL || c->flags & CLIENT_SUSPENDED)
                                continue;
                        if (c->session == s) {
@@ -92,9 +92,8 @@ recalculate_sizes(void)
                s->sy = ssy;
        }
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL || w->active == NULL)
+       RB_FOREACH(w, windows, &windows) {
+               if (w->active == NULL)
                        continue;
                flag = options_get_number(&w->options, "aggressive-resize");
 
diff --git a/server-client.c b/server-client.c
index c022a36..e2f65e7 100644
--- a/server-client.c
+++ b/server-client.c
@@ -720,11 +720,7 @@ server_client_loop(void)
         * Any windows will have been redrawn as part of clients, so clear
         * their flags now. Also check pane focus and resize.
         */
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
-
+       RB_FOREACH(w, windows, &windows) {
                w->flags &= ~WINDOW_REDRAW;
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->fd != -1) {
diff --git a/server-window.c b/server-window.c
index a235570..f157da3 100644
--- a/server-window.c
+++ b/server-window.c
@@ -34,24 +34,20 @@ void
 server_window_loop(void)
 {
        struct window   *w;
-       struct winlink  *wl;
        struct session  *s;
-       u_int            i;
-
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
+       struct winlink  *wl;
 
+       RB_FOREACH(w, windows, &windows) {
                RB_FOREACH(s, sessions, &sessions) {
-                       wl = session_has(s, w);
-                       if (wl == NULL)
-                               continue;
-
-                       if (server_window_check_bell(s, wl) ||
-                           server_window_check_activity(s, wl) ||
-                           server_window_check_silence(s, wl))
-                               server_status_session(s);
+                       RB_FOREACH(wl, winlinks, &s->windows) {
+                               if (wl->window != w)
+                                       continue;
+
+                               if (server_window_check_bell(s, wl) ||
+                                   server_window_check_activity(s, wl) ||
+                                   server_window_check_silence(s, wl))
+                                       server_status_session(s);
+                       }
                }
        }
 }
diff --git a/server.c b/server.c
index bb96d9a..1183d64 100644
--- a/server.c
+++ b/server.c
@@ -137,7 +137,7 @@ server_start(int lockfd, char *lockfile)
        logfile("server");
        log_debug("server started, pid %ld", (long) getpid());
 
-       ARRAY_INIT(&windows);
+       RB_INIT(&windows);
        RB_INIT(&all_window_panes);
        ARRAY_INIT(&clients);
        ARRAY_INIT(&dead_clients);
@@ -438,14 +438,11 @@ server_child_signal(void)
 void
 server_child_exited(pid_t pid, int status)
 {
-       struct window           *w;
+       struct window           *w, *w1;
        struct window_pane      *wp;
        struct job              *job;
-       u_int                    i;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
+       RB_FOREACH_SAFE(w, windows, &windows, w1) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->pid == pid) {
                                wp->status = status;
@@ -469,14 +466,11 @@ server_child_stopped(pid_t pid, int status)
 {
        struct window           *w;
        struct window_pane      *wp;
-       u_int                    i;
 
        if (WSTOPSIG(status) == SIGTTIN || WSTOPSIG(status) == SIGTTOU)
                return;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
+       RB_FOREACH(w, windows, &windows) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->pid == pid) {
                                if (killpg(pid, SIGCONT) != 0)
@@ -493,18 +487,13 @@ server_second_callback(unused int fd, unused short 
events, unused void *arg)
        struct window           *w;
        struct window_pane      *wp;
        struct timeval           tv;
-       u_int                    i;
 
        if (options_get_number(&global_s_options, "lock-server"))
                server_lock_server();
        else
                server_lock_sessions();
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w == NULL)
-                       continue;
-
+       RB_FOREACH(w, windows, &windows) {
                TAILQ_FOREACH(wp, &w->panes, entry) {
                        if (wp->mode != NULL && wp->mode->timer != NULL)
                                wp->mode->timer(wp);
diff --git a/tmux.h b/tmux.h
index 52dc152..e52b14f 100644
--- a/tmux.h
+++ b/tmux.h
@@ -983,8 +983,10 @@ struct window {
        struct options   options;
 
        u_int            references;
+
+       RB_ENTRY(window) entry;
 };
-ARRAY_DECL(windows, struct window *);
+RB_HEAD(windows, window);
 
 /* Entry on local window list. */
 struct winlink {
@@ -2121,6 +2123,8 @@ void       screen_reflow(struct screen *, u_int);
 /* window.c */
 extern struct windows windows;
 extern struct window_pane_tree all_window_panes;
+int             window_cmp(struct window *, struct window *);
+RB_PROTOTYPE(windows, window, entry, window_cmp);
 int             winlink_cmp(struct winlink *, struct winlink *);
 RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
 int             window_pane_cmp(struct window_pane *, struct window_pane *);
diff --git a/window.c b/window.c
index d8f2902..5ca8aa0 100644
--- a/window.c
+++ b/window.c
@@ -64,6 +64,14 @@ void window_pane_error_callback(struct bufferevent *, short, 
void *);
 
 struct window_pane *window_pane_choose_best(struct window_pane_list *);
 
+RB_GENERATE(windows, window, entry, window_cmp);
+
+int
+window_cmp(struct window *w1, struct window *w2)
+{
+       return (w1->id - w2->id);
+}
+
 RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
 
 int
@@ -248,25 +256,18 @@ winlink_stack_remove(struct winlink_stack *stack, struct 
winlink *wl)
 struct window *
 window_find_by_id(u_int id)
 {
-       struct window   *w;
-       u_int            i;
+       struct window   w;
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               w = ARRAY_ITEM(&windows, i);
-               if (w != NULL && w->id == id)
-                       return (w);
-       }
-       return (NULL);
+       w.id = id;
+       return (RB_FIND(windows, &windows, &w));
 }
 
 struct window *
 window_create1(u_int sx, u_int sy)
 {
        struct window   *w;
-       u_int            i;
 
        w = xcalloc(1, sizeof *w);
-       w->id = next_window_id++;
        w->name = NULL;
        w->flags = 0;
 
@@ -283,16 +284,11 @@ window_create1(u_int sx, u_int sy)
        if (options_get_number(&w->options, "automatic-rename"))
                queue_window_name(w);
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if (ARRAY_ITEM(&windows, i) == NULL) {
-                       ARRAY_SET(&windows, i, w);
-                       break;
-               }
-       }
-       if (i == ARRAY_LENGTH(&windows))
-               ARRAY_ADD(&windows, w);
        w->references = 0;
 
+       w->id = next_window_id++;
+       RB_INSERT (windows, &windows, w);
+
        return (w);
 }
 
@@ -327,19 +323,9 @@ window_create(const char *name, int argc, char **argv, 
const char *path,
 void
 window_destroy(struct window *w)
 {
-       u_int   i;
-
        window_unzoom(w);
 
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if (w == ARRAY_ITEM(&windows, i))
-                       break;
-       }
-       if (i == ARRAY_LENGTH(&windows))
-               fatalx("index not found");
-       ARRAY_SET(&windows, i, NULL);
-       while (!ARRAY_EMPTY(&windows) && ARRAY_LAST(&windows) == NULL)
-               ARRAY_TRUNC(&windows, 1);
+       RB_REMOVE(windows, &windows, w);
 
        if (w->layout_root != NULL)
                layout_free(w);
@@ -1328,26 +1314,18 @@ window_pane_find_right(struct window_pane *wp)
 void
 winlink_clear_flags(struct winlink *wl)
 {
-       struct winlink  *wm;
        struct session  *s;
-       struct window   *w;
-       u_int            i;
-
-       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
-               if ((w = ARRAY_ITEM(&windows, i)) == NULL)
-                       continue;
-
-               RB_FOREACH(s, sessions, &sessions) {
-                       if ((wm = session_has(s, w)) == NULL)
-                               continue;
+       struct winlink  *wl_loop;
 
-                       if (wm->window != wl->window)
+       RB_FOREACH(s, sessions, &sessions) {
+               RB_FOREACH(wl_loop, winlinks, &s->windows) {
+                       if (wl_loop->window != wl->window)
                                continue;
-                       if ((wm->flags & WINLINK_ALERTFLAGS) == 0)
+                       if ((wl_loop->flags & WINLINK_ALERTFLAGS) == 0)
                                continue;
 
-                       wm->flags &= ~WINLINK_ALERTFLAGS;
-                       wm->window->flags &= ~WINDOW_ALERTFLAGS;
+                       wl_loop->flags &= ~WINLINK_ALERTFLAGS;
+                       wl_loop->window->flags &= ~WINDOW_ALERTFLAGS;
                        server_status_session(s);
                }
        }


commit 89e80cabd56bf2f7fa783575fe9b1f6192fade42
Author: nicm <nicm>
Commit: nicm <nicm>

    window_index is only used in one place (window_destroy) so inline it there.
---
 server.c |    1 +
 tmux.h   |    1 -
 window.c |   16 +++++-----------
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/server.c b/server.c
index c810177..bb96d9a 100644
--- a/server.c
+++ b/server.c
@@ -389,6 +389,7 @@ void
 server_signal_callback(int sig, unused short events, unused void *data)
 {
        int     fd;
+
        switch (sig) {
        case SIGTERM:
                server_shutdown = 1;
diff --git a/tmux.h b/tmux.h
index 53fd9b2..52dc152 100644
--- a/tmux.h
+++ b/tmux.h
@@ -2141,7 +2141,6 @@ struct winlink    *winlink_previous_by_number(struct 
winlink *, struct session *,
                     int);
 void            winlink_stack_push(struct winlink_stack *, struct winlink *);
 void            winlink_stack_remove(struct winlink_stack *, struct winlink *);
-int             window_index(struct window *, u_int *);
 struct window  *window_find_by_id(u_int);
 struct window  *window_create1(u_int, u_int);
 struct window  *window_create(const char *, int, char **, const char *,
diff --git a/window.c b/window.c
index 3c8d495..d8f2902 100644
--- a/window.c
+++ b/window.c
@@ -245,16 +245,6 @@ winlink_stack_remove(struct winlink_stack *stack, struct 
winlink *wl)
        }
 }
 
-int
-window_index(struct window *s, u_int *i)
-{
-       for (*i = 0; *i < ARRAY_LENGTH(&windows); (*i)++) {
-               if (s == ARRAY_ITEM(&windows, *i))
-                       return (0);
-       }
-       return (-1);
-}
-
 struct window *
 window_find_by_id(u_int id)
 {
@@ -341,7 +331,11 @@ window_destroy(struct window *w)
 
        window_unzoom(w);
 
-       if (window_index(w, &i) != 0)
+       for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
+               if (w == ARRAY_ITEM(&windows, i))
+                       break;
+       }
+       if (i == ARRAY_LENGTH(&windows))
                fatalx("index not found");
        ARRAY_SET(&windows, i, NULL);
        while (!ARRAY_EMPTY(&windows) && ARRAY_LAST(&windows) == NULL)


-----------------------------------------------------------------------

Summary of changes:
 client.c             |    6 ++--
 cmd-attach-session.c |    8 +---
 cmd-choose-client.c  |   24 +++++++-----
 cmd-detach-client.c  |   13 ++-----
 cmd-if-shell.c       |   15 ++++++--
 cmd-list-clients.c   |   15 ++++----
 cmd-run-shell.c      |   15 ++++++--
 cmd-set-option.c     |   52 ++++++++++++++++-----------
 cmd.c                |   26 +++++++------
 control-notify.c     |   28 ++++-----------
 grid.c               |    2 +-
 job.c                |    5 ++-
 notify.c             |    6 +--
 resize.c             |   14 +++----
 server-client.c      |   51 +++++----------------------
 server-fn.c          |   62 +++++++++-----------------------
 server-window.c      |   50 ++++++++++----------------
 server.c             |   95 ++++++++++++++++++--------------------------------
 session.c            |    6 ++--
 status.c             |    2 +-
 tmux.h               |   15 +++++---
 tty.c                |    6 +--
 window-copy.c        |    2 +-
 window.c             |   72 +++++++++++--------------------------
 24 files changed, 236 insertions(+), 354 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
tmux-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to