chiark / gitweb /
fileio: write_string_stream_ts: check for file errors immediately
[elogind.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 #if 0 /// UNNEEDED by elogind
714 static int load_env_file_push(
715                 const char *filename, unsigned line,
716                 const char *key, char *value,
717                 void *userdata,
718                 int *n_pushed) {
719         char ***m = userdata;
720         char *p;
721         int r;
722
723         r = check_utf8ness_and_warn(filename, line, key, value);
724         if (r < 0)
725                 return r;
726
727         p = strjoin(key, "=", value);
728         if (!p)
729                 return -ENOMEM;
730
731         r = strv_env_replace(m, p);
732         if (r < 0) {
733                 free(p);
734                 return r;
735         }
736
737         if (n_pushed)
738                 (*n_pushed)++;
739
740         free(value);
741         return 0;
742 }
743
744 int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
745         char **m = NULL;
746         int r;
747
748         if (!newline)
749                 newline = NEWLINE;
750
751         r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL);
752         if (r < 0) {
753                 strv_free(m);
754                 return r;
755         }
756
757         *rl = m;
758         return 0;
759 }
760 #endif // 0
761
762 static int load_env_file_push_pairs(
763                 const char *filename, unsigned line,
764                 const char *key, char *value,
765                 void *userdata,
766                 int *n_pushed) {
767         char ***m = userdata;
768         int r;
769
770         r = check_utf8ness_and_warn(filename, line, key, value);
771         if (r < 0)
772                 return r;
773
774         r = strv_extend(m, key);
775         if (r < 0)
776                 return -ENOMEM;
777
778         if (!value) {
779                 r = strv_extend(m, "");
780                 if (r < 0)
781                         return -ENOMEM;
782         } else {
783                 r = strv_push(m, value);
784                 if (r < 0)
785                         return r;
786         }
787
788         if (n_pushed)
789                 (*n_pushed)++;
790
791         return 0;
792 }
793
794 int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
795         char **m = NULL;
796         int r;
797
798         if (!newline)
799                 newline = NEWLINE;
800
801         r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
802         if (r < 0) {
803                 strv_free(m);
804                 return r;
805         }
806
807         *rl = m;
808         return 0;
809 }
810 #if 0 /// UNNEEDED by elogind
811
812 static int merge_env_file_push(
813                 const char *filename, unsigned line,
814                 const char *key, char *value,
815                 void *userdata,
816                 int *n_pushed) {
817
818         char ***env = userdata;
819         char *expanded_value;
820
821         assert(env);
822
823         if (!value) {
824                 log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
825                 return 0;
826         }
827
828         if (!env_name_is_valid(key)) {
829                 log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
830                 free(value);
831                 return 0;
832         }
833
834         expanded_value = replace_env(value, *env,
835                                      REPLACE_ENV_USE_ENVIRONMENT|
836                                      REPLACE_ENV_ALLOW_BRACELESS|
837                                      REPLACE_ENV_ALLOW_EXTENDED);
838         if (!expanded_value)
839                 return -ENOMEM;
840
841         free_and_replace(value, expanded_value);
842
843         return load_env_file_push(filename, line, key, value, env, n_pushed);
844 }
845
846 int merge_env_file(
847                 char ***env,
848                 FILE *f,
849                 const char *fname) {
850
851         /* NOTE: this function supports braceful and braceless variable expansions,
852          * plus "extended" substitutions, unlike other exported parsing functions.
853          */
854
855         return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
856 }
857
858 static void write_env_var(FILE *f, const char *v) {
859         const char *p;
860
861         p = strchr(v, '=');
862         if (!p) {
863                 /* Fallback */
864                 fputs_unlocked(v, f);
865                 fputc_unlocked('\n', f);
866                 return;
867         }
868
869         p++;
870         fwrite_unlocked(v, 1, p-v, f);
871
872         if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
873                 fputc_unlocked('\"', f);
874
875                 for (; *p; p++) {
876                         if (strchr(SHELL_NEED_ESCAPE, *p))
877                                 fputc_unlocked('\\', f);
878
879                         fputc_unlocked(*p, f);
880                 }
881
882                 fputc_unlocked('\"', f);
883         } else
884                 fputs_unlocked(p, f);
885
886         fputc_unlocked('\n', f);
887 }
888
889 int write_env_file(const char *fname, char **l) {
890         _cleanup_fclose_ FILE *f = NULL;
891         _cleanup_free_ char *p = NULL;
892         char **i;
893         int r;
894
895         assert(fname);
896
897         r = fopen_temporary(fname, &f, &p);
898         if (r < 0)
899                 return r;
900
901         (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
902         (void) fchmod_umask(fileno(f), 0644);
903
904         STRV_FOREACH(i, l)
905                 write_env_var(f, *i);
906
907         r = fflush_and_check(f);
908         if (r >= 0) {
909                 if (rename(p, fname) >= 0)
910                         return 0;
911
912                 r = -errno;
913         }
914
915         unlink(p);
916         return r;
917 }
918
919 int executable_is_script(const char *path, char **interpreter) {
920         int r;
921         _cleanup_free_ char *line = NULL;
922         int len;
923         char *ans;
924
925         assert(path);
926
927         r = read_one_line_file(path, &line);
928         if (r < 0)
929                 return r;
930
931         if (!startswith(line, "#!"))
932                 return 0;
933
934         ans = strstrip(line + 2);
935         len = strcspn(ans, " \t");
936
937         if (len == 0)
938                 return 0;
939
940         ans = strndup(ans, len);
941         if (!ans)
942                 return -ENOMEM;
943
944         *interpreter = ans;
945         return 1;
946 }
947 #endif // 0
948
949 /**
950  * Retrieve one field from a file like /proc/self/status.  pattern
951  * should not include whitespace or the delimiter (':'). pattern matches only
952  * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
953  * zeros after the ':' will be skipped. field must be freed afterwards.
954  * terminator specifies the terminating characters of the field value (not
955  * included in the value).
956  */
957 int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
958         _cleanup_free_ char *status = NULL;
959         char *t, *f;
960         size_t len;
961         int r;
962
963         assert(terminator);
964         assert(filename);
965         assert(pattern);
966         assert(field);
967
968         r = read_full_file(filename, &status, NULL);
969         if (r < 0)
970                 return r;
971
972         t = status;
973
974         do {
975                 bool pattern_ok;
976
977                 do {
978                         t = strstr(t, pattern);
979                         if (!t)
980                                 return -ENOENT;
981
982                         /* Check that pattern occurs in beginning of line. */
983                         pattern_ok = (t == status || t[-1] == '\n');
984
985                         t += strlen(pattern);
986
987                 } while (!pattern_ok);
988
989                 t += strspn(t, " \t");
990                 if (!*t)
991                         return -ENOENT;
992
993         } while (*t != ':');
994
995         t++;
996
997         if (*t) {
998                 t += strspn(t, " \t");
999
1000                 /* Also skip zeros, because when this is used for
1001                  * capabilities, we don't want the zeros. This way the
1002                  * same capability set always maps to the same string,
1003                  * irrespective of the total capability set size. For
1004                  * other numbers it shouldn't matter. */
1005                 t += strspn(t, "0");
1006                 /* Back off one char if there's nothing but whitespace
1007                    and zeros */
1008                 if (!*t || isspace(*t))
1009                         t--;
1010         }
1011
1012         len = strcspn(t, terminator);
1013
1014         f = strndup(t, len);
1015         if (!f)
1016                 return -ENOMEM;
1017
1018         *field = f;
1019         return 0;
1020 }
1021
1022 DIR *xopendirat(int fd, const char *name, int flags) {
1023         int nfd;
1024         DIR *d;
1025
1026         assert(!(flags & O_CREAT));
1027
1028         nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
1029         if (nfd < 0)
1030                 return NULL;
1031
1032         d = fdopendir(nfd);
1033         if (!d) {
1034                 safe_close(nfd);
1035                 return NULL;
1036         }
1037
1038         return d;
1039 }
1040
1041 #if 0 /// UNNEEDED by elogind
1042 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
1043         char **i;
1044
1045         assert(path);
1046         assert(mode);
1047         assert(_f);
1048
1049         if (!path_strv_resolve_uniq(search, root))
1050                 return -ENOMEM;
1051
1052         STRV_FOREACH(i, search) {
1053                 _cleanup_free_ char *p = NULL;
1054                 FILE *f;
1055
1056                 if (root)
1057                         p = strjoin(root, *i, "/", path);
1058                 else
1059                         p = strjoin(*i, "/", path);
1060                 if (!p)
1061                         return -ENOMEM;
1062
1063                 f = fopen(p, mode);
1064                 if (f) {
1065                         *_f = f;
1066                         return 0;
1067                 }
1068
1069                 if (errno != ENOENT)
1070                         return -errno;
1071         }
1072
1073         return -ENOENT;
1074 }
1075
1076 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
1077         _cleanup_strv_free_ char **copy = NULL;
1078
1079         assert(path);
1080         assert(mode);
1081         assert(_f);
1082
1083         if (path_is_absolute(path)) {
1084                 FILE *f;
1085
1086                 f = fopen(path, mode);
1087                 if (f) {
1088                         *_f = f;
1089                         return 0;
1090                 }
1091
1092                 return -errno;
1093         }
1094
1095         copy = strv_copy((char**) search);
1096         if (!copy)
1097                 return -ENOMEM;
1098
1099         return search_and_fopen_internal(path, mode, root, copy, _f);
1100 }
1101
1102 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
1103         _cleanup_strv_free_ char **s = NULL;
1104
1105         if (path_is_absolute(path)) {
1106                 FILE *f;
1107
1108                 f = fopen(path, mode);
1109                 if (f) {
1110                         *_f = f;
1111                         return 0;
1112                 }
1113
1114                 return -errno;
1115         }
1116
1117         s = strv_split_nulstr(search);
1118         if (!s)
1119                 return -ENOMEM;
1120
1121         return search_and_fopen_internal(path, mode, root, s, _f);
1122 }
1123 #endif // 0
1124
1125 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
1126         FILE *f;
1127         char *t;
1128         int r, fd;
1129
1130         assert(path);
1131         assert(_f);
1132         assert(_temp_path);
1133
1134         r = tempfn_xxxxxx(path, NULL, &t);
1135         if (r < 0)
1136                 return r;
1137
1138         fd = mkostemp_safe(t);
1139         if (fd < 0) {
1140                 free(t);
1141                 return -errno;
1142         }
1143
1144         f = fdopen(fd, "we");
1145         if (!f) {
1146                 unlink_noerrno(t);
1147                 free(t);
1148                 safe_close(fd);
1149                 return -errno;
1150         }
1151
1152         *_f = f;
1153         *_temp_path = t;
1154
1155         return 0;
1156 }
1157
1158 int fflush_and_check(FILE *f) {
1159         assert(f);
1160
1161         errno = 0;
1162         fflush(f);
1163
1164         if (ferror(f))
1165                 return errno > 0 ? -errno : -EIO;
1166
1167         return 0;
1168 }
1169
1170 int fflush_sync_and_check(FILE *f) {
1171         int r;
1172
1173         assert(f);
1174
1175         r = fflush_and_check(f);
1176         if (r < 0)
1177                 return r;
1178
1179         if (fsync(fileno(f)) < 0)
1180                 return -errno;
1181
1182         return 0;
1183 }
1184
1185 /* This is much like mkostemp() but is subject to umask(). */
1186 int mkostemp_safe(char *pattern) {
1187         _cleanup_umask_ mode_t u = 0;
1188         int fd;
1189
1190         assert(pattern);
1191
1192         u = umask(077);
1193
1194         fd = mkostemp(pattern, O_CLOEXEC);
1195         if (fd < 0)
1196                 return -errno;
1197
1198         return fd;
1199 }
1200
1201 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
1202         const char *fn;
1203         char *t;
1204
1205         assert(p);
1206         assert(ret);
1207
1208         /*
1209          * Turns this:
1210          *         /foo/bar/waldo
1211          *
1212          * Into this:
1213          *         /foo/bar/.#<extra>waldoXXXXXX
1214          */
1215
1216         fn = basename(p);
1217         if (!filename_is_valid(fn))
1218                 return -EINVAL;
1219
1220         if (!extra)
1221                 extra = "";
1222
1223         t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
1224         if (!t)
1225                 return -ENOMEM;
1226
1227         strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
1228
1229         *ret = path_kill_slashes(t);
1230         return 0;
1231 }
1232
1233 int tempfn_random(const char *p, const char *extra, char **ret) {
1234         const char *fn;
1235         char *t, *x;
1236         uint64_t u;
1237         unsigned i;
1238
1239         assert(p);
1240         assert(ret);
1241
1242         /*
1243          * Turns this:
1244          *         /foo/bar/waldo
1245          *
1246          * Into this:
1247          *         /foo/bar/.#<extra>waldobaa2a261115984a9
1248          */
1249
1250         fn = basename(p);
1251         if (!filename_is_valid(fn))
1252                 return -EINVAL;
1253
1254         if (!extra)
1255                 extra = "";
1256
1257         t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
1258         if (!t)
1259                 return -ENOMEM;
1260
1261         x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
1262
1263         u = random_u64();
1264         for (i = 0; i < 16; i++) {
1265                 *(x++) = hexchar(u & 0xF);
1266                 u >>= 4;
1267         }
1268
1269         *x = 0;
1270
1271         *ret = path_kill_slashes(t);
1272         return 0;
1273 }
1274
1275 #if 0 /// UNNEEDED by elogind
1276 int tempfn_random_child(const char *p, const char *extra, char **ret) {
1277         char *t, *x;
1278         uint64_t u;
1279         unsigned i;
1280         int r;
1281
1282         assert(ret);
1283
1284         /* Turns this:
1285          *         /foo/bar/waldo
1286          * Into this:
1287          *         /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
1288          */
1289
1290         if (!p) {
1291                 r = tmp_dir(&p);
1292                 if (r < 0)
1293                         return r;
1294         }
1295
1296         if (!extra)
1297                 extra = "";
1298
1299         t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
1300         if (!t)
1301                 return -ENOMEM;
1302
1303         x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
1304
1305         u = random_u64();
1306         for (i = 0; i < 16; i++) {
1307                 *(x++) = hexchar(u & 0xF);
1308                 u >>= 4;
1309         }
1310
1311         *x = 0;
1312
1313         *ret = path_kill_slashes(t);
1314         return 0;
1315 }
1316
1317 int write_timestamp_file_atomic(const char *fn, usec_t n) {
1318         char ln[DECIMAL_STR_MAX(n)+2];
1319
1320         /* Creates a "timestamp" file, that contains nothing but a
1321          * usec_t timestamp, formatted in ASCII. */
1322
1323         if (n <= 0 || n >= USEC_INFINITY)
1324                 return -ERANGE;
1325
1326         xsprintf(ln, USEC_FMT "\n", n);
1327
1328         return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1329 }
1330
1331 int read_timestamp_file(const char *fn, usec_t *ret) {
1332         _cleanup_free_ char *ln = NULL;
1333         uint64_t t;
1334         int r;
1335
1336         r = read_one_line_file(fn, &ln);
1337         if (r < 0)
1338                 return r;
1339
1340         r = safe_atou64(ln, &t);
1341         if (r < 0)
1342                 return r;
1343
1344         if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
1345                 return -ERANGE;
1346
1347         *ret = (usec_t) t;
1348         return 0;
1349 }
1350
1351 int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
1352         int r;
1353
1354         assert(s);
1355
1356         /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
1357          * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
1358          * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
1359          * element, but not before the first one. */
1360
1361         if (!f)
1362                 f = stdout;
1363
1364         if (space) {
1365                 if (!separator)
1366                         separator = " ";
1367
1368                 if (*space) {
1369                         r = fputs(separator, f);
1370                         if (r < 0)
1371                                 return r;
1372                 }
1373
1374                 *space = true;
1375         }
1376
1377         return fputs(s, f);
1378 }
1379 #endif // 0
1380
1381 int open_tmpfile_unlinkable(const char *directory, int flags) {
1382         char *p;
1383         int fd, r;
1384
1385         if (!directory) {
1386                 r = tmp_dir(&directory);
1387                 if (r < 0)
1388                         return r;
1389         }
1390
1391         /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
1392
1393         /* Try O_TMPFILE first, if it is supported */
1394         fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
1395         if (fd >= 0)
1396                 return fd;
1397
1398         /* Fall back to unguessable name + unlinking */
1399         p = strjoina(directory, "/systemd-tmp-XXXXXX");
1400
1401         fd = mkostemp_safe(p);
1402         if (fd < 0)
1403                 return fd;
1404
1405         (void) unlink(p);
1406
1407         return fd;
1408 }
1409
1410 #if 0 /// UNNEEDED by elogind
1411 int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
1412         _cleanup_free_ char *tmp = NULL;
1413         int r, fd;
1414
1415         assert(target);
1416         assert(ret_path);
1417
1418         /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
1419         assert((flags & O_EXCL) == 0);
1420
1421         /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
1422          * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
1423          * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
1424
1425         {
1426                 _cleanup_free_ char *dn = NULL;
1427
1428                 dn = dirname_malloc(target);
1429                 if (!dn)
1430                         return -ENOMEM;
1431
1432                 fd = open(dn, O_TMPFILE|flags, 0640);
1433                 if (fd >= 0) {
1434                         *ret_path = NULL;
1435                         return fd;
1436                 }
1437
1438                 log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
1439         }
1440
1441         r = tempfn_random(target, NULL, &tmp);
1442         if (r < 0)
1443                 return r;
1444
1445         fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
1446         if (fd < 0)
1447                 return -errno;
1448
1449         *ret_path = tmp;
1450         tmp = NULL;
1451
1452         return fd;
1453 }
1454 #endif // 0
1455
1456 int open_serialization_fd(const char *ident) {
1457         int fd = -1;
1458
1459         fd = memfd_create(ident, MFD_CLOEXEC);
1460         if (fd < 0) {
1461                 const char *path;
1462
1463                 path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
1464                 fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
1465                 if (fd < 0)
1466                         return fd;
1467
1468                 log_debug("Serializing %s to %s.", ident, path);
1469         } else
1470                 log_debug("Serializing %s to memfd.", ident);
1471
1472         return fd;
1473 }
1474
1475 #if 0 /// UNNEEDED by elogind
1476 int link_tmpfile(int fd, const char *path, const char *target) {
1477
1478         assert(fd >= 0);
1479         assert(target);
1480
1481         /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
1482          * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
1483          * on the directory, and renameat2() is used instead.
1484          *
1485          * Note that in both cases we will not replace existing files. This is because linkat() does not support this
1486          * operation currently (renameat2() does), and there is no nice way to emulate this. */
1487
1488         if (path) {
1489                 if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
1490                         return -errno;
1491         } else {
1492                 char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
1493
1494                 xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
1495
1496                 if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
1497                         return -errno;
1498         }
1499
1500         return 0;
1501 }
1502
1503 int read_nul_string(FILE *f, char **ret) {
1504         _cleanup_free_ char *x = NULL;
1505         size_t allocated = 0, n = 0;
1506
1507         assert(f);
1508         assert(ret);
1509
1510         /* Reads a NUL-terminated string from the specified file. */
1511
1512         for (;;) {
1513                 int c;
1514
1515                 if (!GREEDY_REALLOC(x, allocated, n+2))
1516                         return -ENOMEM;
1517
1518                 c = fgetc(f);
1519                 if (c == 0) /* Terminate at NUL byte */
1520                         break;
1521                 if (c == EOF) {
1522                         if (ferror(f))
1523                                 return -errno;
1524                         break; /* Terminate at EOF */
1525                 }
1526
1527                 x[n++] = (char) c;
1528         }
1529
1530         if (x)
1531                 x[n] = 0;
1532         else {
1533                 x = new0(char, 1);
1534                 if (!x)
1535                         return -ENOMEM;
1536         }
1537
1538         *ret = x;
1539         x = NULL;
1540
1541         return 0;
1542 }
1543
1544 int mkdtemp_malloc(const char *template, char **ret) {
1545         char *p;
1546
1547         assert(template);
1548         assert(ret);
1549
1550         p = strdup(template);
1551         if (!p)
1552                 return -ENOMEM;
1553
1554         if (!mkdtemp(p)) {
1555                 free(p);
1556                 return -errno;
1557         }
1558
1559         *ret = p;
1560         return 0;
1561 }
1562 #endif // 0
1563
1564 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
1565
1566 int read_line(FILE *f, size_t limit, char **ret) {
1567         _cleanup_free_ char *buffer = NULL;
1568         size_t n = 0, allocated = 0, count = 0;
1569
1570         assert(f);
1571
1572         /* Something like a bounded version of getline().
1573          *
1574          * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
1575          * returned.
1576          *
1577          * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1578          * the number of characters in the returned string). When EOF is hit, 0 is returned.
1579          *
1580          * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1581          * delimiters. If the limit is hit we fail and return -ENOBUFS.
1582          *
1583          * If a line shall be skipped ret may be initialized as NULL. */
1584
1585         if (ret) {
1586                 if (!GREEDY_REALLOC(buffer, allocated, 1))
1587                         return -ENOMEM;
1588         }
1589
1590         {
1591                 _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
1592                 flockfile(f);
1593
1594                 for (;;) {
1595                         int c;
1596
1597                         if (n >= limit)
1598                                 return -ENOBUFS;
1599
1600                         errno = 0;
1601                         c = fgetc_unlocked(f);
1602                         if (c == EOF) {
1603                                 /* if we read an error, and have no data to return, then propagate the error */
1604                                 if (ferror_unlocked(f) && n == 0)
1605                                         return errno > 0 ? -errno : -EIO;
1606
1607                                 break;
1608                         }
1609
1610                         count++;
1611
1612                         if (IN_SET(c, '\n', 0)) /* Reached a delimiter */
1613                                 break;
1614
1615                         if (ret) {
1616                                 if (!GREEDY_REALLOC(buffer, allocated, n + 2))
1617                                         return -ENOMEM;
1618
1619                                 buffer[n] = (char) c;
1620                         }
1621
1622                         n++;
1623                 }
1624         }
1625
1626         if (ret) {
1627                 buffer[n] = 0;
1628
1629                 *ret = buffer;
1630                 buffer = NULL;
1631         }
1632
1633         return (int) count;
1634 }