]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/strv.c
Merge pull request #7388 from keszybz/doc-tweak
[thirdparty/systemd.git] / src / basic / strv.c
CommitLineData
a7334b09
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
a7334b09 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
07630cea 20#include <errno.h>
11c3a366 21#include <fnmatch.h>
60918275 22#include <stdarg.h>
11c3a366 23#include <stdio.h>
07630cea 24#include <stdlib.h>
60918275
LP
25#include <string.h>
26
b5efdb8a 27#include "alloc-util.h"
4f5dd394 28#include "escape.h"
11c3a366 29#include "extract-word.h"
d390f8ef 30#include "fileio.h"
07630cea 31#include "string-util.h"
60918275 32#include "strv.h"
cf0fbc49 33#include "util.h"
60918275
LP
34
35char *strv_find(char **l, const char *name) {
5f9a22c3
LP
36 char **i;
37
60918275
LP
38 assert(name);
39
5f9a22c3
LP
40 STRV_FOREACH(i, l)
41 if (streq(*i, name))
42 return *i;
60918275
LP
43
44 return NULL;
45}
46
a4bfb399
LP
47char *strv_find_prefix(char **l, const char *name) {
48 char **i;
49
50 assert(name);
51
52 STRV_FOREACH(i, l)
53 if (startswith(*i, name))
54 return *i;
55
56 return NULL;
57}
58
28849dba
LP
59char *strv_find_startswith(char **l, const char *name) {
60 char **i, *e;
61
62 assert(name);
63
64 /* Like strv_find_prefix, but actually returns only the
65 * suffix, not the whole item */
66
67 STRV_FOREACH(i, l) {
68 e = startswith(*i, name);
69 if (e)
70 return e;
71 }
72
73 return NULL;
74}
75
dd9c7723 76void strv_clear(char **l) {
60918275
LP
77 char **k;
78
79 if (!l)
80 return;
81
82 for (k = l; *k; k++)
83 free(*k);
84
dd9c7723
TG
85 *l = NULL;
86}
87
33c2ce7b 88char **strv_free(char **l) {
dd9c7723 89 strv_clear(l);
6b430fdb 90 return mfree(l);
60918275
LP
91}
92
ab84f5b9
ZJS
93char **strv_free_erase(char **l) {
94 char **i;
95
96 STRV_FOREACH(i, l)
97 string_erase(*i);
98
99 return strv_free(l);
100}
101
2fd9ae2e 102char **strv_copy(char * const *l) {
60918275
LP
103 char **r, **k;
104
1fd8d04e
LP
105 k = r = new(char*, strv_length(l) + 1);
106 if (!r)
60918275
LP
107 return NULL;
108
ede27aab 109 if (l)
1fd8d04e
LP
110 for (; *l; k++, l++) {
111 *k = strdup(*l);
112 if (!*k) {
113 strv_free(r);
114 return NULL;
115 }
116 }
60918275
LP
117
118 *k = NULL;
119 return r;
60918275
LP
120}
121
2fd9ae2e 122unsigned strv_length(char * const *l) {
60918275
LP
123 unsigned n = 0;
124
125 if (!l)
126 return 0;
127
128 for (; *l; l++)
129 n++;
130
131 return n;
132}
133
257eca1a 134char **strv_new_ap(const char *x, va_list ap) {
60918275
LP
135 const char *s;
136 char **a;
137 unsigned n = 0, i = 0;
257eca1a
LP
138 va_list aq;
139
07719a21 140 /* As a special trick we ignore all listed strings that equal
f9d14060 141 * STRV_IGNORE. This is supposed to be used with the
07719a21
LP
142 * STRV_IFNOTNULL() macro to include possibly NULL strings in
143 * the string list. */
144
60918275 145 if (x) {
f9d14060 146 n = x == STRV_IGNORE ? 0 : 1;
60918275 147
257eca1a 148 va_copy(aq, ap);
07719a21 149 while ((s = va_arg(aq, const char*))) {
f9d14060 150 if (s == STRV_IGNORE)
07719a21
LP
151 continue;
152
60918275 153 n++;
07719a21
LP
154 }
155
257eca1a 156 va_end(aq);
60918275
LP
157 }
158
07719a21
LP
159 a = new(char*, n+1);
160 if (!a)
60918275
LP
161 return NULL;
162
163 if (x) {
f9d14060 164 if (x != STRV_IGNORE) {
07719a21
LP
165 a[i] = strdup(x);
166 if (!a[i])
167 goto fail;
168 i++;
60918275
LP
169 }
170
60918275 171 while ((s = va_arg(ap, const char*))) {
07719a21 172
f9d14060 173 if (s == STRV_IGNORE)
07719a21
LP
174 continue;
175
176 a[i] = strdup(s);
177 if (!a[i])
60918275
LP
178 goto fail;
179
180 i++;
181 }
60918275
LP
182 }
183
184 a[i] = NULL;
257eca1a 185
60918275
LP
186 return a;
187
188fail:
1fd8d04e 189 strv_free(a);
60918275
LP
190 return NULL;
191}
034c6ed7 192
257eca1a
LP
193char **strv_new(const char *x, ...) {
194 char **r;
195 va_list ap;
196
197 va_start(ap, x);
198 r = strv_new_ap(x, ap);
199 va_end(ap);
200
201 return r;
202}
203
e287086b
LP
204int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
205 char **s, **t;
206 size_t p, q, i = 0, j;
207
208 assert(a);
209
210 if (strv_isempty(b))
211 return 0;
212
213 p = strv_length(*a);
214 q = strv_length(b);
215
216 t = realloc(*a, sizeof(char*) * (p + q + 1));
217 if (!t)
218 return -ENOMEM;
219
220 t[p] = NULL;
221 *a = t;
07719a21 222
e3e45d4f 223 STRV_FOREACH(s, b) {
e287086b
LP
224
225 if (filter_duplicates && strv_contains(t, *s))
226 continue;
227
228 t[p+i] = strdup(*s);
229 if (!t[p+i])
230 goto rollback;
231
232 i++;
233 t[p+i] = NULL;
07719a21 234 }
034c6ed7 235
e287086b
LP
236 assert(i <= q);
237
238 return (int) i;
239
240rollback:
241 for (j = 0; j < i; j++)
242 free(t[p + j]);
243
244 t[p] = NULL;
245 return -ENOMEM;
5f9a22c3
LP
246}
247
e3e45d4f
SP
248int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
249 int r;
250 char **s;
5f9a22c3 251
e3e45d4f
SP
252 STRV_FOREACH(s, b) {
253 char *v;
5f9a22c3 254
e3e45d4f
SP
255 v = strappend(*s, suffix);
256 if (!v)
257 return -ENOMEM;
5f9a22c3 258
e3e45d4f
SP
259 r = strv_push(a, v);
260 if (r < 0) {
261 free(v);
262 return r;
8ea913b2 263 }
8ea913b2 264 }
5f9a22c3 265
e3e45d4f 266 return 0;
5f9a22c3
LP
267}
268
269char **strv_split(const char *s, const char *separator) {
a2a5291b 270 const char *word, *state;
5f9a22c3
LP
271 size_t l;
272 unsigned n, i;
273 char **r;
274
275 assert(s);
276
277 n = 0;
a2a5291b 278 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
5f9a22c3
LP
279 n++;
280
1fd8d04e
LP
281 r = new(char*, n+1);
282 if (!r)
5f9a22c3
LP
283 return NULL;
284
285 i = 0;
a2a5291b
ZJS
286 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
287 r[i] = strndup(word, l);
1fd8d04e 288 if (!r[i]) {
5f9a22c3
LP
289 strv_free(r);
290 return NULL;
291 }
292
1fd8d04e
LP
293 i++;
294 }
295
5f9a22c3
LP
296 r[i] = NULL;
297 return r;
298}
299
26d04f86
LP
300char **strv_split_newlines(const char *s) {
301 char **l;
302 unsigned n;
303
304 assert(s);
305
306 /* Special version of strv_split() that splits on newlines and
307 * suppresses an empty string at the end */
308
309 l = strv_split(s, NEWLINE);
310 if (!l)
311 return NULL;
312
313 n = strv_length(l);
314 if (n <= 0)
315 return l;
316
ece174c5 317 if (isempty(l[n - 1]))
a1e58e8e 318 l[n - 1] = mfree(l[n - 1]);
26d04f86
LP
319
320 return l;
321}
322
8adaf7bd 323int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
f88e6be5 324 _cleanup_strv_free_ char **l = NULL;
8dd4c05b 325 size_t n = 0, allocated = 0;
f88e6be5
LP
326 int r;
327
328 assert(t);
329 assert(s);
330
331 for (;;) {
332 _cleanup_free_ char *word = NULL;
333
8adaf7bd 334 r = extract_first_word(&s, &word, separators, flags);
f88e6be5
LP
335 if (r < 0)
336 return r;
ece174c5 337 if (r == 0)
f88e6be5
LP
338 break;
339
340 if (!GREEDY_REALLOC(l, allocated, n + 2))
341 return -ENOMEM;
342
343 l[n++] = word;
344 word = NULL;
345
346 l[n] = NULL;
347 }
348
8dd4c05b 349 if (!l) {
f88e6be5 350 l = new0(char*, 1);
8dd4c05b
LP
351 if (!l)
352 return -ENOMEM;
353 }
f88e6be5
LP
354
355 *t = l;
356 l = NULL;
357
8dd4c05b 358 return (int) n;
f88e6be5
LP
359}
360
5f9a22c3
LP
361char *strv_join(char **l, const char *separator) {
362 char *r, *e;
363 char **s;
364 size_t n, k;
365
366 if (!separator)
367 separator = " ";
368
369 k = strlen(separator);
370
371 n = 0;
372 STRV_FOREACH(s, l) {
afe773b0 373 if (s != l)
5f9a22c3
LP
374 n += k;
375 n += strlen(*s);
376 }
377
1fd8d04e
LP
378 r = new(char, n+1);
379 if (!r)
5f9a22c3
LP
380 return NULL;
381
382 e = r;
383 STRV_FOREACH(s, l) {
afe773b0 384 if (s != l)
5f9a22c3
LP
385 e = stpcpy(e, separator);
386
387 e = stpcpy(e, *s);
388 }
389
8d49745c
LP
390 *e = 0;
391
5f9a22c3
LP
392 return r;
393}
394
a6fde353
ZJS
395char *strv_join_quoted(char **l) {
396 char *buf = NULL;
397 char **s;
398 size_t allocated = 0, len = 0;
399
400 STRV_FOREACH(s, l) {
401 /* assuming here that escaped string cannot be more
402 * than twice as long, and reserving space for the
403 * separator and quotes.
404 */
405 _cleanup_free_ char *esc = NULL;
406 size_t needed;
407
408 if (!GREEDY_REALLOC(buf, allocated,
409 len + strlen(*s) * 2 + 3))
410 goto oom;
411
412 esc = cescape(*s);
413 if (!esc)
414 goto oom;
415
416 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
417 len > 0 ? " " : "", esc);
418 assert(needed < allocated - len);
419 len += needed;
420 }
421
422 if (!buf)
423 buf = malloc0(1);
424
425 return buf;
426
427 oom:
6b430fdb 428 return mfree(buf);
a6fde353
ZJS
429}
430
4468addc 431int strv_push(char ***l, char *value) {
5926ccca 432 char **c;
97569e15 433 unsigned n, m;
5926ccca
LP
434
435 if (!value)
436 return 0;
437
82dde599 438 n = strv_length(*l);
97569e15 439
98940a3c 440 /* Increase and check for overflow */
97569e15
LP
441 m = n + 2;
442 if (m < n)
443 return -ENOMEM;
444
14f27b4e 445 c = realloc_multiply(*l, sizeof(char*), m);
4468addc 446 if (!c)
82dde599 447 return -ENOMEM;
82dde599 448
4468addc 449 c[n] = value;
82dde599
LP
450 c[n+1] = NULL;
451
5926ccca
LP
452 *l = c;
453 return 0;
454}
455
98940a3c
LP
456int strv_push_pair(char ***l, char *a, char *b) {
457 char **c;
458 unsigned n, m;
459
460 if (!a && !b)
461 return 0;
462
463 n = strv_length(*l);
464
465 /* increase and check for overflow */
466 m = n + !!a + !!b + 1;
467 if (m < n)
468 return -ENOMEM;
469
470 c = realloc_multiply(*l, sizeof(char*), m);
471 if (!c)
472 return -ENOMEM;
473
474 if (a)
475 c[n++] = a;
476 if (b)
477 c[n++] = b;
478 c[n] = NULL;
479
480 *l = c;
481 return 0;
482}
483
9a00f57a
LP
484int strv_push_prepend(char ***l, char *value) {
485 char **c;
97569e15 486 unsigned n, m, i;
9a00f57a
LP
487
488 if (!value)
489 return 0;
490
491 n = strv_length(*l);
97569e15
LP
492
493 /* increase and check for overflow */
494 m = n + 2;
495 if (m < n)
496 return -ENOMEM;
497
498 c = new(char*, m);
9a00f57a
LP
499 if (!c)
500 return -ENOMEM;
501
502 for (i = 0; i < n; i++)
503 c[i+1] = (*l)[i];
504
505 c[0] = value;
506 c[n+1] = NULL;
507
508 free(*l);
509 *l = c;
510
511 return 0;
512}
513
6e18964d
ZJS
514int strv_consume(char ***l, char *value) {
515 int r;
516
517 r = strv_push(l, value);
518 if (r < 0)
519 free(value);
520
9a00f57a
LP
521 return r;
522}
523
98940a3c
LP
524int strv_consume_pair(char ***l, char *a, char *b) {
525 int r;
526
527 r = strv_push_pair(l, a, b);
528 if (r < 0) {
529 free(a);
530 free(b);
531 }
532
533 return r;
534}
535
9a00f57a
LP
536int strv_consume_prepend(char ***l, char *value) {
537 int r;
538
539 r = strv_push_prepend(l, value);
540 if (r < 0)
541 free(value);
542
6e18964d
ZJS
543 return r;
544}
545
4468addc
LP
546int strv_extend(char ***l, const char *value) {
547 char *v;
4468addc
LP
548
549 if (!value)
550 return 0;
551
552 v = strdup(value);
553 if (!v)
554 return -ENOMEM;
555
6e18964d 556 return strv_consume(l, v);
4468addc
LP
557}
558
4f4afc88
LP
559int strv_extend_front(char ***l, const char *value) {
560 size_t n, m;
561 char *v, **c;
562
563 assert(l);
564
565 /* Like strv_extend(), but prepends rather than appends the new entry */
566
bcab914f
LP
567 if (!value)
568 return 0;
569
4f4afc88
LP
570 n = strv_length(*l);
571
572 /* Increase and overflow check. */
573 m = n + 2;
574 if (m < n)
575 return -ENOMEM;
576
bcab914f
LP
577 v = strdup(value);
578 if (!v)
579 return -ENOMEM;
4f4afc88
LP
580
581 c = realloc_multiply(*l, sizeof(char*), m);
582 if (!c) {
583 free(v);
584 return -ENOMEM;
585 }
586
587 memmove(c+1, c, n * sizeof(char*));
588 c[0] = v;
589 c[n+1] = NULL;
590
591 *l = c;
592 return 0;
593}
594
5f9a22c3 595char **strv_uniq(char **l) {
cba8922f
LP
596 char **i;
597
5f9a22c3
LP
598 /* Drops duplicate entries. The first identical string will be
599 * kept, the others dropped */
600
cba8922f 601 STRV_FOREACH(i, l)
5f9a22c3
LP
602 strv_remove(i+1, *i);
603
604 return l;
605}
606
e1dd6790
LP
607bool strv_is_uniq(char **l) {
608 char **i;
609
610 STRV_FOREACH(i, l)
611 if (strv_find(i+1, *i))
612 return false;
613
614 return true;
615}
616
5f9a22c3
LP
617char **strv_remove(char **l, const char *s) {
618 char **f, **t;
619
620 if (!l)
621 return NULL;
622
5d6ab905
LP
623 assert(s);
624
625 /* Drops every occurrence of s in the string list, edits
626 * in-place. */
5f9a22c3 627
e3e45d4f
SP
628 for (f = t = l; *f; f++)
629 if (streq(*f, s))
71ecc858 630 free(*f);
e3e45d4f
SP
631 else
632 *(t++) = *f;
71ecc858
LP
633
634 *t = NULL;
635 return l;
636}
637
21bc923a 638char **strv_parse_nulstr(const char *s, size_t l) {
b60df13b
ZJS
639 /* l is the length of the input data, which will be split at NULs into
640 * elements of the resulting strv. Hence, the number of items in the resulting strv
641 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
642 * unless s[l-1] is NUL, in which case the final empty string is not stored in
643 * the resulting strv, and length is equal to the number of NUL bytes.
644 *
645 * Note that contrary to a normal nulstr which cannot contain empty strings, because
646 * the input data is terminated by any two consequent NUL bytes, this parser accepts
647 * empty strings in s.
648 */
649
21bc923a
LP
650 const char *p;
651 unsigned c = 0, i = 0;
652 char **v;
653
654 assert(s || l <= 0);
655
656 if (l <= 0)
49b832c5 657 return new0(char*, 1);
21bc923a
LP
658
659 for (p = s; p < s + l; p++)
660 if (*p == 0)
661 c++;
662
663 if (s[l-1] != 0)
664 c++;
665
1fd8d04e
LP
666 v = new0(char*, c+1);
667 if (!v)
21bc923a
LP
668 return NULL;
669
670 p = s;
671 while (p < s + l) {
672 const char *e;
673
674 e = memchr(p, 0, s + l - p);
675
1fd8d04e
LP
676 v[i] = strndup(p, e ? e - p : s + l - p);
677 if (!v[i]) {
21bc923a
LP
678 strv_free(v);
679 return NULL;
680 }
681
1fd8d04e
LP
682 i++;
683
21bc923a
LP
684 if (!e)
685 break;
686
687 p = e + 1;
688 }
689
690 assert(i == c);
691
692 return v;
693}
0c85a4f3 694
fabe5c0e
LP
695char **strv_split_nulstr(const char *s) {
696 const char *i;
697 char **r = NULL;
698
699 NULSTR_FOREACH(i, s)
700 if (strv_extend(&r, i) < 0) {
701 strv_free(r);
702 return NULL;
703 }
704
705 if (!r)
706 return strv_new(NULL, NULL);
707
708 return r;
709}
710
e287086b 711int strv_make_nulstr(char **l, char **p, size_t *q) {
b60df13b
ZJS
712 /* A valid nulstr with two NULs at the end will be created, but
713 * q will be the length without the two trailing NULs. Thus the output
714 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
715 * and can also be parsed by strv_parse_nulstr as long as the length
716 * is provided separately.
717 */
718
e287086b
LP
719 size_t n_allocated = 0, n = 0;
720 _cleanup_free_ char *m = NULL;
721 char **i;
722
723 assert(p);
724 assert(q);
725
726 STRV_FOREACH(i, l) {
727 size_t z;
728
729 z = strlen(*i);
730
b60df13b 731 if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
e287086b
LP
732 return -ENOMEM;
733
734 memcpy(m + n, *i, z + 1);
735 n += z + 1;
736 }
737
738 if (!m) {
739 m = new0(char, 1);
740 if (!m)
741 return -ENOMEM;
b60df13b
ZJS
742 n = 1;
743 } else
744 /* make sure there is a second extra NUL at the end of resulting nulstr */
745 m[n] = '\0';
e287086b 746
b60df13b 747 assert(n > 0);
e287086b 748 *p = m;
b60df13b 749 *q = n - 1;
e287086b
LP
750
751 m = NULL;
752
753 return 0;
754}
755
0c85a4f3 756bool strv_overlap(char **a, char **b) {
e3e45d4f 757 char **i;
0c85a4f3 758
e3e45d4f
SP
759 STRV_FOREACH(i, a)
760 if (strv_contains(b, *i))
761 return true;
0c85a4f3
LP
762
763 return false;
764}
857a493d
LP
765
766static int str_compare(const void *_a, const void *_b) {
767 const char **a = (const char**) _a, **b = (const char**) _b;
768
769 return strcmp(*a, *b);
770}
771
772char **strv_sort(char **l) {
f6d703c3 773 qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
857a493d
LP
774 return l;
775}
7c2d8094 776
0f84a72e 777bool strv_equal(char **a, char **b) {
e287086b
LP
778
779 if (strv_isempty(a))
780 return strv_isempty(b);
781
782 if (strv_isempty(b))
783 return false;
0f84a72e
DH
784
785 for ( ; *a || *b; ++a, ++b)
786 if (!streq_ptr(*a, *b))
787 return false;
788
789 return true;
790}
791
7c2d8094
TA
792void strv_print(char **l) {
793 char **s;
794
7c2d8094
TA
795 STRV_FOREACH(s, l)
796 puts(*s);
797}
4de33e7f
LP
798
799int strv_extendf(char ***l, const char *format, ...) {
800 va_list ap;
801 char *x;
802 int r;
803
804 va_start(ap, format);
805 r = vasprintf(&x, format, ap);
806 va_end(ap);
807
808 if (r < 0)
809 return -ENOMEM;
810
811 return strv_consume(l, x);
812}
e1dd6790
LP
813
814char **strv_reverse(char **l) {
815 unsigned n, i;
816
817 n = strv_length(l);
818 if (n <= 1)
819 return l;
820
fc549b96 821 for (i = 0; i < n / 2; i++)
8a3134b2 822 SWAP_TWO(l[i], l[n-1-i]);
e1dd6790
LP
823
824 return l;
825}
bceccd5e 826
04c14b25
RM
827char **strv_shell_escape(char **l, const char *bad) {
828 char **s;
829
830 /* Escapes every character in every string in l that is in bad,
831 * edits in-place, does not roll-back on error. */
832
833 STRV_FOREACH(s, l) {
834 char *v;
835
836 v = shell_escape(*s, bad);
837 if (!v)
838 return NULL;
839
840 free(*s);
841 *s = v;
842 }
843
844 return l;
845}
846
2404701e 847bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
bceccd5e
ZJS
848 char* const* p;
849
850 STRV_FOREACH(p, patterns)
2027927b 851 if (fnmatch(*p, s, flags) == 0)
bceccd5e
ZJS
852 return true;
853
854 return false;
855}
fe382237
LP
856
857char ***strv_free_free(char ***l) {
858 char ***i;
859
860 if (!l)
861 return NULL;
862
863 for (i = l; *i; i++)
864 strv_free(*i);
865
6b430fdb 866 return mfree(l);
fe382237 867}
e3ead6bb
LP
868
869char **strv_skip(char **l, size_t n) {
870
871 while (n > 0) {
872 if (strv_isempty(l))
873 return l;
874
875 l++, n--;
876 }
877
878 return l;
879}
8dd4c05b
LP
880
881int strv_extend_n(char ***l, const char *value, size_t n) {
882 size_t i, j, k;
883 char **nl;
884
885 assert(l);
886
887 if (!value)
888 return 0;
889 if (n == 0)
890 return 0;
891
61233823 892 /* Adds the value n times to l */
8dd4c05b
LP
893
894 k = strv_length(*l);
895
896 nl = realloc(*l, sizeof(char*) * (k + n + 1));
897 if (!nl)
898 return -ENOMEM;
899
900 *l = nl;
901
902 for (i = k; i < k + n; i++) {
903 nl[i] = strdup(value);
904 if (!nl[i])
905 goto rollback;
906 }
907
908 nl[i] = NULL;
909 return 0;
910
911rollback:
6fff8ac4 912 for (j = k; j < i; j++)
8dd4c05b
LP
913 free(nl[j]);
914
915 nl[k] = NULL;
5b700370 916 return -ENOMEM;
8dd4c05b 917}
3df9bec5
LP
918
919int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
920 bool b = false;
921 char **s;
922 int r;
923
924 /* Like fputs(), but for strv, and with a less stupid argument order */
925
3df9bec5
LP
926 if (!space)
927 space = &b;
928
929 STRV_FOREACH(s, l) {
d390f8ef 930 r = fputs_with_space(f, *s, separator, space);
3df9bec5
LP
931 if (r < 0)
932 return r;
3df9bec5
LP
933 }
934
935 return 0;
936}