1 #include "qemu/osdep.h"
2 #include "qemu/queue.h"
3 #include "qemu/envlist.h"
6 const char *ev_var; /* actual env value */
7 QLIST_ENTRY(envlist_entry) ev_link;
11 QLIST_HEAD(, envlist_entry) el_entries; /* actual entries */
12 size_t el_count; /* number of entries */
15 static int envlist_parse(envlist_t *envlist,
16 const char *env, int (*)(envlist_t *, const char *));
19 * Allocates new envlist and returns pointer to it.
26 envlist = g_malloc(sizeof(*envlist));
28 QLIST_INIT(&envlist->el_entries);
29 envlist->el_count = 0;
35 * Releases given envlist and its entries.
38 envlist_free(envlist_t *envlist)
40 struct envlist_entry *entry;
42 assert(envlist != NULL);
44 while (envlist->el_entries.lh_first != NULL) {
45 entry = envlist->el_entries.lh_first;
46 QLIST_REMOVE(entry, ev_link);
48 g_free((char *)entry->ev_var);
55 * Parses comma separated list of set/modify environment
56 * variable entries and updates given enlist accordingly.
59 * envlist_parse(el, "HOME=foo,SHELL=/bin/sh");
61 * inserts/sets environment variables HOME and SHELL.
63 * Returns 0 on success, errno otherwise.
66 envlist_parse_set(envlist_t *envlist, const char *env)
68 return (envlist_parse(envlist, env, &envlist_setenv));
72 * Parses comma separated list of unset environment variable
73 * entries and removes given variables from given envlist.
75 * Returns 0 on success, errno otherwise.
78 envlist_parse_unset(envlist_t *envlist, const char *env)
80 return (envlist_parse(envlist, env, &envlist_unsetenv));
84 * Parses comma separated list of set, modify or unset entries
85 * and calls given callback for each entry.
87 * Returns 0 in case of success, errno otherwise.
90 envlist_parse(envlist_t *envlist, const char *env,
91 int (*callback)(envlist_t *, const char *))
93 char *tmpenv, *envvar;
96 assert(callback != NULL);
98 if ((envlist == NULL) || (env == NULL))
101 tmpenv = g_strdup(env);
105 envvar = strchr(tmpenv, ',');
106 if (envvar != NULL) {
109 if ((*callback)(envlist, tmpenv) != 0) {
114 } while (envvar != NULL);
121 * Sets environment value to envlist in similar manner
124 * Returns 0 in success, errno otherwise.
127 envlist_setenv(envlist_t *envlist, const char *env)
129 struct envlist_entry *entry = NULL;
133 if ((envlist == NULL) || (env == NULL))
136 /* find out first equals sign in given env */
137 if ((eq_sign = strchr(env, '=')) == NULL)
139 envname_len = eq_sign - env + 1;
142 * If there already exists variable with given name
143 * we remove and release it before allocating a whole
146 for (entry = envlist->el_entries.lh_first; entry != NULL;
147 entry = entry->ev_link.le_next) {
148 if (strncmp(entry->ev_var, env, envname_len) == 0)
153 QLIST_REMOVE(entry, ev_link);
154 g_free((char *)entry->ev_var);
160 entry = g_malloc(sizeof(*entry));
161 entry->ev_var = g_strdup(env);
162 QLIST_INSERT_HEAD(&envlist->el_entries, entry, ev_link);
168 * Removes given env value from envlist in similar manner
169 * than unsetenv(3). Returns 0 in success, errno otherwise.
172 envlist_unsetenv(envlist_t *envlist, const char *env)
174 struct envlist_entry *entry;
177 if ((envlist == NULL) || (env == NULL))
180 /* env is not allowed to contain '=' */
181 if (strchr(env, '=') != NULL)
185 * Find out the requested entry and remove
188 envname_len = strlen(env);
189 for (entry = envlist->el_entries.lh_first; entry != NULL;
190 entry = entry->ev_link.le_next) {
191 if (strncmp(entry->ev_var, env, envname_len) == 0)
195 QLIST_REMOVE(entry, ev_link);
196 g_free((char *)entry->ev_var);
205 * Returns given envlist as array of strings (in same form that
206 * global variable environ is). Caller must free returned memory
207 * by calling g_free for each element and the array.
208 * Returned array and given envlist are not related (no common
211 * If caller provides count pointer, number of items in array is
215 envlist_to_environ(const envlist_t *envlist, size_t *count)
217 struct envlist_entry *entry;
220 penv = env = g_malloc((envlist->el_count + 1) * sizeof(char *));
222 for (entry = envlist->el_entries.lh_first; entry != NULL;
223 entry = entry->ev_link.le_next) {
224 *(penv++) = g_strdup(entry->ev_var);
226 *penv = NULL; /* NULL terminate the list */
229 *count = envlist->el_count;