chiark / gitweb /
sd-login: build test code again
[elogind.git] / src / strv.c
index b1643b357fbddf9f69eb09d4ae2c8cde67b7dd5d..f15aa8736a0339a241245f01c71845f93d24d7a5 100644 (file)
@@ -67,20 +67,23 @@ void strv_free(char **l) {
 char **strv_copy(char **l) {
         char **r, **k;
 
-        if (!(r = new(char*, strv_length(l)+1)))
+        if (!(k = r = new(char*, strv_length(l)+1)))
                 return NULL;
 
-        for (k = r; *l; k++, l++)
-                if (!(*k = strdup(*l)))
-                        goto fail;
+        if (l)
+                for (; *l; k++, l++)
+                        if (!(*k = strdup(*l)))
+                                goto fail;
 
         *k = NULL;
         return r;
 
 fail:
-        for (k--, l--; k >= r; k--, l--)
+        for (k--; k >= r; k--)
                 free(*k);
 
+        free(r);
+
         return NULL;
 }
 
@@ -355,7 +358,10 @@ char **strv_remove(char **l, const char *s) {
         if (!l)
                 return NULL;
 
-        /* Drops every occurence of s in the string list */
+        assert(s);
+
+        /* Drops every occurrence of s in the string list, edits
+         * in-place. */
 
         for (f = t = l; *f; f++) {
 
@@ -379,12 +385,17 @@ static int env_append(char **r, char ***k, char **a) {
                 return 0;
 
         /* Add the entries of a to *k unless they already exist in *r
-         * in which case they are overriden instead. This assumes
+         * in which case they are overridden instead. This assumes
          * there is enough space in the r array. */
 
         for (; *a; a++) {
                 char **j;
-                size_t n = strcspn(*a, "=") + 1;
+                size_t n;
+
+                n = strcspn(*a, "=");
+
+                if ((*a)[n] == '=')
+                        n++;
 
                 for (j = r; j < *k; j++)
                         if (strncmp(*j, *a, n) == 0)
@@ -435,6 +446,8 @@ char **strv_env_merge(unsigned n_lists, ...) {
         return r;
 
 fail:
+        va_end(ap);
+
         for (k--; k >= r; k--)
                 free(*k);
 
@@ -474,7 +487,7 @@ char **strv_env_delete(char **x, unsigned n_lists, ...) {
         char **l, **k, **r, **j;
         va_list ap;
 
-        /* Deletes every entry fromx that is mentioned in the other
+        /* Deletes every entry from x that is mentioned in the other
          * string lists */
 
         n = strv_length(x);
@@ -512,9 +525,38 @@ char **strv_env_delete(char **x, unsigned n_lists, ...) {
         return r;
 }
 
+char **strv_env_unset(char **l, const char *p) {
+
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        assert(p);
+
+        /* Drops every occurrence of the env var setting p in the
+         * string list. edits in-place. */
+
+        for (f = t = l; *f; f++) {
+
+                if (env_match(*f, p)) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
 char **strv_env_set(char **x, const char *p) {
 
         char **k, **r;
+        char* m[2] = { (char*) p, NULL };
+
+        /* Overrides the env var setting of p, returns a new copy */
 
         if (!(r = new(char*, strv_length(x)+2)))
                 return NULL;
@@ -523,7 +565,7 @@ char **strv_env_set(char **x, const char *p) {
         if (env_append(r, &k, x) < 0)
                 goto fail;
 
-        if (!(*(k++) = strdup(p)))
+        if (env_append(r, &k, m) < 0)
                 goto fail;
 
         *k = NULL;