diff options
-rw-r--r-- | client.c | 6 | ||||
-rw-r--r-- | cmd-attach-session.c | 8 | ||||
-rw-r--r-- | cmd-choose-client.c | 24 | ||||
-rw-r--r-- | cmd-detach-client.c | 13 | ||||
-rw-r--r-- | cmd-if-shell.c | 15 | ||||
-rw-r--r-- | cmd-list-clients.c | 15 | ||||
-rw-r--r-- | cmd-run-shell.c | 15 | ||||
-rw-r--r-- | cmd-set-option.c | 52 | ||||
-rw-r--r-- | cmd.c | 26 | ||||
-rw-r--r-- | control-notify.c | 28 | ||||
-rw-r--r-- | grid.c | 2 | ||||
-rw-r--r-- | job.c | 5 | ||||
-rw-r--r-- | notify.c | 6 | ||||
-rw-r--r-- | resize.c | 14 | ||||
-rw-r--r-- | server-client.c | 51 | ||||
-rw-r--r-- | server-fn.c | 62 | ||||
-rw-r--r-- | server-window.c | 50 | ||||
-rw-r--r-- | server.c | 95 | ||||
-rw-r--r-- | session.c | 6 | ||||
-rw-r--r-- | status.c | 2 | ||||
-rw-r--r-- | tmux.h | 15 | ||||
-rw-r--r-- | tty.c | 6 | ||||
-rw-r--r-- | window-copy.c | 2 | ||||
-rw-r--r-- | window.c | 72 |
24 files changed, 236 insertions, 354 deletions
@@ -258,6 +258,9 @@ client_main(int argc, char **argv, int flags) return (1); } + /* 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) { @@ -305,9 +308,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); diff --git a/cmd-attach-session.c b/cmd-attach-session.c index a67ec82c..79e14616 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 3002f7ba..49fe2a34 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 7f87d2c6..4bae9997 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-if-shell.c b/cmd-if-shell.c index cdd2135c..a307bd2f 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-list-clients.c b/cmd-list-clients.c index 893a6d05..372b5283 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-run-shell.c b/cmd-run-shell.c index 5d6d178b..134cbeba 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/cmd-set-option.c b/cmd-set-option.c index 01d691d5..83d31b93 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]; @@ -176,9 +175,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)) @@ -188,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); } @@ -291,9 +287,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; @@ -457,21 +459,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 (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); + 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)); @@ -115,10 +115,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 *); @@ -451,8 +453,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); @@ -464,9 +465,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); } @@ -477,12 +476,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; @@ -614,11 +618,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 747ef5b4..943d670c 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; @@ -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); @@ -40,7 +40,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; @@ -66,6 +66,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); @@ -135,7 +135,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 @@ -144,9 +143,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); } } @@ -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 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 (j = 0; j < ARRAY_LENGTH(&clients); j++) { - c = ARRAY_ITEM(&clients, j); - 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) @@ -92,9 +91,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"); @@ -105,7 +103,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-client.c b/server-client.c index 72edbdc8..f221a150 100644 --- a/server-client.c +++ b/server-client.c @@ -59,7 +59,6 @@ void server_client_create(int fd) { struct client *c; - u_int i; setblocking(fd, 0); @@ -107,13 +106,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); } @@ -147,10 +140,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); /* @@ -204,14 +194,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 */ @@ -262,16 +245,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) { /* @@ -701,13 +682,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); @@ -719,11 +695,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) { @@ -768,7 +740,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; @@ -796,12 +767,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 f2b2e269..043463fd 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; } } @@ -199,7 +179,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); } } @@ -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); } } @@ -268,7 +242,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) { @@ -433,16 +407,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 a2355701..4385dd90 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); + } } } } @@ -62,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) @@ -78,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) @@ -102,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; @@ -120,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); } @@ -138,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) @@ -171,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); } @@ -187,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); } } @@ -136,10 +136,10 @@ 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); + TAILQ_INIT(&clients); + TAILQ_INIT(&dead_clients); RB_INIT(&sessions); RB_INIT(&dead_sessions); TAILQ_INIT(&session_groups); @@ -167,7 +167,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++; @@ -213,16 +213,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); } @@ -231,10 +229,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); } @@ -243,55 +239,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); } } @@ -390,6 +373,7 @@ void server_signal_callback(int sig, unused short events, unused void *data) { int fd; + switch (sig) { case SIGTERM: server_shutdown = 1; @@ -438,14 +422,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 +450,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 +471,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); @@ -308,16 +308,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 * @@ -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); @@ -981,8 +981,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 { @@ -1345,8 +1347,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 { @@ -1609,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); @@ -2119,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 *); @@ -2139,7 +2145,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 *, @@ -2316,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); @@ -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; diff --git a/window-copy.c b/window-copy.c index eb00131e..7d5bae4c 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); @@ -63,6 +63,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 @@ -244,38 +252,21 @@ 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) { - 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; @@ -292,16 +283,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); } @@ -336,15 +322,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); - if (window_index(w, &i) != 0) - 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); @@ -1348,26 +1328,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); } } |