]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/serialize.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
9 #include "missing_mman.h"
10 #include "missing_syscall.h"
11 #include "parse-util.h"
12 #include "process-util.h"
13 #include "serialize.h"
15 #include "tmpfile-util.h"
17 int serialize_item(FILE *f
, const char *key
, const char *value
) {
24 /* Make sure that anything we serialize we can also read back again with read_line() with a maximum line size
25 * of LONG_LINE_MAX. This is a safety net only. All code calling us should filter this out earlier anyway. */
26 if (strlen(key
) + 1 + strlen(value
) + 1 > LONG_LINE_MAX
) {
27 log_warning("Attempted to serialize overly long item '%s', refusing.", key
);
39 int serialize_item_escaped(FILE *f
, const char *key
, const char *value
) {
40 _cleanup_free_
char *c
= NULL
;
52 return serialize_item(f
, key
, c
);
55 int serialize_item_format(FILE *f
, const char *key
, const char *format
, ...) {
56 char buf
[LONG_LINE_MAX
];
65 k
= vsnprintf(buf
, sizeof(buf
), format
, ap
);
68 if (k
< 0 || (size_t) k
>= sizeof(buf
) || strlen(key
) + 1 + k
+ 1 > LONG_LINE_MAX
) {
69 log_warning("Attempted to serialize overly long item '%s', refusing.", key
);
81 int serialize_fd(FILE *f
, FDSet
*fds
, const char *key
, int fd
) {
90 copy
= fdset_put_dup(fds
, fd
);
92 return log_error_errno(copy
, "Failed to add file descriptor to serialization set: %m");
94 return serialize_item_format(f
, key
, "%i", copy
);
97 int serialize_usec(FILE *f
, const char *key
, usec_t usec
) {
101 if (usec
== USEC_INFINITY
)
104 return serialize_item_format(f
, key
, USEC_FMT
, usec
);
107 int serialize_dual_timestamp(FILE *f
, const char *name
, const dual_timestamp
*t
) {
112 if (!dual_timestamp_is_set(t
))
115 return serialize_item_format(f
, name
, USEC_FMT
" " USEC_FMT
, t
->realtime
, t
->monotonic
);
118 int serialize_strv(FILE *f
, const char *key
, char **l
) {
122 /* Returns the first error, or positive if anything was serialized, 0 otherwise. */
125 r
= serialize_item_escaped(f
, key
, *i
);
126 if ((ret
>= 0 && r
< 0) ||
134 int deserialize_usec(const char *value
, usec_t
*ret
) {
139 r
= safe_atou64(value
, ret
);
141 return log_debug_errno(r
, "Failed to parse usec value \"%s\": %m", value
);
146 int deserialize_dual_timestamp(const char *value
, dual_timestamp
*t
) {
153 pos
= strspn(value
, WHITESPACE
);
154 if (value
[pos
] == '-')
156 pos
+= strspn(value
+ pos
, DIGITS
);
157 pos
+= strspn(value
+ pos
, WHITESPACE
);
158 if (value
[pos
] == '-')
161 r
= sscanf(value
, "%" PRIu64
"%" PRIu64
"%n", &a
, &b
, &pos
);
163 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
164 "Failed to parse dual timestamp value \"%s\".",
167 if (value
[pos
] != '\0')
168 /* trailing garbage */
177 int deserialize_environment(const char *value
, char ***list
) {
178 _cleanup_free_
char *unescaped
= NULL
;
185 /* Changes the *environment strv inline. */
187 l
= cunescape(value
, 0, &unescaped
);
189 return log_error_errno(l
, "Failed to unescape: %m");
191 r
= strv_env_replace_consume(list
, TAKE_PTR(unescaped
));
193 return log_error_errno(r
, "Failed to append environment variable: %m");
198 int open_serialization_fd(const char *ident
) {
201 fd
= memfd_create(ident
, MFD_CLOEXEC
);
205 path
= getpid_cached() == 1 ? "/run/systemd" : "/tmp";
206 fd
= open_tmpfile_unlinkable(path
, O_RDWR
|O_CLOEXEC
);
210 log_debug("Serializing %s to %s.", ident
, path
);
212 log_debug("Serializing %s to memfd.", ident
);