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_new(char *, envlist
->el_count
+ 1);
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
;