Use TMPDIR if set, from Han Boetes.
[tmux-openbsd.git] / environ.c
blob4c4af98f303faf6ee0a1e2a2b0dc780a1e5ca358
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <stdlib.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Environment - manipulate a set of environment variables.
30 RB_GENERATE(environ, environ_entry, entry, environ_cmp);
32 int
33 environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
35 return (strcmp(envent1->name, envent2->name));
38 /* Initialise the environment. */
39 void
40 environ_init(struct environ *env)
42 RB_INIT(env);
45 /* Free an environment. */
46 void
47 environ_free(struct environ *env)
49 struct environ_entry *envent;
51 while (!RB_EMPTY(env)) {
52 envent = RB_ROOT(env);
53 RB_REMOVE(environ, env, envent);
54 xfree(envent->name);
55 if (envent->value != NULL)
56 xfree(envent->value);
57 xfree(envent);
61 /* Copy one environment into another. */
62 void
63 environ_copy(struct environ *srcenv, struct environ *dstenv)
65 struct environ_entry *envent;
67 RB_FOREACH(envent, environ, srcenv)
68 environ_set(dstenv, envent->name, envent->value);
71 /* Find an environment variable. */
72 struct environ_entry *
73 environ_find(struct environ *env, const char *name)
75 struct environ_entry envent;
77 envent.name = (char *) name;
78 return (RB_FIND(environ, env, &envent));
81 /* Set an environment variable. */
82 void
83 environ_set(struct environ *env, const char *name, const char *value)
85 struct environ_entry *envent;
87 if ((envent = environ_find(env, name)) != NULL) {
88 if (envent->value != NULL)
89 xfree(envent->value);
90 if (value != NULL)
91 envent->value = xstrdup(value);
92 else
93 envent->value = NULL;
94 } else {
95 envent = xmalloc(sizeof *envent);
96 envent->name = xstrdup(name);
97 if (value != NULL)
98 envent->value = xstrdup(value);
99 else
100 envent->value = NULL;
101 RB_INSERT(environ, env, envent);
105 /* Set an environment variable from a NAME=VALUE string. */
106 void
107 environ_put(struct environ *env, const char *var)
109 char *name, *value;
111 value = strchr(var, '=');
112 if (value == NULL)
113 return;
114 value++;
116 name = xstrdup(var);
117 name[strcspn(name, "=")] = '\0';
119 environ_set(env, name, value);
120 xfree(name);
123 /* Unset an environment variable. */
124 void
125 environ_unset(struct environ *env, const char *name)
127 struct environ_entry *envent;
129 if ((envent = environ_find(env, name)) == NULL)
130 return;
131 RB_REMOVE(environ, env, envent);
132 xfree(envent->name);
133 if (envent->value != NULL)
134 xfree(envent->value);
135 xfree(envent);
139 * Copy a space-separated list of variables from a destination into a source
140 * environment.
142 void
143 environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv)
145 struct environ_entry *envent;
146 char *copyvars, *var, *next;
148 copyvars = next = xstrdup(vars);
149 while ((var = strsep(&next, " ")) != NULL) {
150 if ((envent = environ_find(srcenv, var)) == NULL)
151 environ_set(dstenv, var, NULL);
152 else
153 environ_set(dstenv, envent->name, envent->value);
155 xfree(copyvars);
158 /* Push environment into the real environment - use after fork(). */
159 void
160 environ_push(struct environ *env)
162 ARRAY_DECL(, char *) varlist;
163 struct environ_entry *envent;
164 char **varp, *var;
165 u_int i;
167 ARRAY_INIT(&varlist);
168 for (varp = environ; *varp != NULL; varp++) {
169 var = xstrdup(*varp);
170 var[strcspn(var, "=")] = '\0';
171 ARRAY_ADD(&varlist, var);
173 for (i = 0; i < ARRAY_LENGTH(&varlist); i++)
174 unsetenv(ARRAY_ITEM(&varlist, i));
175 ARRAY_FREE(&varlist);
177 RB_FOREACH(envent, environ, env) {
178 if (envent->value != NULL)
179 setenv(envent->name, envent->value, 1);