]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fileio.c
coccinelle: make use of SYNTHETIC_ERRNO
[thirdparty/systemd.git] / src / basic / fileio.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <limits.h>
6 #include <stdarg.h>
7 #include <stdint.h>
8 #include <stdio_ext.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/mman.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 #include "alloc-util.h"
17 #include "ctype.h"
18 #include "env-util.h"
19 #include "escape.h"
20 #include "fd-util.h"
21 #include "fileio.h"
22 #include "fs-util.h"
23 #include "hexdecoct.h"
24 #include "log.h"
25 #include "macro.h"
26 #include "missing.h"
27 #include "parse-util.h"
28 #include "path-util.h"
29 #include "process-util.h"
30 #include "random-util.h"
31 #include "stdio-util.h"
32 #include "string-util.h"
33 #include "strv.h"
34 #include "time-util.h"
35 #include "umask-util.h"
36 #include "utf8.h"
37
38 #define READ_FULL_BYTES_MAX (4U*1024U*1024U)
39
40 int write_string_stream_ts(
41 FILE *f,
42 const char *line,
43 WriteStringFileFlags flags,
44 struct timespec *ts) {
45
46 bool needs_nl;
47 int r;
48
49 assert(f);
50 assert(line);
51
52 if (ferror(f))
53 return -EIO;
54
55 needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
56
57 if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
58 /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
59 * that the write goes out in one go, instead of two */
60
61 line = strjoina(line, "\n");
62 needs_nl = false;
63 }
64
65 if (fputs(line, f) == EOF)
66 return -errno;
67
68 if (needs_nl)
69 if (fputc('\n', f) == EOF)
70 return -errno;
71
72 if (flags & WRITE_STRING_FILE_SYNC)
73 r = fflush_sync_and_check(f);
74 else
75 r = fflush_and_check(f);
76 if (r < 0)
77 return r;
78
79 if (ts) {
80 struct timespec twice[2] = {*ts, *ts};
81
82 if (futimens(fileno(f), twice) < 0)
83 return -errno;
84 }
85
86 return 0;
87 }
88
89 static int write_string_file_atomic(
90 const char *fn,
91 const char *line,
92 WriteStringFileFlags flags,
93 struct timespec *ts) {
94
95 _cleanup_fclose_ FILE *f = NULL;
96 _cleanup_free_ char *p = NULL;
97 int r;
98
99 assert(fn);
100 assert(line);
101
102 r = fopen_temporary(fn, &f, &p);
103 if (r < 0)
104 return r;
105
106 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
107 (void) fchmod_umask(fileno(f), 0644);
108
109 r = write_string_stream_ts(f, line, flags, ts);
110 if (r < 0)
111 goto fail;
112
113 if (rename(p, fn) < 0) {
114 r = -errno;
115 goto fail;
116 }
117
118 return 0;
119
120 fail:
121 (void) unlink(p);
122 return r;
123 }
124
125 int write_string_file_ts(
126 const char *fn,
127 const char *line,
128 WriteStringFileFlags flags,
129 struct timespec *ts) {
130
131 _cleanup_fclose_ FILE *f = NULL;
132 int q, r;
133
134 assert(fn);
135 assert(line);
136
137 /* We don't know how to verify whether the file contents was already on-disk. */
138 assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC)));
139
140 if (flags & WRITE_STRING_FILE_ATOMIC) {
141 assert(flags & WRITE_STRING_FILE_CREATE);
142
143 r = write_string_file_atomic(fn, line, flags, ts);
144 if (r < 0)
145 goto fail;
146
147 return r;
148 } else
149 assert(!ts);
150
151 if (flags & WRITE_STRING_FILE_CREATE) {
152 f = fopen(fn, "we");
153 if (!f) {
154 r = -errno;
155 goto fail;
156 }
157 } else {
158 int fd;
159
160 /* We manually build our own version of fopen(..., "we") that
161 * works without O_CREAT */
162 fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY | ((flags & WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0));
163 if (fd < 0) {
164 r = -errno;
165 goto fail;
166 }
167
168 f = fdopen(fd, "we");
169 if (!f) {
170 r = -errno;
171 safe_close(fd);
172 goto fail;
173 }
174 }
175
176 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
177
178 if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
179 setvbuf(f, NULL, _IONBF, 0);
180
181 r = write_string_stream_ts(f, line, flags, ts);
182 if (r < 0)
183 goto fail;
184
185 return 0;
186
187 fail:
188 if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
189 return r;
190
191 f = safe_fclose(f);
192
193 /* OK, the operation failed, but let's see if the right
194 * contents in place already. If so, eat up the error. */
195
196 q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
197 if (q <= 0)
198 return r;
199
200 return 0;
201 }
202
203 int write_string_filef(
204 const char *fn,
205 WriteStringFileFlags flags,
206 const char *format, ...) {
207
208 _cleanup_free_ char *p = NULL;
209 va_list ap;
210 int r;
211
212 va_start(ap, format);
213 r = vasprintf(&p, format, ap);
214 va_end(ap);
215
216 if (r < 0)
217 return -ENOMEM;
218
219 return write_string_file(fn, p, flags);
220 }
221
222 int read_one_line_file(const char *fn, char **line) {
223 _cleanup_fclose_ FILE *f = NULL;
224 int r;
225
226 assert(fn);
227 assert(line);
228
229 f = fopen(fn, "re");
230 if (!f)
231 return -errno;
232
233 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
234
235 r = read_line(f, LONG_LINE_MAX, line);
236 return r < 0 ? r : 0;
237 }
238
239 int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
240 _cleanup_fclose_ FILE *f = NULL;
241 _cleanup_free_ char *buf = NULL;
242 size_t l, k;
243
244 assert(fn);
245 assert(blob);
246
247 l = strlen(blob);
248
249 if (accept_extra_nl && endswith(blob, "\n"))
250 accept_extra_nl = false;
251
252 buf = malloc(l + accept_extra_nl + 1);
253 if (!buf)
254 return -ENOMEM;
255
256 f = fopen(fn, "re");
257 if (!f)
258 return -errno;
259
260 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
261
262 /* We try to read one byte more than we need, so that we know whether we hit eof */
263 errno = 0;
264 k = fread(buf, 1, l + accept_extra_nl + 1, f);
265 if (ferror(f))
266 return errno > 0 ? -errno : -EIO;
267
268 if (k != l && k != l + accept_extra_nl)
269 return 0;
270 if (memcmp(buf, blob, l) != 0)
271 return 0;
272 if (k > l && buf[l] != '\n')
273 return 0;
274
275 return 1;
276 }
277
278 int read_full_stream(FILE *f, char **contents, size_t *size) {
279 _cleanup_free_ char *buf = NULL;
280 struct stat st;
281 size_t n, l;
282 int fd;
283
284 assert(f);
285 assert(contents);
286
287 n = LINE_MAX;
288
289 fd = fileno(f);
290 if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see fmemopen(), let's
291 * optimize our buffering) */
292
293 if (fstat(fileno(f), &st) < 0)
294 return -errno;
295
296 if (S_ISREG(st.st_mode)) {
297
298 /* Safety check */
299 if (st.st_size > READ_FULL_BYTES_MAX)
300 return -E2BIG;
301
302 /* Start with the right file size, but be prepared for files from /proc which generally report a file
303 * size of 0. Note that we increase the size to read here by one, so that the first read attempt
304 * already makes us notice the EOF. */
305 if (st.st_size > 0)
306 n = st.st_size + 1;
307 }
308 }
309
310 l = 0;
311 for (;;) {
312 char *t;
313 size_t k;
314
315 t = realloc(buf, n + 1);
316 if (!t)
317 return -ENOMEM;
318
319 buf = t;
320 errno = 0;
321 k = fread(buf + l, 1, n - l, f);
322 if (k > 0)
323 l += k;
324
325 if (ferror(f))
326 return errno > 0 ? -errno : -EIO;
327
328 if (feof(f))
329 break;
330
331 /* We aren't expecting fread() to return a short read outside
332 * of (error && eof), assert buffer is full and enlarge buffer.
333 */
334 assert(l == n);
335
336 /* Safety check */
337 if (n >= READ_FULL_BYTES_MAX)
338 return -E2BIG;
339
340 n = MIN(n * 2, READ_FULL_BYTES_MAX);
341 }
342
343 buf[l] = 0;
344 *contents = TAKE_PTR(buf);
345
346 if (size)
347 *size = l;
348
349 return 0;
350 }
351
352 int read_full_file(const char *fn, char **contents, size_t *size) {
353 _cleanup_fclose_ FILE *f = NULL;
354
355 assert(fn);
356 assert(contents);
357
358 f = fopen(fn, "re");
359 if (!f)
360 return -errno;
361
362 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
363
364 return read_full_stream(f, contents, size);
365 }
366
367 static int parse_env_file_internal(
368 FILE *f,
369 const char *fname,
370 int (*push) (const char *filename, unsigned line,
371 const char *key, char *value, void *userdata, int *n_pushed),
372 void *userdata,
373 int *n_pushed) {
374
375 size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1;
376 _cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
377 unsigned line = 1;
378 char *p;
379 int r;
380
381 enum {
382 PRE_KEY,
383 KEY,
384 PRE_VALUE,
385 VALUE,
386 VALUE_ESCAPE,
387 SINGLE_QUOTE_VALUE,
388 SINGLE_QUOTE_VALUE_ESCAPE,
389 DOUBLE_QUOTE_VALUE,
390 DOUBLE_QUOTE_VALUE_ESCAPE,
391 COMMENT,
392 COMMENT_ESCAPE
393 } state = PRE_KEY;
394
395 if (f)
396 r = read_full_stream(f, &contents, NULL);
397 else
398 r = read_full_file(fname, &contents, NULL);
399 if (r < 0)
400 return r;
401
402 for (p = contents; *p; p++) {
403 char c = *p;
404
405 switch (state) {
406
407 case PRE_KEY:
408 if (strchr(COMMENTS, c))
409 state = COMMENT;
410 else if (!strchr(WHITESPACE, c)) {
411 state = KEY;
412 last_key_whitespace = (size_t) -1;
413
414 if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
415 return -ENOMEM;
416
417 key[n_key++] = c;
418 }
419 break;
420
421 case KEY:
422 if (strchr(NEWLINE, c)) {
423 state = PRE_KEY;
424 line++;
425 n_key = 0;
426 } else if (c == '=') {
427 state = PRE_VALUE;
428 last_value_whitespace = (size_t) -1;
429 } else {
430 if (!strchr(WHITESPACE, c))
431 last_key_whitespace = (size_t) -1;
432 else if (last_key_whitespace == (size_t) -1)
433 last_key_whitespace = n_key;
434
435 if (!GREEDY_REALLOC(key, key_alloc, n_key+2))
436 return -ENOMEM;
437
438 key[n_key++] = c;
439 }
440
441 break;
442
443 case PRE_VALUE:
444 if (strchr(NEWLINE, c)) {
445 state = PRE_KEY;
446 line++;
447 key[n_key] = 0;
448
449 if (value)
450 value[n_value] = 0;
451
452 /* strip trailing whitespace from key */
453 if (last_key_whitespace != (size_t) -1)
454 key[last_key_whitespace] = 0;
455
456 r = push(fname, line, key, value, userdata, n_pushed);
457 if (r < 0)
458 return r;
459
460 n_key = 0;
461 value = NULL;
462 value_alloc = n_value = 0;
463
464 } else if (c == '\'')
465 state = SINGLE_QUOTE_VALUE;
466 else if (c == '\"')
467 state = DOUBLE_QUOTE_VALUE;
468 else if (c == '\\')
469 state = VALUE_ESCAPE;
470 else if (!strchr(WHITESPACE, c)) {
471 state = VALUE;
472
473 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
474 return -ENOMEM;
475
476 value[n_value++] = c;
477 }
478
479 break;
480
481 case VALUE:
482 if (strchr(NEWLINE, c)) {
483 state = PRE_KEY;
484 line++;
485
486 key[n_key] = 0;
487
488 if (value)
489 value[n_value] = 0;
490
491 /* Chomp off trailing whitespace from value */
492 if (last_value_whitespace != (size_t) -1)
493 value[last_value_whitespace] = 0;
494
495 /* strip trailing whitespace from key */
496 if (last_key_whitespace != (size_t) -1)
497 key[last_key_whitespace] = 0;
498
499 r = push(fname, line, key, value, userdata, n_pushed);
500 if (r < 0)
501 return r;
502
503 n_key = 0;
504 value = NULL;
505 value_alloc = n_value = 0;
506
507 } else if (c == '\\') {
508 state = VALUE_ESCAPE;
509 last_value_whitespace = (size_t) -1;
510 } else {
511 if (!strchr(WHITESPACE, c))
512 last_value_whitespace = (size_t) -1;
513 else if (last_value_whitespace == (size_t) -1)
514 last_value_whitespace = n_value;
515
516 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
517 return -ENOMEM;
518
519 value[n_value++] = c;
520 }
521
522 break;
523
524 case VALUE_ESCAPE:
525 state = VALUE;
526
527 if (!strchr(NEWLINE, c)) {
528 /* Escaped newlines we eat up entirely */
529 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
530 return -ENOMEM;
531
532 value[n_value++] = c;
533 }
534 break;
535
536 case SINGLE_QUOTE_VALUE:
537 if (c == '\'')
538 state = PRE_VALUE;
539 else if (c == '\\')
540 state = SINGLE_QUOTE_VALUE_ESCAPE;
541 else {
542 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
543 return -ENOMEM;
544
545 value[n_value++] = c;
546 }
547
548 break;
549
550 case SINGLE_QUOTE_VALUE_ESCAPE:
551 state = SINGLE_QUOTE_VALUE;
552
553 if (!strchr(NEWLINE, c)) {
554 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
555 return -ENOMEM;
556
557 value[n_value++] = c;
558 }
559 break;
560
561 case DOUBLE_QUOTE_VALUE:
562 if (c == '\"')
563 state = PRE_VALUE;
564 else if (c == '\\')
565 state = DOUBLE_QUOTE_VALUE_ESCAPE;
566 else {
567 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
568 return -ENOMEM;
569
570 value[n_value++] = c;
571 }
572
573 break;
574
575 case DOUBLE_QUOTE_VALUE_ESCAPE:
576 state = DOUBLE_QUOTE_VALUE;
577
578 if (!strchr(NEWLINE, c)) {
579 if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
580 return -ENOMEM;
581
582 value[n_value++] = c;
583 }
584 break;
585
586 case COMMENT:
587 if (c == '\\')
588 state = COMMENT_ESCAPE;
589 else if (strchr(NEWLINE, c)) {
590 state = PRE_KEY;
591 line++;
592 }
593 break;
594
595 case COMMENT_ESCAPE:
596 state = COMMENT;
597 break;
598 }
599 }
600
601 if (IN_SET(state,
602 PRE_VALUE,
603 VALUE,
604 VALUE_ESCAPE,
605 SINGLE_QUOTE_VALUE,
606 SINGLE_QUOTE_VALUE_ESCAPE,
607 DOUBLE_QUOTE_VALUE,
608 DOUBLE_QUOTE_VALUE_ESCAPE)) {
609
610 key[n_key] = 0;
611
612 if (value)
613 value[n_value] = 0;
614
615 if (state == VALUE)
616 if (last_value_whitespace != (size_t) -1)
617 value[last_value_whitespace] = 0;
618
619 /* strip trailing whitespace from key */
620 if (last_key_whitespace != (size_t) -1)
621 key[last_key_whitespace] = 0;
622
623 r = push(fname, line, key, value, userdata, n_pushed);
624 if (r < 0)
625 return r;
626
627 value = NULL;
628 }
629
630 return 0;
631 }
632
633 static int check_utf8ness_and_warn(
634 const char *filename, unsigned line,
635 const char *key, char *value) {
636
637 if (!utf8_is_valid(key)) {
638 _cleanup_free_ char *p = NULL;
639
640 p = utf8_escape_invalid(key);
641 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
642 "%s:%u: invalid UTF-8 in key '%s', ignoring.",
643 strna(filename), line, p);
644 }
645
646 if (value && !utf8_is_valid(value)) {
647 _cleanup_free_ char *p = NULL;
648
649 p = utf8_escape_invalid(value);
650 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
651 "%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.",
652 strna(filename), line, key, p);
653 }
654
655 return 0;
656 }
657
658 static int parse_env_file_push(
659 const char *filename, unsigned line,
660 const char *key, char *value,
661 void *userdata,
662 int *n_pushed) {
663
664 const char *k;
665 va_list aq, *ap = userdata;
666 int r;
667
668 r = check_utf8ness_and_warn(filename, line, key, value);
669 if (r < 0)
670 return r;
671
672 va_copy(aq, *ap);
673
674 while ((k = va_arg(aq, const char *))) {
675 char **v;
676
677 v = va_arg(aq, char **);
678
679 if (streq(key, k)) {
680 va_end(aq);
681 free(*v);
682 *v = value;
683
684 if (n_pushed)
685 (*n_pushed)++;
686
687 return 1;
688 }
689 }
690
691 va_end(aq);
692 free(value);
693
694 return 0;
695 }
696
697 int parse_env_filev(
698 FILE *f,
699 const char *fname,
700 va_list ap) {
701
702 int r, n_pushed = 0;
703 va_list aq;
704
705 va_copy(aq, ap);
706 r = parse_env_file_internal(f, fname, parse_env_file_push, &aq, &n_pushed);
707 va_end(aq);
708 if (r < 0)
709 return r;
710
711 return n_pushed;
712 }
713
714 int parse_env_file_sentinel(
715 FILE *f,
716 const char *fname,
717 ...) {
718
719 va_list ap;
720 int r;
721
722 va_start(ap, fname);
723 r = parse_env_filev(f, fname, ap);
724 va_end(ap);
725
726 return r;
727 }
728
729 static int load_env_file_push(
730 const char *filename, unsigned line,
731 const char *key, char *value,
732 void *userdata,
733 int *n_pushed) {
734 char ***m = userdata;
735 char *p;
736 int r;
737
738 r = check_utf8ness_and_warn(filename, line, key, value);
739 if (r < 0)
740 return r;
741
742 p = strjoin(key, "=", value);
743 if (!p)
744 return -ENOMEM;
745
746 r = strv_env_replace(m, p);
747 if (r < 0) {
748 free(p);
749 return r;
750 }
751
752 if (n_pushed)
753 (*n_pushed)++;
754
755 free(value);
756 return 0;
757 }
758
759 int load_env_file(FILE *f, const char *fname, char ***rl) {
760 char **m = NULL;
761 int r;
762
763 r = parse_env_file_internal(f, fname, load_env_file_push, &m, NULL);
764 if (r < 0) {
765 strv_free(m);
766 return r;
767 }
768
769 *rl = m;
770 return 0;
771 }
772
773 static int load_env_file_push_pairs(
774 const char *filename, unsigned line,
775 const char *key, char *value,
776 void *userdata,
777 int *n_pushed) {
778 char ***m = userdata;
779 int r;
780
781 r = check_utf8ness_and_warn(filename, line, key, value);
782 if (r < 0)
783 return r;
784
785 r = strv_extend(m, key);
786 if (r < 0)
787 return -ENOMEM;
788
789 if (!value) {
790 r = strv_extend(m, "");
791 if (r < 0)
792 return -ENOMEM;
793 } else {
794 r = strv_push(m, value);
795 if (r < 0)
796 return r;
797 }
798
799 if (n_pushed)
800 (*n_pushed)++;
801
802 return 0;
803 }
804
805 int load_env_file_pairs(FILE *f, const char *fname, char ***rl) {
806 char **m = NULL;
807 int r;
808
809 r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m, NULL);
810 if (r < 0) {
811 strv_free(m);
812 return r;
813 }
814
815 *rl = m;
816 return 0;
817 }
818
819 static int merge_env_file_push(
820 const char *filename, unsigned line,
821 const char *key, char *value,
822 void *userdata,
823 int *n_pushed) {
824
825 char ***env = userdata;
826 char *expanded_value;
827
828 assert(env);
829
830 if (!value) {
831 log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
832 return 0;
833 }
834
835 if (!env_name_is_valid(key)) {
836 log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
837 free(value);
838 return 0;
839 }
840
841 expanded_value = replace_env(value, *env,
842 REPLACE_ENV_USE_ENVIRONMENT|
843 REPLACE_ENV_ALLOW_BRACELESS|
844 REPLACE_ENV_ALLOW_EXTENDED);
845 if (!expanded_value)
846 return -ENOMEM;
847
848 free_and_replace(value, expanded_value);
849
850 return load_env_file_push(filename, line, key, value, env, n_pushed);
851 }
852
853 int merge_env_file(
854 char ***env,
855 FILE *f,
856 const char *fname) {
857
858 /* NOTE: this function supports braceful and braceless variable expansions,
859 * plus "extended" substitutions, unlike other exported parsing functions.
860 */
861
862 return parse_env_file_internal(f, fname, merge_env_file_push, env, NULL);
863 }
864
865 static void write_env_var(FILE *f, const char *v) {
866 const char *p;
867
868 p = strchr(v, '=');
869 if (!p) {
870 /* Fallback */
871 fputs_unlocked(v, f);
872 fputc_unlocked('\n', f);
873 return;
874 }
875
876 p++;
877 fwrite_unlocked(v, 1, p-v, f);
878
879 if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
880 fputc_unlocked('\"', f);
881
882 for (; *p; p++) {
883 if (strchr(SHELL_NEED_ESCAPE, *p))
884 fputc_unlocked('\\', f);
885
886 fputc_unlocked(*p, f);
887 }
888
889 fputc_unlocked('\"', f);
890 } else
891 fputs_unlocked(p, f);
892
893 fputc_unlocked('\n', f);
894 }
895
896 int write_env_file(const char *fname, char **l) {
897 _cleanup_fclose_ FILE *f = NULL;
898 _cleanup_free_ char *p = NULL;
899 char **i;
900 int r;
901
902 assert(fname);
903
904 r = fopen_temporary(fname, &f, &p);
905 if (r < 0)
906 return r;
907
908 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
909 (void) fchmod_umask(fileno(f), 0644);
910
911 STRV_FOREACH(i, l)
912 write_env_var(f, *i);
913
914 r = fflush_and_check(f);
915 if (r >= 0) {
916 if (rename(p, fname) >= 0)
917 return 0;
918
919 r = -errno;
920 }
921
922 unlink(p);
923 return r;
924 }
925
926 int executable_is_script(const char *path, char **interpreter) {
927 _cleanup_free_ char *line = NULL;
928 size_t len;
929 char *ans;
930 int r;
931
932 assert(path);
933
934 r = read_one_line_file(path, &line);
935 if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */
936 return 0;
937 if (r < 0)
938 return r;
939
940 if (!startswith(line, "#!"))
941 return 0;
942
943 ans = strstrip(line + 2);
944 len = strcspn(ans, " \t");
945
946 if (len == 0)
947 return 0;
948
949 ans = strndup(ans, len);
950 if (!ans)
951 return -ENOMEM;
952
953 *interpreter = ans;
954 return 1;
955 }
956
957 /**
958 * Retrieve one field from a file like /proc/self/status. pattern
959 * should not include whitespace or the delimiter (':'). pattern matches only
960 * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
961 * zeros after the ':' will be skipped. field must be freed afterwards.
962 * terminator specifies the terminating characters of the field value (not
963 * included in the value).
964 */
965 int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
966 _cleanup_free_ char *status = NULL;
967 char *t, *f;
968 size_t len;
969 int r;
970
971 assert(terminator);
972 assert(filename);
973 assert(pattern);
974 assert(field);
975
976 r = read_full_file(filename, &status, NULL);
977 if (r < 0)
978 return r;
979
980 t = status;
981
982 do {
983 bool pattern_ok;
984
985 do {
986 t = strstr(t, pattern);
987 if (!t)
988 return -ENOENT;
989
990 /* Check that pattern occurs in beginning of line. */
991 pattern_ok = (t == status || t[-1] == '\n');
992
993 t += strlen(pattern);
994
995 } while (!pattern_ok);
996
997 t += strspn(t, " \t");
998 if (!*t)
999 return -ENOENT;
1000
1001 } while (*t != ':');
1002
1003 t++;
1004
1005 if (*t) {
1006 t += strspn(t, " \t");
1007
1008 /* Also skip zeros, because when this is used for
1009 * capabilities, we don't want the zeros. This way the
1010 * same capability set always maps to the same string,
1011 * irrespective of the total capability set size. For
1012 * other numbers it shouldn't matter. */
1013 t += strspn(t, "0");
1014 /* Back off one char if there's nothing but whitespace
1015 and zeros */
1016 if (!*t || isspace(*t))
1017 t--;
1018 }
1019
1020 len = strcspn(t, terminator);
1021
1022 f = strndup(t, len);
1023 if (!f)
1024 return -ENOMEM;
1025
1026 *field = f;
1027 return 0;
1028 }
1029
1030 DIR *xopendirat(int fd, const char *name, int flags) {
1031 int nfd;
1032 DIR *d;
1033
1034 assert(!(flags & O_CREAT));
1035
1036 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
1037 if (nfd < 0)
1038 return NULL;
1039
1040 d = fdopendir(nfd);
1041 if (!d) {
1042 safe_close(nfd);
1043 return NULL;
1044 }
1045
1046 return d;
1047 }
1048
1049 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
1050 char **i;
1051
1052 assert(path);
1053 assert(mode);
1054 assert(_f);
1055
1056 if (!path_strv_resolve_uniq(search, root))
1057 return -ENOMEM;
1058
1059 STRV_FOREACH(i, search) {
1060 _cleanup_free_ char *p = NULL;
1061 FILE *f;
1062
1063 if (root)
1064 p = strjoin(root, *i, "/", path);
1065 else
1066 p = strjoin(*i, "/", path);
1067 if (!p)
1068 return -ENOMEM;
1069
1070 f = fopen(p, mode);
1071 if (f) {
1072 *_f = f;
1073 return 0;
1074 }
1075
1076 if (errno != ENOENT)
1077 return -errno;
1078 }
1079
1080 return -ENOENT;
1081 }
1082
1083 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
1084 _cleanup_strv_free_ char **copy = NULL;
1085
1086 assert(path);
1087 assert(mode);
1088 assert(_f);
1089
1090 if (path_is_absolute(path)) {
1091 FILE *f;
1092
1093 f = fopen(path, mode);
1094 if (f) {
1095 *_f = f;
1096 return 0;
1097 }
1098
1099 return -errno;
1100 }
1101
1102 copy = strv_copy((char**) search);
1103 if (!copy)
1104 return -ENOMEM;
1105
1106 return search_and_fopen_internal(path, mode, root, copy, _f);
1107 }
1108
1109 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
1110 _cleanup_strv_free_ char **s = NULL;
1111
1112 if (path_is_absolute(path)) {
1113 FILE *f;
1114
1115 f = fopen(path, mode);
1116 if (f) {
1117 *_f = f;
1118 return 0;
1119 }
1120
1121 return -errno;
1122 }
1123
1124 s = strv_split_nulstr(search);
1125 if (!s)
1126 return -ENOMEM;
1127
1128 return search_and_fopen_internal(path, mode, root, s, _f);
1129 }
1130
1131 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
1132 FILE *f;
1133 char *t;
1134 int r, fd;
1135
1136 assert(path);
1137 assert(_f);
1138 assert(_temp_path);
1139
1140 r = tempfn_xxxxxx(path, NULL, &t);
1141 if (r < 0)
1142 return r;
1143
1144 fd = mkostemp_safe(t);
1145 if (fd < 0) {
1146 free(t);
1147 return -errno;
1148 }
1149
1150 f = fdopen(fd, "we");
1151 if (!f) {
1152 unlink_noerrno(t);
1153 free(t);
1154 safe_close(fd);
1155 return -errno;
1156 }
1157
1158 *_f = f;
1159 *_temp_path = t;
1160
1161 return 0;
1162 }
1163
1164 int fflush_and_check(FILE *f) {
1165 assert(f);
1166
1167 errno = 0;
1168 fflush(f);
1169
1170 if (ferror(f))
1171 return errno > 0 ? -errno : -EIO;
1172
1173 return 0;
1174 }
1175
1176 int fflush_sync_and_check(FILE *f) {
1177 int r;
1178
1179 assert(f);
1180
1181 r = fflush_and_check(f);
1182 if (r < 0)
1183 return r;
1184
1185 if (fsync(fileno(f)) < 0)
1186 return -errno;
1187
1188 r = fsync_directory_of_file(fileno(f));
1189 if (r < 0)
1190 return r;
1191
1192 return 0;
1193 }
1194
1195 /* This is much like mkostemp() but is subject to umask(). */
1196 int mkostemp_safe(char *pattern) {
1197 _cleanup_umask_ mode_t u = 0;
1198 int fd;
1199
1200 assert(pattern);
1201
1202 u = umask(077);
1203
1204 fd = mkostemp(pattern, O_CLOEXEC);
1205 if (fd < 0)
1206 return -errno;
1207
1208 return fd;
1209 }
1210
1211 int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) {
1212 int fd;
1213 FILE *f;
1214
1215 fd = mkostemp_safe(pattern);
1216 if (fd < 0)
1217 return fd;
1218
1219 f = fdopen(fd, mode);
1220 if (!f) {
1221 safe_close(fd);
1222 return -errno;
1223 }
1224
1225 *ret_f = f;
1226 return 0;
1227 }
1228
1229 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
1230 const char *fn;
1231 char *t;
1232
1233 assert(ret);
1234
1235 if (isempty(p))
1236 return -EINVAL;
1237 if (path_equal(p, "/"))
1238 return -EINVAL;
1239
1240 /*
1241 * Turns this:
1242 * /foo/bar/waldo
1243 *
1244 * Into this:
1245 * /foo/bar/.#<extra>waldoXXXXXX
1246 */
1247
1248 fn = basename(p);
1249 if (!filename_is_valid(fn))
1250 return -EINVAL;
1251
1252 extra = strempty(extra);
1253
1254 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
1255 if (!t)
1256 return -ENOMEM;
1257
1258 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
1259
1260 *ret = path_simplify(t, false);
1261 return 0;
1262 }
1263
1264 int tempfn_random(const char *p, const char *extra, char **ret) {
1265 const char *fn;
1266 char *t, *x;
1267 uint64_t u;
1268 unsigned i;
1269
1270 assert(ret);
1271
1272 if (isempty(p))
1273 return -EINVAL;
1274 if (path_equal(p, "/"))
1275 return -EINVAL;
1276
1277 /*
1278 * Turns this:
1279 * /foo/bar/waldo
1280 *
1281 * Into this:
1282 * /foo/bar/.#<extra>waldobaa2a261115984a9
1283 */
1284
1285 fn = basename(p);
1286 if (!filename_is_valid(fn))
1287 return -EINVAL;
1288
1289 extra = strempty(extra);
1290
1291 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
1292 if (!t)
1293 return -ENOMEM;
1294
1295 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
1296
1297 u = random_u64();
1298 for (i = 0; i < 16; i++) {
1299 *(x++) = hexchar(u & 0xF);
1300 u >>= 4;
1301 }
1302
1303 *x = 0;
1304
1305 *ret = path_simplify(t, false);
1306 return 0;
1307 }
1308
1309 int tempfn_random_child(const char *p, const char *extra, char **ret) {
1310 char *t, *x;
1311 uint64_t u;
1312 unsigned i;
1313 int r;
1314
1315 assert(ret);
1316
1317 /* Turns this:
1318 * /foo/bar/waldo
1319 * Into this:
1320 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
1321 */
1322
1323 if (!p) {
1324 r = tmp_dir(&p);
1325 if (r < 0)
1326 return r;
1327 }
1328
1329 extra = strempty(extra);
1330
1331 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
1332 if (!t)
1333 return -ENOMEM;
1334
1335 if (isempty(p))
1336 x = stpcpy(stpcpy(t, ".#"), extra);
1337 else
1338 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
1339
1340 u = random_u64();
1341 for (i = 0; i < 16; i++) {
1342 *(x++) = hexchar(u & 0xF);
1343 u >>= 4;
1344 }
1345
1346 *x = 0;
1347
1348 *ret = path_simplify(t, false);
1349 return 0;
1350 }
1351
1352 int write_timestamp_file_atomic(const char *fn, usec_t n) {
1353 char ln[DECIMAL_STR_MAX(n)+2];
1354
1355 /* Creates a "timestamp" file, that contains nothing but a
1356 * usec_t timestamp, formatted in ASCII. */
1357
1358 if (n <= 0 || n >= USEC_INFINITY)
1359 return -ERANGE;
1360
1361 xsprintf(ln, USEC_FMT "\n", n);
1362
1363 return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1364 }
1365
1366 int read_timestamp_file(const char *fn, usec_t *ret) {
1367 _cleanup_free_ char *ln = NULL;
1368 uint64_t t;
1369 int r;
1370
1371 r = read_one_line_file(fn, &ln);
1372 if (r < 0)
1373 return r;
1374
1375 r = safe_atou64(ln, &t);
1376 if (r < 0)
1377 return r;
1378
1379 if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
1380 return -ERANGE;
1381
1382 *ret = (usec_t) t;
1383 return 0;
1384 }
1385
1386 int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
1387 int r;
1388
1389 assert(s);
1390
1391 /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
1392 * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
1393 * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
1394 * element, but not before the first one. */
1395
1396 if (!f)
1397 f = stdout;
1398
1399 if (space) {
1400 if (!separator)
1401 separator = " ";
1402
1403 if (*space) {
1404 r = fputs(separator, f);
1405 if (r < 0)
1406 return r;
1407 }
1408
1409 *space = true;
1410 }
1411
1412 return fputs(s, f);
1413 }
1414
1415 int open_tmpfile_unlinkable(const char *directory, int flags) {
1416 char *p;
1417 int fd, r;
1418
1419 if (!directory) {
1420 r = tmp_dir(&directory);
1421 if (r < 0)
1422 return r;
1423 } else if (isempty(directory))
1424 return -EINVAL;
1425
1426 /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
1427
1428 /* Try O_TMPFILE first, if it is supported */
1429 fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
1430 if (fd >= 0)
1431 return fd;
1432
1433 /* Fall back to unguessable name + unlinking */
1434 p = strjoina(directory, "/systemd-tmp-XXXXXX");
1435
1436 fd = mkostemp_safe(p);
1437 if (fd < 0)
1438 return fd;
1439
1440 (void) unlink(p);
1441
1442 return fd;
1443 }
1444
1445 int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
1446 _cleanup_free_ char *tmp = NULL;
1447 int r, fd;
1448
1449 assert(target);
1450 assert(ret_path);
1451
1452 /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
1453 assert((flags & O_EXCL) == 0);
1454
1455 /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
1456 * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
1457 * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
1458
1459 fd = open_parent(target, O_TMPFILE|flags, 0640);
1460 if (fd >= 0) {
1461 *ret_path = NULL;
1462 return fd;
1463 }
1464
1465 log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target);
1466
1467 r = tempfn_random(target, NULL, &tmp);
1468 if (r < 0)
1469 return r;
1470
1471 fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
1472 if (fd < 0)
1473 return -errno;
1474
1475 *ret_path = TAKE_PTR(tmp);
1476
1477 return fd;
1478 }
1479
1480 int open_serialization_fd(const char *ident) {
1481 int fd = -1;
1482
1483 fd = memfd_create(ident, MFD_CLOEXEC);
1484 if (fd < 0) {
1485 const char *path;
1486
1487 path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
1488 fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
1489 if (fd < 0)
1490 return fd;
1491
1492 log_debug("Serializing %s to %s.", ident, path);
1493 } else
1494 log_debug("Serializing %s to memfd.", ident);
1495
1496 return fd;
1497 }
1498
1499 int link_tmpfile(int fd, const char *path, const char *target) {
1500 int r;
1501
1502 assert(fd >= 0);
1503 assert(target);
1504
1505 /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
1506 * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
1507 * on the directory, and renameat2() is used instead.
1508 *
1509 * Note that in both cases we will not replace existing files. This is because linkat() does not support this
1510 * operation currently (renameat2() does), and there is no nice way to emulate this. */
1511
1512 if (path) {
1513 r = rename_noreplace(AT_FDCWD, path, AT_FDCWD, target);
1514 if (r < 0)
1515 return r;
1516 } else {
1517 char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
1518
1519 xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
1520
1521 if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
1522 return -errno;
1523 }
1524
1525 return 0;
1526 }
1527
1528 int read_nul_string(FILE *f, char **ret) {
1529 _cleanup_free_ char *x = NULL;
1530 size_t allocated = 0, n = 0;
1531
1532 assert(f);
1533 assert(ret);
1534
1535 /* Reads a NUL-terminated string from the specified file. */
1536
1537 for (;;) {
1538 int c;
1539
1540 if (!GREEDY_REALLOC(x, allocated, n+2))
1541 return -ENOMEM;
1542
1543 c = fgetc(f);
1544 if (c == 0) /* Terminate at NUL byte */
1545 break;
1546 if (c == EOF) {
1547 if (ferror(f))
1548 return -errno;
1549 break; /* Terminate at EOF */
1550 }
1551
1552 x[n++] = (char) c;
1553 }
1554
1555 if (x)
1556 x[n] = 0;
1557 else {
1558 x = new0(char, 1);
1559 if (!x)
1560 return -ENOMEM;
1561 }
1562
1563 *ret = TAKE_PTR(x);
1564
1565 return 0;
1566 }
1567
1568 int mkdtemp_malloc(const char *template, char **ret) {
1569 _cleanup_free_ char *p = NULL;
1570 int r;
1571
1572 assert(ret);
1573
1574 if (template)
1575 p = strdup(template);
1576 else {
1577 const char *tmp;
1578
1579 r = tmp_dir(&tmp);
1580 if (r < 0)
1581 return r;
1582
1583 p = strjoin(tmp, "/XXXXXX");
1584 }
1585 if (!p)
1586 return -ENOMEM;
1587
1588 if (!mkdtemp(p))
1589 return -errno;
1590
1591 *ret = TAKE_PTR(p);
1592 return 0;
1593 }
1594
1595 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
1596
1597 int read_line(FILE *f, size_t limit, char **ret) {
1598 _cleanup_free_ char *buffer = NULL;
1599 size_t n = 0, allocated = 0, count = 0;
1600
1601 assert(f);
1602
1603 /* Something like a bounded version of getline().
1604 *
1605 * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
1606 * returned.
1607 *
1608 * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1609 * the number of characters in the returned string). When EOF is hit, 0 is returned.
1610 *
1611 * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1612 * delimiters. If the limit is hit we fail and return -ENOBUFS.
1613 *
1614 * If a line shall be skipped ret may be initialized as NULL. */
1615
1616 if (ret) {
1617 if (!GREEDY_REALLOC(buffer, allocated, 1))
1618 return -ENOMEM;
1619 }
1620
1621 {
1622 _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
1623 flockfile(f);
1624
1625 for (;;) {
1626 int c;
1627
1628 if (n >= limit)
1629 return -ENOBUFS;
1630
1631 errno = 0;
1632 c = fgetc_unlocked(f);
1633 if (c == EOF) {
1634 /* if we read an error, and have no data to return, then propagate the error */
1635 if (ferror_unlocked(f) && n == 0)
1636 return errno > 0 ? -errno : -EIO;
1637
1638 break;
1639 }
1640
1641 count++;
1642
1643 if (IN_SET(c, '\n', 0)) /* Reached a delimiter */
1644 break;
1645
1646 if (ret) {
1647 if (!GREEDY_REALLOC(buffer, allocated, n + 2))
1648 return -ENOMEM;
1649
1650 buffer[n] = (char) c;
1651 }
1652
1653 n++;
1654 }
1655 }
1656
1657 if (ret) {
1658 buffer[n] = 0;
1659
1660 *ret = TAKE_PTR(buffer);
1661 }
1662
1663 return (int) count;
1664 }