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