]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/serialize.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include "alloc-util.h"
10 #include "parse-util.h"
11 #include "process-util.h"
12 #include "serialize.h"
14 #include "tmpfile-util.h"
16 int serialize_item(FILE *f
, const char *key
, const char *value
) {
23 /* Make sure that anything we serialize we can also read back again with read_line() with a maximum line size
24 * of LONG_LINE_MAX. This is a safety net only. All code calling us should filter this out earlier anyway. */
25 if (strlen(key
) + 1 + strlen(value
) + 1 > LONG_LINE_MAX
) {
26 log_warning("Attempted to serialize overly long item '%s', refusing.", key
);
38 int serialize_item_escaped(FILE *f
, const char *key
, const char *value
) {
39 _cleanup_free_
char *c
= NULL
;
51 return serialize_item(f
, key
, c
);
54 int serialize_item_format(FILE *f
, const char *key
, const char *format
, ...) {
55 char buf
[LONG_LINE_MAX
];
64 k
= vsnprintf(buf
, sizeof(buf
), format
, ap
);
67 if (k
< 0 || (size_t) k
>= sizeof(buf
) || strlen(key
) + 1 + k
+ 1 > LONG_LINE_MAX
) {
68 log_warning("Attempted to serialize overly long item '%s', refusing.", key
);
80 int serialize_fd(FILE *f
, FDSet
*fds
, const char *key
, int fd
) {
89 copy
= fdset_put_dup(fds
, fd
);
91 return log_error_errno(copy
, "Failed to add file descriptor to serialization set: %m");
93 return serialize_item_format(f
, key
, "%i", copy
);
96 int serialize_usec(FILE *f
, const char *key
, usec_t usec
) {
100 if (usec
== USEC_INFINITY
)
103 return serialize_item_format(f
, key
, USEC_FMT
, usec
);
106 int serialize_dual_timestamp(FILE *f
, const char *name
, const dual_timestamp
*t
) {
111 if (!dual_timestamp_is_set(t
))
114 return serialize_item_format(f
, name
, USEC_FMT
" " USEC_FMT
, t
->realtime
, t
->monotonic
);
117 int serialize_strv(FILE *f
, const char *key
, char **l
) {
121 /* Returns the first error, or positive if anything was serialized, 0 otherwise. */
124 r
= serialize_item_escaped(f
, key
, *i
);
125 if ((ret
>= 0 && r
< 0) ||
133 int deserialize_usec(const char *value
, usec_t
*ret
) {
138 r
= safe_atou64(value
, ret
);
140 return log_debug_errno(r
, "Failed to parse usec value \"%s\": %m", value
);
145 int deserialize_dual_timestamp(const char *value
, dual_timestamp
*t
) {
152 pos
= strspn(value
, WHITESPACE
);
153 if (value
[pos
] == '-')
155 pos
+= strspn(value
+ pos
, DIGITS
);
156 pos
+= strspn(value
+ pos
, WHITESPACE
);
157 if (value
[pos
] == '-')
160 r
= sscanf(value
, "%" PRIu64
"%" PRIu64
"%n", &a
, &b
, &pos
);
162 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
163 "Failed to parse dual timestamp value \"%s\".",
166 if (value
[pos
] != '\0')
167 /* trailing garbage */
176 int deserialize_environment(const char *value
, char ***list
) {
177 _cleanup_free_
char *unescaped
= NULL
;
183 /* Changes the *environment strv inline. */
185 r
= cunescape(value
, 0, &unescaped
);
187 return log_error_errno(r
, "Failed to unescape: %m");
189 r
= strv_env_replace(list
, unescaped
);
191 return log_error_errno(r
, "Failed to append environment variable: %m");
193 unescaped
= NULL
; /* now part of 'list' */
197 int open_serialization_fd(const char *ident
) {
200 fd
= memfd_create(ident
, MFD_CLOEXEC
);
204 path
= getpid_cached() == 1 ? "/run/systemd" : "/tmp";
205 fd
= open_tmpfile_unlinkable(path
, O_RDWR
|O_CLOEXEC
);
209 log_debug("Serializing %s to %s.", ident
, path
);
211 log_debug("Serializing %s to memfd.", ident
);