diff --git a/client.c b/client.c index 66bc0dab..83aa05ca 100644 --- a/client.c +++ b/client.c @@ -295,7 +295,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags) options_free(global_options); options_free(global_s_options); options_free(global_w_options); - environ_free(&global_environ); + environ_free(global_environ); /* Create stdin handler. */ setblocking(STDIN_FILENO, 0); diff --git a/cmd-attach-session.c b/cmd-attach-session.c index a3623ec4..c570358c 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -123,7 +123,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, if (!Eflag) { update = options_get_string(s->options, "update-environment"); - environ_update(update, &c->environ, &s->environ); + environ_update(update, c->environ, s->environ); } c->session = s; @@ -154,7 +154,7 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag, if (!Eflag) { update = options_get_string(s->options, "update-environment"); - environ_update(update, &c->environ, &s->environ); + environ_update(update, c->environ, s->environ); } c->session = s; diff --git a/cmd-find.c b/cmd-find.c index e1738faf..475753d4 100644 --- a/cmd-find.c +++ b/cmd-find.c @@ -120,7 +120,7 @@ cmd_find_try_TMUX(struct client *c, struct window *w) u_int session; struct session *s; - envent = environ_find(&c->environ, "TMUX"); + envent = environ_find(c->environ, "TMUX"); if (envent == NULL) return (NULL); diff --git a/cmd-new-session.c b/cmd-new-session.c index 48828e54..7b637bc6 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -60,7 +60,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) struct client *c = cmdq->client, *c0; struct session *s, *groupwith; struct window *w; - struct environ env; + struct environ *env; struct termios tio, *tiop; const char *newname, *target, *update, *errstr, *template; const char *path; @@ -223,30 +223,30 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq) path = NULL; if (c != NULL && c->session == NULL) - envent = environ_find(&c->environ, "PATH"); + envent = environ_find(c->environ, "PATH"); else - envent = environ_find(&global_environ, "PATH"); + envent = environ_find(global_environ, "PATH"); if (envent != NULL) path = envent->value; /* Construct the environment. */ - environ_init(&env); + env = environ_create(); if (c != NULL && !args_has(args, 'E')) { update = options_get_string(global_s_options, "update-environment"); - environ_update(update, &c->environ, &env); + environ_update(update, c->environ, env); } /* Create the new session. */ idx = -1 - options_get_number(global_s_options, "base-index"); - s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx, + s = session_create(newname, argc, argv, path, cwd, env, tiop, idx, sx, sy, &cause); + environ_free(env); if (s == NULL) { cmdq_error(cmdq, "create session failed: %s", cause); free(cause); goto error; } - environ_free(&env); /* Set the initial window name if one given. */ if (argc >= 0 && args_has(args, 'n')) { diff --git a/cmd-new-window.c b/cmd-new-window.c index a3712d76..70e70c68 100644 --- a/cmd-new-window.c +++ b/cmd-new-window.c @@ -86,9 +86,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq) path = NULL; if (cmdq->client != NULL && cmdq->client->session == NULL) - envent = environ_find(&cmdq->client->environ, "PATH"); + envent = environ_find(cmdq->client->environ, "PATH"); else - envent = environ_find(&s->environ, "PATH"); + envent = environ_find(s->environ, "PATH"); if (envent != NULL) path = envent->value; diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c index 6575e8e4..864b45b8 100644 --- a/cmd-respawn-pane.c +++ b/cmd-respawn-pane.c @@ -46,7 +46,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) struct window *w; struct window_pane *wp; struct session *s; - struct environ env; + struct environ *env; const char *path; char *cause; u_int idx; @@ -64,10 +64,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } - environ_init(&env); - environ_copy(&global_environ, &env); - environ_copy(&s->environ, &env); - server_fill_environ(s, &env); + env = environ_create(); + environ_copy(global_environ, env); + environ_copy(s->environ, env); + server_fill_environ(s, env); window_pane_reset_mode(wp); screen_reinit(&wp->base); @@ -75,22 +75,22 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) path = NULL; if (cmdq->client != NULL && cmdq->client->session == NULL) - envent = environ_find(&cmdq->client->environ, "PATH"); + envent = environ_find(cmdq->client->environ, "PATH"); else - envent = environ_find(&s->environ, "PATH"); + envent = environ_find(s->environ, "PATH"); if (envent != NULL) path = envent->value; - if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env, + if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, env, s->tio, &cause) != 0) { cmdq_error(cmdq, "respawn pane failed: %s", cause); free(cause); - environ_free(&env); + environ_free(env); return (CMD_RETURN_ERROR); } wp->flags |= PANE_REDRAW; server_status_window(w); - environ_free(&env); + environ_free(env); return (CMD_RETURN_NORMAL); } diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c index 06102ed0..8d8332b1 100644 --- a/cmd-respawn-window.c +++ b/cmd-respawn-window.c @@ -45,7 +45,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) struct window *w; struct window_pane *wp; struct session *s; - struct environ env; + struct environ *env; const char *path; char *cause; struct environ_entry *envent; @@ -64,10 +64,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) } } - environ_init(&env); - environ_copy(&global_environ, &env); - environ_copy(&s->environ, &env); - server_fill_environ(s, &env); + env = environ_create(); + environ_copy(global_environ, env); + environ_copy(s->environ, env); + server_fill_environ(s, env); wp = TAILQ_FIRST(&w->panes); TAILQ_REMOVE(&w->panes, wp, entry); @@ -78,17 +78,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) path = NULL; if (cmdq->client != NULL && cmdq->client->session == NULL) - envent = environ_find(&cmdq->client->environ, "PATH"); + envent = environ_find(cmdq->client->environ, "PATH"); else - envent = environ_find(&s->environ, "PATH"); + envent = environ_find(s->environ, "PATH"); if (envent != NULL) path = envent->value; - if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env, + if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, env, s->tio, &cause) != 0) { cmdq_error(cmdq, "respawn window failed: %s", cause); free(cause); - environ_free(&env); + environ_free(env); server_destroy_pane(wp); return (CMD_RETURN_ERROR); } @@ -101,6 +101,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) recalculate_sizes(); server_redraw_window(w); - environ_free(&env); + environ_free(env); return (CMD_RETURN_NORMAL); } diff --git a/cmd-set-environment.c b/cmd-set-environment.c index 83e63b48..864e1d9b 100644 --- a/cmd-set-environment.c +++ b/cmd-set-environment.c @@ -61,11 +61,11 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) value = args->argv[1]; if (args_has(self->args, 'g')) - env = &global_environ; + env = global_environ; else { if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) return (CMD_RETURN_ERROR); - env = &s->environ; + env = s->environ; } if (args_has(self->args, 'u')) { diff --git a/cmd-show-environment.c b/cmd-show-environment.c index af24d91b..96cfa289 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -91,12 +91,12 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) struct environ_entry *envent; if (args_has(self->args, 'g')) - env = &global_environ; + env = global_environ; else { s = cmd_find_session(cmdq, args_get(args, 't'), 0); if (s == NULL) return (CMD_RETURN_ERROR); - env = &s->environ; + env = s->environ; } if (args->argc != 0) { @@ -109,7 +109,10 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); } - RB_FOREACH(envent, environ, env) + envent = environ_first(env); + while (envent != NULL) { cmd_show_environment_print(self, cmdq, envent); + envent = environ_next(envent); + } return (CMD_RETURN_NORMAL); } diff --git a/cmd-split-window.c b/cmd-split-window.c index 026f951f..ec37e0d7 100644 --- a/cmd-split-window.c +++ b/cmd-split-window.c @@ -51,7 +51,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) struct winlink *wl; struct window *w; struct window_pane *wp, *new_wp = NULL; - struct environ env; + struct environ *env; const char *cmd, *path, *shell, *template; char **argv, *cause, *new_cause, *cp; u_int hlimit; @@ -66,10 +66,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) w = wl->window; server_unzoom_window(w); - environ_init(&env); - environ_copy(&global_environ, &env); - environ_copy(&s->environ, &env); - server_fill_environ(s, &env); + env = environ_create(); + environ_copy(global_environ, env); + environ_copy(s->environ, env); + server_fill_environ(s, env); if (args->argc == 0) { cmd = options_get_string(s->options, "default-command"); @@ -150,13 +150,13 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) path = NULL; if (cmdq->client != NULL && cmdq->client->session == NULL) - envent = environ_find(&cmdq->client->environ, "PATH"); + envent = environ_find(cmdq->client->environ, "PATH"); else - envent = environ_find(&s->environ, "PATH"); + envent = environ_find(s->environ, "PATH"); if (envent != NULL) path = envent->value; - if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env, + if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, env, s->tio, &cause) != 0) goto error; @@ -169,7 +169,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) } else server_status_session(s); - environ_free(&env); + environ_free(env); if (args_has(args, 'P')) { if ((template = args_get(args, 'F')) == NULL) @@ -192,7 +192,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); error: - environ_free(&env); + environ_free(env); if (new_wp != NULL) { layout_close_pane(new_wp); window_remove_pane(w, new_wp); diff --git a/cmd-string.c b/cmd-string.c index db1723cb..51554800 100644 --- a/cmd-string.c +++ b/cmd-string.c @@ -126,7 +126,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file, whitespace = argv[0] + strcspn(argv[0], " \t"); if (equals == NULL || equals > whitespace) break; - environ_put(&global_environ, argv[0]); + environ_put(global_environ, argv[0]); argc--; memmove(argv, argv + 1, argc * (sizeof *argv)); } @@ -303,7 +303,7 @@ cmd_string_variable(const char *s, size_t *p) buf = xrealloc(buf, len + 1); buf[len] = '\0'; - envent = environ_find(&global_environ, buf); + envent = environ_find(global_environ, buf); free(buf); if (envent == NULL) return (xstrdup("")); @@ -326,7 +326,7 @@ cmd_string_expand_tilde(const char *s, size_t *p) last = cmd_string_getc(s, p); if (last == EOF || last == '/' || last == ' '|| last == '\t') { - envent = environ_find(&global_environ, "HOME"); + envent = environ_find(global_environ, "HOME"); if (envent != NULL && *envent->value != '\0') home = envent->value; else if ((pw = getpwuid(getuid())) != NULL) diff --git a/cmd-switch-client.c b/cmd-switch-client.c index 5a8c8b08..dbdc5b63 100644 --- a/cmd-switch-client.c +++ b/cmd-switch-client.c @@ -121,7 +121,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq) if (c != NULL && !args_has(args, 'E')) { update = options_get_string(s->options, "update-environment"); - environ_update(update, &c->environ, &s->environ); + environ_update(update, c->environ, s->environ); } if (c->session != NULL && c->session != s) diff --git a/environ.c b/environ.c index 11b8c849..43a9ce01 100644 --- a/environ.c +++ b/environ.c @@ -27,6 +27,9 @@ * Environment - manipulate a set of environment variables. */ +RB_HEAD(environ, environ_entry); +int environ_cmp(struct environ_entry *, struct environ_entry *); +RB_PROTOTYPE(environ, environ_entry, entry, environ_cmp); RB_GENERATE(environ, environ_entry, entry, environ_cmp); int @@ -36,25 +39,42 @@ environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2) } /* Initialise the environment. */ -void -environ_init(struct environ *env) +struct environ * +environ_create(void) { + struct environ *env; + + env = xcalloc(1, sizeof *env); RB_INIT(env); + + return (env); } /* Free an environment. */ void environ_free(struct environ *env) { - struct environ_entry *envent; + struct environ_entry *envent, *envent1; - while (!RB_EMPTY(env)) { - envent = RB_ROOT(env); + RB_FOREACH_SAFE(envent, environ, env, envent1) { RB_REMOVE(environ, env, envent); free(envent->name); free(envent->value); free(envent); } + free(env); +} + +struct environ_entry * +environ_first(struct environ *env) +{ + return (RB_MIN(environ, env)); +} + +struct environ_entry * +environ_next(struct environ_entry *envent) +{ + return (RB_NEXT(environ, env, envent)); } /* Copy one environment into another. */ diff --git a/format.c b/format.c index 15b5b82d..3c0f4a39 100644 --- a/format.c +++ b/format.c @@ -648,9 +648,9 @@ format_find(struct format_tree *ft, const char *key, int modifiers) if (~modifiers & FORMAT_TIMESTRING) { envent = NULL; if (ft->s != NULL) - envent = environ_find(&ft->s->environ, key); + envent = environ_find(ft->s->environ, key); if (envent == NULL) - envent = environ_find(&global_environ, key); + envent = environ_find(global_environ, key); if (envent != NULL) { found = envent->value; goto found; diff --git a/job.c b/job.c index dc11c4c8..47274db1 100644 --- a/job.c +++ b/job.c @@ -44,22 +44,22 @@ job_run(const char *cmd, struct session *s, int cwd, void (*callbackfn)(struct job *), void (*freefn)(void *), void *data) { struct job *job; - struct environ env; + struct environ *env; pid_t pid; int nullfd, out[2]; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0) return (NULL); - environ_init(&env); - environ_copy(&global_environ, &env); + env = environ_create(); + environ_copy(global_environ, env); if (s != NULL) - environ_copy(&s->environ, &env); - server_fill_environ(s, &env); + environ_copy(s->environ, env); + server_fill_environ(s, env); switch (pid = fork()) { case -1: - environ_free(&env); + environ_free(env); close(out[0]); close(out[1]); return (NULL); @@ -69,8 +69,8 @@ job_run(const char *cmd, struct session *s, int cwd, if (cwd != -1 && fchdir(cwd) != 0) chdir("/"); - environ_push(&env); - environ_free(&env); + environ_push(env); + environ_free(env); if (dup2(out[1], STDIN_FILENO) == -1) fatal("dup2 failed"); @@ -95,7 +95,7 @@ job_run(const char *cmd, struct session *s, int cwd, } /* parent */ - environ_free(&env); + environ_free(env); close(out[1]); job = xmalloc(sizeof *job); diff --git a/server-client.c b/server-client.c index 924bcc04..bf18cae7 100644 --- a/server-client.c +++ b/server-client.c @@ -57,7 +57,7 @@ server_client_check_nested(struct client *c) if (c->tty.path == NULL) return (0); - envent = environ_find(&c->environ, "TMUX"); + envent = environ_find(c->environ, "TMUX"); if (envent == NULL || *envent->value == '\0') return (0); @@ -93,7 +93,7 @@ server_client_create(int fd) fatal("gettimeofday failed"); memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); - environ_init(&c->environ); + c->environ = environ_create(); c->fd = -1; c->cwd = -1; @@ -217,7 +217,7 @@ server_client_lost(struct client *c) cmdq_free(c->cmdq); c->cmdq = NULL; - environ_free(&c->environ); + environ_free(c->environ); proc_remove_peer(c->peer); c->peer = NULL; @@ -1154,7 +1154,7 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) if (datalen == 0 || data[datalen - 1] != '\0') fatalx("bad MSG_IDENTIFY_ENVIRON string"); if (strchr(data, '=') != NULL) - environ_put(&c->environ, data); + environ_put(c->environ, data); log_debug("client %p IDENTIFY_ENVIRON %s", c, data); break; case MSG_IDENTIFY_CLIENTPID: diff --git a/session.c b/session.c index 50af8a04..9f086bbd 100644 --- a/session.c +++ b/session.c @@ -119,9 +119,9 @@ session_create(const char *name, int argc, char **argv, const char *path, TAILQ_INIT(&s->lastw); RB_INIT(&s->windows); - environ_init(&s->environ); + s->environ = environ_create(); if (env != NULL) - environ_copy(env, &s->environ); + environ_copy(env, s->environ); s->options = options_create(global_s_options); s->tio = NULL; @@ -189,7 +189,7 @@ session_free(unused int fd, unused short events, void *arg) log_debug("session %s freed (%d references)", s->name, s->references); if (s->references == 0) { - environ_free(&s->environ); + environ_free(s->environ); options_free(s->options); free(s->name); @@ -318,7 +318,7 @@ session_new(struct session *s, const char *name, int argc, char **argv, { struct window *w; struct winlink *wl; - struct environ env; + struct environ *env; const char *shell; u_int hlimit; @@ -327,26 +327,26 @@ session_new(struct session *s, const char *name, int argc, char **argv, return (NULL); } - environ_init(&env); - environ_copy(&global_environ, &env); - environ_copy(&s->environ, &env); - server_fill_environ(s, &env); + env = environ_create(); + environ_copy(global_environ, env); + environ_copy(s->environ, env); + server_fill_environ(s, env); shell = options_get_string(s->options, "default-shell"); if (*shell == '\0' || areshell(shell)) shell = _PATH_BSHELL; hlimit = options_get_number(s->options, "history-limit"); - w = window_create(name, argc, argv, path, shell, cwd, &env, s->tio, + w = window_create(name, argc, argv, path, shell, cwd, env, s->tio, s->sx, s->sy, hlimit, cause); if (w == NULL) { winlink_remove(&s->windows, wl); - environ_free(&env); + environ_free(env); return (NULL); } winlink_set_window(wl, w); notify_window_linked(s, w); - environ_free(&env); + environ_free(env); if (options_get_number(s->options, "set-remain-on-exit")) options_set_number(w->options, "remain-on-exit", 1); diff --git a/tmux.c b/tmux.c index 843f439f..c79a01bd 100644 --- a/tmux.c +++ b/tmux.c @@ -39,7 +39,7 @@ extern char *malloc_options; struct options *global_options; /* server options */ struct options *global_s_options; /* session options */ struct options *global_w_options; /* window options */ -struct environ global_environ; +struct environ *global_environ; char *shell_cmd; int debug_level; @@ -282,11 +282,11 @@ main(int argc, char **argv) flags |= CLIENT_UTF8; } - environ_init(&global_environ); + global_environ = environ_create(); for (var = environ; *var != NULL; var++) - environ_put(&global_environ, *var); + environ_put(global_environ, *var); if (getcwd(tmp, sizeof tmp) != NULL) - environ_set(&global_environ, "PWD", tmp); + environ_set(global_environ, "PWD", tmp); global_options = options_create(NULL); options_table_populate_tree(server_options_table, global_options); diff --git a/tmux.h b/tmux.h index a4921298..0fd8062e 100644 --- a/tmux.h +++ b/tmux.h @@ -39,6 +39,15 @@ extern char *__progname; extern char **environ; +struct client; +struct environ; +struct input_ctx; +struct mouse_event; +struct options; +struct session; +struct tmuxpeer; +struct tmuxproc; + /* Default global configuration file. */ #define TMUX_CONF "/etc/tmux.conf" @@ -765,9 +774,6 @@ struct screen_write_ctx { * Window mode. Windows can be in several modes and this is used to call the * right function to handle input and output. */ -struct client; -struct session; -struct mouse_event; struct window_mode { struct screen *(*init)(struct window_pane *); void (*free)(struct window_pane *); @@ -799,7 +805,6 @@ struct window_choose_data { }; /* Child window structure. */ -struct input_ctx; struct window_pane { u_int id; u_int active_point; @@ -864,7 +869,6 @@ TAILQ_HEAD(window_panes, window_pane); RB_HEAD(window_pane_tree, window_pane); /* Window structure. */ -struct options; struct window { u_int id; @@ -962,7 +966,6 @@ struct environ_entry { RB_ENTRY(environ_entry) entry; }; -RB_HEAD(environ, environ_entry); /* Client session. */ struct session_group { @@ -1001,7 +1004,7 @@ struct session { struct termios *tio; - struct environ environ; + struct environ *environ; int references; @@ -1167,8 +1170,6 @@ struct message_entry { }; /* Client connection. */ -struct tmuxproc; -struct tmuxpeer; struct client { struct tmuxpeer *peer; @@ -1180,7 +1181,7 @@ struct client { struct timeval creation_time; struct timeval activity_time; - struct environ environ; + struct environ *environ; char *title; int cwd; @@ -1407,7 +1408,7 @@ struct options_table_entry { extern struct options *global_options; extern struct options *global_s_options; extern struct options *global_w_options; -extern struct environ global_environ; +extern struct environ *global_environ; extern char *shell_cmd; extern int debug_level; extern time_t start_time; @@ -1544,10 +1545,10 @@ void job_free(struct job *); void job_died(struct job *, int); /* environ.c */ -int environ_cmp(struct environ_entry *, struct environ_entry *); -RB_PROTOTYPE(environ, environ_entry, entry, environ_cmp); -void environ_init(struct environ *); +struct environ *environ_create(void); void environ_free(struct environ *); +struct environ_entry *environ_first(struct environ *); +struct environ_entry *environ_next(struct environ_entry *); void environ_copy(struct environ *, struct environ *); struct environ_entry *environ_find(struct environ *, const char *); void environ_set(struct environ *, const char *, const char *);