1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
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.
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.
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/>.
26 #include <stdio_ext.h>
31 #include <sys/types.h>
34 #include "alloc-util.h"
42 #include "hexdecoct.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"
53 #include "time-util.h"
54 #include "umask-util.h"
57 #define READ_FULL_BYTES_MAX (4U*1024U*1024U)
59 int write_string_stream_ts(
62 WriteStringFileFlags flags
,
63 struct timespec
*ts
) {
73 needs_nl
= !(flags
& WRITE_STRING_FILE_AVOID_NEWLINE
) && !endswith(line
, "\n");
75 if (needs_nl
&& (flags
& WRITE_STRING_FILE_DISABLE_BUFFER
)) {
76 /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
77 * that the write goes out in one go, instead of two */
79 line
= strjoina(line
, "\n");
83 if (fputs(line
, f
) == EOF
)
87 if (fputc('\n', f
) == EOF
)
91 struct timespec twice
[2] = {*ts
, *ts
};
93 if (futimens(fileno(f
), twice
) < 0)
97 if (flags
& WRITE_STRING_FILE_SYNC
)
98 return fflush_sync_and_check(f
);
100 return fflush_and_check(f
);
103 static int write_string_file_atomic(
106 WriteStringFileFlags flags
,
107 struct timespec
*ts
) {
109 _cleanup_fclose_
FILE *f
= NULL
;
110 _cleanup_free_
char *p
= NULL
;
116 r
= fopen_temporary(fn
, &f
, &p
);
120 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
121 (void) fchmod_umask(fileno(f
), 0644);
123 r
= write_string_stream_ts(f
, line
, flags
, ts
);
127 if (rename(p
, fn
) < 0) {
139 int write_string_file_ts(
142 WriteStringFileFlags flags
,
143 struct timespec
*ts
) {
145 _cleanup_fclose_
FILE *f
= NULL
;
151 /* We don't know how to verify whether the file contents was already on-disk. */
152 assert(!((flags
& WRITE_STRING_FILE_VERIFY_ON_FAILURE
) && (flags
& WRITE_STRING_FILE_SYNC
)));
154 if (flags
& WRITE_STRING_FILE_ATOMIC
) {
155 assert(flags
& WRITE_STRING_FILE_CREATE
);
157 r
= write_string_file_atomic(fn
, line
, flags
, ts
);
165 if (flags
& WRITE_STRING_FILE_CREATE
) {
174 /* We manually build our own version of fopen(..., "we") that
175 * works without O_CREAT */
176 fd
= open(fn
, O_WRONLY
|O_CLOEXEC
|O_NOCTTY
);
182 f
= fdopen(fd
, "we");
190 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
192 if (flags
& WRITE_STRING_FILE_DISABLE_BUFFER
)
193 setvbuf(f
, NULL
, _IONBF
, 0);
195 r
= write_string_stream_ts(f
, line
, flags
, ts
);
202 if (!(flags
& WRITE_STRING_FILE_VERIFY_ON_FAILURE
))
207 /* OK, the operation failed, but let's see if the right
208 * contents in place already. If so, eat up the error. */
210 q
= verify_file(fn
, line
, !(flags
& WRITE_STRING_FILE_AVOID_NEWLINE
));
217 int read_one_line_file(const char *fn
, char **line
) {
218 _cleanup_fclose_
FILE *f
= NULL
;
228 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
230 r
= read_line(f
, LONG_LINE_MAX
, line
);
231 return r
< 0 ? r
: 0;
234 int verify_file(const char *fn
, const char *blob
, bool accept_extra_nl
) {
235 _cleanup_fclose_
FILE *f
= NULL
;
236 _cleanup_free_
char *buf
= NULL
;
244 if (accept_extra_nl
&& endswith(blob
, "\n"))
245 accept_extra_nl
= false;
247 buf
= malloc(l
+ accept_extra_nl
+ 1);
255 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
257 /* We try to read one byte more than we need, so that we know whether we hit eof */
259 k
= fread(buf
, 1, l
+ accept_extra_nl
+ 1, f
);
261 return errno
> 0 ? -errno
: -EIO
;
263 if (k
!= l
&& k
!= l
+ accept_extra_nl
)
265 if (memcmp(buf
, blob
, l
) != 0)
267 if (k
> l
&& buf
[l
] != '\n')
273 int read_full_stream(FILE *f
, char **contents
, size_t *size
) {
275 _cleanup_free_
char *buf
= NULL
;
281 if (fstat(fileno(f
), &st
) < 0)
286 if (S_ISREG(st
.st_mode
)) {
289 if (st
.st_size
> READ_FULL_BYTES_MAX
)
292 /* Start with the right file size, but be prepared for files from /proc which generally report a file
293 * size of 0. Note that we increase the size to read here by one, so that the first read attempt
294 * already makes us notice the EOF. */
304 t
= realloc(buf
, n
+ 1);
310 k
= fread(buf
+ l
, 1, n
- l
, f
);
315 return errno
> 0 ? -errno
: -EIO
;
320 /* We aren't expecting fread() to return a short read outside
321 * of (error && eof), assert buffer is full and enlarge buffer.
326 if (n
>= READ_FULL_BYTES_MAX
)
329 n
= MIN(n
* 2, READ_FULL_BYTES_MAX
);
334 buf
= NULL
; /* do not free */
342 int read_full_file(const char *fn
, char **contents
, size_t *size
) {
343 _cleanup_fclose_
FILE *f
= NULL
;
352 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
354 return read_full_stream(f
, contents
, size
);
357 static int parse_env_file_internal(
361 int (*push
) (const char *filename
, unsigned line
,
362 const char *key
, char *value
, void *userdata
, int *n_pushed
),
366 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;
367 _cleanup_free_
char *contents
= NULL
, *key
= NULL
, *value
= NULL
;
379 SINGLE_QUOTE_VALUE_ESCAPE
,
381 DOUBLE_QUOTE_VALUE_ESCAPE
,
389 r
= read_full_stream(f
, &contents
, NULL
);
391 r
= read_full_file(fname
, &contents
, NULL
);
395 for (p
= contents
; *p
; p
++) {
401 if (strchr(COMMENTS
, c
))
403 else if (!strchr(WHITESPACE
, c
)) {
405 last_key_whitespace
= (size_t) -1;
407 if (!GREEDY_REALLOC(key
, key_alloc
, n_key
+2))
415 if (strchr(newline
, c
)) {
419 } else if (c
== '=') {
421 last_value_whitespace
= (size_t) -1;
423 if (!strchr(WHITESPACE
, c
))
424 last_key_whitespace
= (size_t) -1;
425 else if (last_key_whitespace
== (size_t) -1)
426 last_key_whitespace
= n_key
;
428 if (!GREEDY_REALLOC(key
, key_alloc
, n_key
+2))
437 if (strchr(newline
, c
)) {
445 /* strip trailing whitespace from key */
446 if (last_key_whitespace
!= (size_t) -1)
447 key
[last_key_whitespace
] = 0;
449 r
= push(fname
, line
, key
, value
, userdata
, n_pushed
);
455 value_alloc
= n_value
= 0;
457 } else if (c
== '\'')
458 state
= SINGLE_QUOTE_VALUE
;
460 state
= DOUBLE_QUOTE_VALUE
;
462 state
= VALUE_ESCAPE
;
463 else if (!strchr(WHITESPACE
, c
)) {
466 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
469 value
[n_value
++] = c
;
475 if (strchr(newline
, c
)) {
484 /* Chomp off trailing whitespace from value */
485 if (last_value_whitespace
!= (size_t) -1)
486 value
[last_value_whitespace
] = 0;
488 /* strip trailing whitespace from key */
489 if (last_key_whitespace
!= (size_t) -1)
490 key
[last_key_whitespace
] = 0;
492 r
= push(fname
, line
, key
, value
, userdata
, n_pushed
);
498 value_alloc
= n_value
= 0;
500 } else if (c
== '\\') {
501 state
= VALUE_ESCAPE
;
502 last_value_whitespace
= (size_t) -1;
504 if (!strchr(WHITESPACE
, c
))
505 last_value_whitespace
= (size_t) -1;
506 else if (last_value_whitespace
== (size_t) -1)
507 last_value_whitespace
= n_value
;
509 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
512 value
[n_value
++] = c
;
520 if (!strchr(newline
, c
)) {
521 /* Escaped newlines we eat up entirely */
522 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
525 value
[n_value
++] = c
;
529 case SINGLE_QUOTE_VALUE
:
533 state
= SINGLE_QUOTE_VALUE_ESCAPE
;
535 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
538 value
[n_value
++] = c
;
543 case SINGLE_QUOTE_VALUE_ESCAPE
:
544 state
= SINGLE_QUOTE_VALUE
;
546 if (!strchr(newline
, c
)) {
547 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
550 value
[n_value
++] = c
;
554 case DOUBLE_QUOTE_VALUE
:
558 state
= DOUBLE_QUOTE_VALUE_ESCAPE
;
560 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
563 value
[n_value
++] = c
;
568 case DOUBLE_QUOTE_VALUE_ESCAPE
:
569 state
= DOUBLE_QUOTE_VALUE
;
571 if (!strchr(newline
, c
)) {
572 if (!GREEDY_REALLOC(value
, value_alloc
, n_value
+2))
575 value
[n_value
++] = c
;
581 state
= COMMENT_ESCAPE
;
582 else if (strchr(newline
, c
)) {
599 SINGLE_QUOTE_VALUE_ESCAPE
,
601 DOUBLE_QUOTE_VALUE_ESCAPE
)) {
609 if (last_value_whitespace
!= (size_t) -1)
610 value
[last_value_whitespace
] = 0;
612 /* strip trailing whitespace from key */
613 if (last_key_whitespace
!= (size_t) -1)
614 key
[last_key_whitespace
] = 0;
616 r
= push(fname
, line
, key
, value
, userdata
, n_pushed
);
626 static int check_utf8ness_and_warn(
627 const char *filename
, unsigned line
,
628 const char *key
, char *value
) {
630 if (!utf8_is_valid(key
)) {
631 _cleanup_free_
char *p
= NULL
;
633 p
= utf8_escape_invalid(key
);
634 log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename
), line
, p
);
638 if (value
&& !utf8_is_valid(value
)) {
639 _cleanup_free_
char *p
= NULL
;
641 p
= utf8_escape_invalid(value
);
642 log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename
), line
, key
, p
);
649 static int parse_env_file_push(
650 const char *filename
, unsigned line
,
651 const char *key
, char *value
,
656 va_list aq
, *ap
= userdata
;
659 r
= check_utf8ness_and_warn(filename
, line
, key
, value
);
665 while ((k
= va_arg(aq
, const char *))) {
668 v
= va_arg(aq
, char **);
690 const char *newline
, ...) {
698 va_start(ap
, newline
);
699 r
= parse_env_file_internal(NULL
, fname
, newline
, parse_env_file_push
, &ap
, &n_pushed
);
702 return r
< 0 ? r
: n_pushed
;
705 static int load_env_file_push(
706 const char *filename
, unsigned line
,
707 const char *key
, char *value
,
710 char ***m
= userdata
;
714 r
= check_utf8ness_and_warn(filename
, line
, key
, value
);
718 p
= strjoin(key
, "=", value
);
722 r
= strv_env_replace(m
, p
);
735 int load_env_file(FILE *f
, const char *fname
, const char *newline
, char ***rl
) {
742 r
= parse_env_file_internal(f
, fname
, newline
, load_env_file_push
, &m
, NULL
);
752 static int load_env_file_push_pairs(
753 const char *filename
, unsigned line
,
754 const char *key
, char *value
,
757 char ***m
= userdata
;
760 r
= check_utf8ness_and_warn(filename
, line
, key
, value
);
764 r
= strv_extend(m
, key
);
769 r
= strv_extend(m
, "");
773 r
= strv_push(m
, value
);
784 int load_env_file_pairs(FILE *f
, const char *fname
, const char *newline
, char ***rl
) {
791 r
= parse_env_file_internal(f
, fname
, newline
, load_env_file_push_pairs
, &m
, NULL
);
801 static int merge_env_file_push(
802 const char *filename
, unsigned line
,
803 const char *key
, char *value
,
807 char ***env
= userdata
;
808 char *expanded_value
;
813 log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename
), line
, key
);
817 if (!env_name_is_valid(key
)) {
818 log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename
), line
, key
);
823 expanded_value
= replace_env(value
, *env
,
824 REPLACE_ENV_USE_ENVIRONMENT
|
825 REPLACE_ENV_ALLOW_BRACELESS
|
826 REPLACE_ENV_ALLOW_EXTENDED
);
830 free_and_replace(value
, expanded_value
);
832 return load_env_file_push(filename
, line
, key
, value
, env
, n_pushed
);
840 /* NOTE: this function supports braceful and braceless variable expansions,
841 * plus "extended" substitutions, unlike other exported parsing functions.
844 return parse_env_file_internal(f
, fname
, NEWLINE
, merge_env_file_push
, env
, NULL
);
847 static void write_env_var(FILE *f
, const char *v
) {
853 fputs_unlocked(v
, f
);
854 fputc_unlocked('\n', f
);
859 fwrite_unlocked(v
, 1, p
-v
, f
);
861 if (string_has_cc(p
, NULL
) || chars_intersect(p
, WHITESPACE SHELL_NEED_QUOTES
)) {
862 fputc_unlocked('\"', f
);
865 if (strchr(SHELL_NEED_ESCAPE
, *p
))
866 fputc_unlocked('\\', f
);
868 fputc_unlocked(*p
, f
);
871 fputc_unlocked('\"', f
);
873 fputs_unlocked(p
, f
);
875 fputc_unlocked('\n', f
);
878 int write_env_file(const char *fname
, char **l
) {
879 _cleanup_fclose_
FILE *f
= NULL
;
880 _cleanup_free_
char *p
= NULL
;
886 r
= fopen_temporary(fname
, &f
, &p
);
890 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
891 (void) fchmod_umask(fileno(f
), 0644);
894 write_env_var(f
, *i
);
896 r
= fflush_and_check(f
);
898 if (rename(p
, fname
) >= 0)
908 int executable_is_script(const char *path
, char **interpreter
) {
909 _cleanup_free_
char *line
= NULL
;
916 r
= read_one_line_file(path
, &line
);
917 if (r
== -ENOBUFS
) /* First line overly long? if so, then it's not a script */
922 if (!startswith(line
, "#!"))
925 ans
= strstrip(line
+ 2);
926 len
= strcspn(ans
, " \t");
931 ans
= strndup(ans
, len
);
940 * Retrieve one field from a file like /proc/self/status. pattern
941 * should not include whitespace or the delimiter (':'). pattern matches only
942 * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
943 * zeros after the ':' will be skipped. field must be freed afterwards.
944 * terminator specifies the terminating characters of the field value (not
945 * included in the value).
947 int get_proc_field(const char *filename
, const char *pattern
, const char *terminator
, char **field
) {
948 _cleanup_free_
char *status
= NULL
;
958 r
= read_full_file(filename
, &status
, NULL
);
968 t
= strstr(t
, pattern
);
972 /* Check that pattern occurs in beginning of line. */
973 pattern_ok
= (t
== status
|| t
[-1] == '\n');
975 t
+= strlen(pattern
);
977 } while (!pattern_ok
);
979 t
+= strspn(t
, " \t");
988 t
+= strspn(t
, " \t");
990 /* Also skip zeros, because when this is used for
991 * capabilities, we don't want the zeros. This way the
992 * same capability set always maps to the same string,
993 * irrespective of the total capability set size. For
994 * other numbers it shouldn't matter. */
996 /* Back off one char if there's nothing but whitespace
998 if (!*t
|| isspace(*t
))
1002 len
= strcspn(t
, terminator
);
1004 f
= strndup(t
, len
);
1012 DIR *xopendirat(int fd
, const char *name
, int flags
) {
1016 assert(!(flags
& O_CREAT
));
1018 nfd
= openat(fd
, name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|flags
, 0);
1031 static int search_and_fopen_internal(const char *path
, const char *mode
, const char *root
, char **search
, FILE **_f
) {
1038 if (!path_strv_resolve_uniq(search
, root
))
1041 STRV_FOREACH(i
, search
) {
1042 _cleanup_free_
char *p
= NULL
;
1046 p
= strjoin(root
, *i
, "/", path
);
1048 p
= strjoin(*i
, "/", path
);
1058 if (errno
!= ENOENT
)
1065 int search_and_fopen(const char *path
, const char *mode
, const char *root
, const char **search
, FILE **_f
) {
1066 _cleanup_strv_free_
char **copy
= NULL
;
1072 if (path_is_absolute(path
)) {
1075 f
= fopen(path
, mode
);
1084 copy
= strv_copy((char**) search
);
1088 return search_and_fopen_internal(path
, mode
, root
, copy
, _f
);
1091 int search_and_fopen_nulstr(const char *path
, const char *mode
, const char *root
, const char *search
, FILE **_f
) {
1092 _cleanup_strv_free_
char **s
= NULL
;
1094 if (path_is_absolute(path
)) {
1097 f
= fopen(path
, mode
);
1106 s
= strv_split_nulstr(search
);
1110 return search_and_fopen_internal(path
, mode
, root
, s
, _f
);
1113 int fopen_temporary(const char *path
, FILE **_f
, char **_temp_path
) {
1122 r
= tempfn_xxxxxx(path
, NULL
, &t
);
1126 fd
= mkostemp_safe(t
);
1132 f
= fdopen(fd
, "we");
1146 int fflush_and_check(FILE *f
) {
1153 return errno
> 0 ? -errno
: -EIO
;
1158 int fflush_sync_and_check(FILE *f
) {
1163 r
= fflush_and_check(f
);
1167 if (fsync(fileno(f
)) < 0)
1170 r
= fsync_directory_of_file(fileno(f
));
1177 /* This is much like mkostemp() but is subject to umask(). */
1178 int mkostemp_safe(char *pattern
) {
1179 _cleanup_umask_ mode_t u
= 0;
1186 fd
= mkostemp(pattern
, O_CLOEXEC
);
1193 int tempfn_xxxxxx(const char *p
, const char *extra
, char **ret
) {
1205 * /foo/bar/.#<extra>waldoXXXXXX
1209 if (!filename_is_valid(fn
))
1212 extra
= strempty(extra
);
1214 t
= new(char, strlen(p
) + 2 + strlen(extra
) + 6 + 1);
1218 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t
, p
, fn
- p
), ".#"), extra
), fn
), "XXXXXX");
1220 *ret
= path_kill_slashes(t
);
1224 int tempfn_random(const char *p
, const char *extra
, char **ret
) {
1238 * /foo/bar/.#<extra>waldobaa2a261115984a9
1242 if (!filename_is_valid(fn
))
1245 extra
= strempty(extra
);
1247 t
= new(char, strlen(p
) + 2 + strlen(extra
) + 16 + 1);
1251 x
= stpcpy(stpcpy(stpcpy(mempcpy(t
, p
, fn
- p
), ".#"), extra
), fn
);
1254 for (i
= 0; i
< 16; i
++) {
1255 *(x
++) = hexchar(u
& 0xF);
1261 *ret
= path_kill_slashes(t
);
1265 int tempfn_random_child(const char *p
, const char *extra
, char **ret
) {
1276 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
1285 extra
= strempty(extra
);
1287 t
= new(char, strlen(p
) + 3 + strlen(extra
) + 16 + 1);
1291 x
= stpcpy(stpcpy(stpcpy(t
, p
), "/.#"), extra
);
1294 for (i
= 0; i
< 16; i
++) {
1295 *(x
++) = hexchar(u
& 0xF);
1301 *ret
= path_kill_slashes(t
);
1305 int write_timestamp_file_atomic(const char *fn
, usec_t n
) {
1306 char ln
[DECIMAL_STR_MAX(n
)+2];
1308 /* Creates a "timestamp" file, that contains nothing but a
1309 * usec_t timestamp, formatted in ASCII. */
1311 if (n
<= 0 || n
>= USEC_INFINITY
)
1314 xsprintf(ln
, USEC_FMT
"\n", n
);
1316 return write_string_file(fn
, ln
, WRITE_STRING_FILE_CREATE
|WRITE_STRING_FILE_ATOMIC
);
1319 int read_timestamp_file(const char *fn
, usec_t
*ret
) {
1320 _cleanup_free_
char *ln
= NULL
;
1324 r
= read_one_line_file(fn
, &ln
);
1328 r
= safe_atou64(ln
, &t
);
1332 if (t
<= 0 || t
>= (uint64_t) USEC_INFINITY
)
1339 int fputs_with_space(FILE *f
, const char *s
, const char *separator
, bool *space
) {
1344 /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
1345 * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
1346 * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
1347 * element, but not before the first one. */
1357 r
= fputs(separator
, f
);
1368 int open_tmpfile_unlinkable(const char *directory
, int flags
) {
1373 r
= tmp_dir(&directory
);
1378 /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
1380 /* Try O_TMPFILE first, if it is supported */
1381 fd
= open(directory
, flags
|O_TMPFILE
|O_EXCL
, S_IRUSR
|S_IWUSR
);
1385 /* Fall back to unguessable name + unlinking */
1386 p
= strjoina(directory
, "/systemd-tmp-XXXXXX");
1388 fd
= mkostemp_safe(p
);
1397 int open_tmpfile_linkable(const char *target
, int flags
, char **ret_path
) {
1398 _cleanup_free_
char *tmp
= NULL
;
1404 /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
1405 assert((flags
& O_EXCL
) == 0);
1407 /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
1408 * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
1409 * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
1412 _cleanup_free_
char *dn
= NULL
;
1414 dn
= dirname_malloc(target
);
1418 fd
= open(dn
, O_TMPFILE
|flags
, 0640);
1424 log_debug_errno(errno
, "Failed to use O_TMPFILE on %s: %m", dn
);
1427 r
= tempfn_random(target
, NULL
, &tmp
);
1431 fd
= open(tmp
, O_CREAT
|O_EXCL
|O_NOFOLLOW
|O_NOCTTY
|flags
, 0640);
1441 int open_serialization_fd(const char *ident
) {
1444 fd
= memfd_create(ident
, MFD_CLOEXEC
);
1448 path
= getpid_cached() == 1 ? "/run/systemd" : "/tmp";
1449 fd
= open_tmpfile_unlinkable(path
, O_RDWR
|O_CLOEXEC
);
1453 log_debug("Serializing %s to %s.", ident
, path
);
1455 log_debug("Serializing %s to memfd.", ident
);
1460 int link_tmpfile(int fd
, const char *path
, const char *target
) {
1465 /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
1466 * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
1467 * on the directory, and renameat2() is used instead.
1469 * Note that in both cases we will not replace existing files. This is because linkat() does not support this
1470 * operation currently (renameat2() does), and there is no nice way to emulate this. */
1473 if (rename_noreplace(AT_FDCWD
, path
, AT_FDCWD
, target
) < 0)
1476 char proc_fd_path
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd
) + 1];
1478 xsprintf(proc_fd_path
, "/proc/self/fd/%i", fd
);
1480 if (linkat(AT_FDCWD
, proc_fd_path
, AT_FDCWD
, target
, AT_SYMLINK_FOLLOW
) < 0)
1487 int read_nul_string(FILE *f
, char **ret
) {
1488 _cleanup_free_
char *x
= NULL
;
1489 size_t allocated
= 0, n
= 0;
1494 /* Reads a NUL-terminated string from the specified file. */
1499 if (!GREEDY_REALLOC(x
, allocated
, n
+2))
1503 if (c
== 0) /* Terminate at NUL byte */
1508 break; /* Terminate at EOF */
1528 int mkdtemp_malloc(const char *template, char **ret
) {
1534 p
= strdup(template);
1547 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile
);
1549 int read_line(FILE *f
, size_t limit
, char **ret
) {
1550 _cleanup_free_
char *buffer
= NULL
;
1551 size_t n
= 0, allocated
= 0, count
= 0;
1555 /* Something like a bounded version of getline().
1557 * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
1560 * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1561 * the number of characters in the returned string). When EOF is hit, 0 is returned.
1563 * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1564 * delimiters. If the limit is hit we fail and return -ENOBUFS.
1566 * If a line shall be skipped ret may be initialized as NULL. */
1569 if (!GREEDY_REALLOC(buffer
, allocated
, 1))
1574 _unused_
_cleanup_(funlockfilep
) FILE *flocked
= f
;
1584 c
= fgetc_unlocked(f
);
1586 /* if we read an error, and have no data to return, then propagate the error */
1587 if (ferror_unlocked(f
) && n
== 0)
1588 return errno
> 0 ? -errno
: -EIO
;
1595 if (IN_SET(c
, '\n', 0)) /* Reached a delimiter */
1599 if (!GREEDY_REALLOC(buffer
, allocated
, n
+ 2))
1602 buffer
[n
] = (char) c
;