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