Bug Summary

File:build-scan/../src/shared/bus-unit-util.c
Warning:line 2333, column 25
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name bus-unit-util.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/shared/libsystemd-shared-239.a.p -I src/shared -I ../src/shared -I src/basic -I ../src/basic -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/shared/bus-unit-util.c

../src/shared/bus-unit-util.c

1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include "alloc-util.h"
4#include "bus-internal.h"
5#include "bus-unit-util.h"
6#include "bus-util.h"
7#include "cap-list.h"
8#include "cgroup-util.h"
9#include "condition.h"
10#include "cpu-set-util.h"
11#include "env-util.h"
12#include "errno-list.h"
13#include "escape.h"
14#include "hashmap.h"
15#include "hexdecoct.h"
16#include "hostname-util.h"
17#include "in-addr-util.h"
18#include "list.h"
19#include "locale-util.h"
20#include "mount-util.h"
21#include "nsflags.h"
22#include "parse-util.h"
23#include "path-util.h"
24#include "process-util.h"
25#include "rlimit-util.h"
26#include "securebits-util.h"
27#include "signal-util.h"
28#include "socket-protocol-list.h"
29#include "socket-util.h"
30#include "stdio-util.h"
31#include "string-util.h"
32#include "syslog-util.h"
33#include "terminal-util.h"
34#include "unit-def.h"
35#include "user-util.h"
36#include "utf8.h"
37#include "util.h"
38
39int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
40 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/shared/bus-unit-util.c"
, 40, __PRETTY_FUNCTION__); } while (0)
;
41 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/shared/bus-unit-util.c", 41
, __PRETTY_FUNCTION__); } while (0)
;
42
43 u->machine = NULL((void*)0);
44
45 return sd_bus_message_read(
46 message,
47 "(ssssssouso)",
48 &u->id,
49 &u->description,
50 &u->load_state,
51 &u->active_state,
52 &u->sub_state,
53 &u->following,
54 &u->unit_path,
55 &u->job_id,
56 &u->job_type,
57 &u->job_path);
58}
59
60#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func)static int bus_append_parse_func( sd_bus_message *m, const char
*field, const char *eq) { type val; int r; r = parse_func(eq
, &val); if (r < 0) return ({ int _level = ((3)), _e =
((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 60, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, bus_type
, (cast_type) val); if (r < 0) return bus_log_create_error
(r); return 1; }
\
61 static int bus_append_##parse_func( \
62 sd_bus_message *m, \
63 const char *field, \
64 const char *eq) { \
65 type val; \
66 int r; \
67 \
68 r = parse_func(eq, &val); \
69 if (r < 0) \
70 return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 70, __func__, "Failed to parse %s=%s: %m"
, field, eq) : -abs(_e); })
; \
71 \
72 r = sd_bus_message_append(m, "(sv)", field, \
73 bus_type, (cast_type) val); \
74 if (r < 0) \
75 return bus_log_create_error(r); \
76 \
77 return 1; \
78 }
79
80#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func)static int bus_append_parse_func( sd_bus_message *m, const char
*field, const char *eq) { int r; r = parse_func(eq); if (r <
0) { ({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 80, __func__, "Failed to parse %s: %s"
, field, eq) : -abs(_e); }); return -22; } r = sd_bus_message_append
(m, "(sv)", field, bus_type, (int32_t) r); if (r < 0) return
bus_log_create_error(r); return 1; }
\
81 static int bus_append_##parse_func( \
82 sd_bus_message *m, \
83 const char *field, \
84 const char *eq) { \
85 int r; \
86 \
87 r = parse_func(eq); \
88 if (r < 0) { \
89 log_error("Failed to parse %s: %s", field, eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 89, __func__, "Failed to parse %s: %s"
, field, eq) : -abs(_e); })
; \
90 return -EINVAL22; \
91 } \
92 \
93 r = sd_bus_message_append(m, "(sv)", field, \
94 bus_type, (int32_t) r); \
95 if (r < 0) \
96 return bus_log_create_error(r); \
97 \
98 return 1; \
99 }
100
101DEFINE_BUS_APPEND_PARSE("b", parse_boolean)static int bus_append_parse_boolean( sd_bus_message *m, const
char *field, const char *eq) { int r; r = parse_boolean(eq);
if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm =
(LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 101, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "b", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
102DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string)static int bus_append_ioprio_class_from_string( sd_bus_message
*m, const char *field, const char *eq) { int r; r = ioprio_class_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 102, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
103DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string)static int bus_append_ip_tos_from_string( sd_bus_message *m, const
char *field, const char *eq) { int r; r = ip_tos_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 103, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
104DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string)static int bus_append_log_facility_unshifted_from_string( sd_bus_message
*m, const char *field, const char *eq) { int r; r = log_facility_unshifted_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 104, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
105DEFINE_BUS_APPEND_PARSE("i", log_level_from_string)static int bus_append_log_level_from_string( sd_bus_message *
m, const char *field, const char *eq) { int r; r = log_level_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 105, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
106DEFINE_BUS_APPEND_PARSE("i", parse_errno)static int bus_append_parse_errno( sd_bus_message *m, const char
*field, const char *eq) { int r; r = parse_errno(eq); if (r <
0) { ({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 106, __func__, "Failed to parse %s: %s"
, field, eq) : -abs(_e); }); return -22; } r = sd_bus_message_append
(m, "(sv)", field, "i", (int32_t) r); if (r < 0) return bus_log_create_error
(r); return 1; }
;
107DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string)static int bus_append_sched_policy_from_string( sd_bus_message
*m, const char *field, const char *eq) { int r; r = sched_policy_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 107, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
108DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string)static int bus_append_secure_bits_from_string( sd_bus_message
*m, const char *field, const char *eq) { int r; r = secure_bits_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 108, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
109DEFINE_BUS_APPEND_PARSE("i", signal_from_string)static int bus_append_signal_from_string( sd_bus_message *m, const
char *field, const char *eq) { int r; r = signal_from_string
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 109, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
110DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name)static int bus_append_socket_protocol_from_name( sd_bus_message
*m, const char *field, const char *eq) { int r; r = socket_protocol_from_name
(eq); if (r < 0) { ({ int _level = (((3))), _e = ((0)), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 110, __func__
, "Failed to parse %s: %s", field, eq) : -abs(_e); }); return
-22; } r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) r); if (r < 0) return bus_log_create_error(r); return 1;
}
;
111DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority)static int bus_append_ioprio_parse_priority( sd_bus_message *
m, const char *field, const char *eq) { int val; int r; r = ioprio_parse_priority
(eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 111, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
112DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice)static int bus_append_parse_nice( sd_bus_message *m, const char
*field, const char *eq) { int val; int r; r = parse_nice(eq,
&val); if (r < 0) return ({ int _level = ((3)), _e = (
(r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(
_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm
) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 112, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
113DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi)static int bus_append_safe_atoi( sd_bus_message *m, const char
*field, const char *eq) { int val; int r; r = safe_atoi(eq, &
val); if (r < 0) return ({ int _level = ((3)), _e = ((r)),
_realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm
) >= ((_level) & 0x07)) ? log_internal_realm(((_realm)
<< 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 113, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
114DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec)static int bus_append_parse_nsec( sd_bus_message *m, const char
*field, const char *eq) { nsec_t val; int r; r = parse_nsec(
eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 114, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
115DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse)static int bus_append_cg_blkio_weight_parse( sd_bus_message *
m, const char *field, const char *eq) { uint64_t val; int r; r
= cg_blkio_weight_parse(eq, &val); if (r < 0) return (
{ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 115, __func__, "Failed to parse %s=%s: %m"
, field, eq) : -abs(_e); }); r = sd_bus_message_append(m, "(sv)"
, field, "t", (uint64_t) val); if (r < 0) return bus_log_create_error
(r); return 1; }
;
116DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse)static int bus_append_cg_cpu_shares_parse( sd_bus_message *m,
const char *field, const char *eq) { uint64_t val; int r; r =
cg_cpu_shares_parse(eq, &val); if (r < 0) return ({ int
_level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 116, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
117DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse)static int bus_append_cg_weight_parse( sd_bus_message *m, const
char *field, const char *eq) { uint64_t val; int r; r = cg_weight_parse
(eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 117, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
118DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string)static int bus_append_mount_propagation_flags_from_string( sd_bus_message
*m, const char *field, const char *eq) { unsigned long val; int
r; r = mount_propagation_flags_from_string(eq, &val); if
(r < 0) return ({ int _level = ((3)), _e = ((r)), _realm =
(LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= (
(_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/shared/bus-unit-util.c", 118, __func__
, "Failed to parse %s=%s: %m", field, eq) : -abs(_e); }); r =
sd_bus_message_append(m, "(sv)", field, "t", (uint64_t) val)
; if (r < 0) return bus_log_create_error(r); return 1; }
;
119DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64)static int bus_append_safe_atou64( sd_bus_message *m, const char
*field, const char *eq) { uint64_t val; int r; r = safe_atou64
(eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 119, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
120DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode)static int bus_append_parse_mode( sd_bus_message *m, const char
*field, const char *eq) { mode_t val; int r; r = parse_mode(
eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 120, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "u", (uint32_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
121DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou)static int bus_append_safe_atou( sd_bus_message *m, const char
*field, const char *eq) { unsigned val; int r; r = safe_atou
(eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 121, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "u", (uint32_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
122DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64)static int bus_append_safe_atoi64( sd_bus_message *m, const char
*field, const char *eq) { int64_t val; int r; r = safe_atoi64
(eq, &val); if (r < 0) return ({ int _level = ((3)), _e
= ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm
(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((
_realm) << 10 | (_level)), _e, "../src/shared/bus-unit-util.c"
, 122, __func__, "Failed to parse %s=%s: %m", field, eq) : -abs
(_e); }); r = sd_bus_message_append(m, "(sv)", field, "x", (int64_t
) val); if (r < 0) return bus_log_create_error(r); return 1
; }
;
123
124static inline int bus_append_string(sd_bus_message *m, const char *field, const char *eq) {
125 int r;
126
127 r = sd_bus_message_append(m, "(sv)", field, "s", eq);
128 if (r < 0)
129 return bus_log_create_error(r);
130
131 return 1;
132}
133
134static int bus_append_strv(sd_bus_message *m, const char *field, const char *eq, ExtractFlags flags) {
135 const char *p;
136 int r;
137
138 r = sd_bus_message_open_container(m, 'r', "sv");
139 if (r < 0)
140 return bus_log_create_error(r);
141
142 r = sd_bus_message_append_basic(m, 's', field);
143 if (r < 0)
144 return bus_log_create_error(r);
145
146 r = sd_bus_message_open_container(m, 'v', "as");
147 if (r < 0)
148 return bus_log_create_error(r);
149
150 r = sd_bus_message_open_container(m, 'a', "s");
151 if (r < 0)
152 return bus_log_create_error(r);
153
154 for (p = eq;;) {
155 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
156
157 r = extract_first_word(&p, &word, NULL((void*)0), flags);
158 if (r == 0)
159 break;
160 if (r == -ENOMEM12)
161 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 161, __func__)
;
162 if (r < 0)
163 return log_error_errno(r, "Invalid syntax: %s", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 163, __func__, "Invalid syntax: %s"
, eq) : -abs(_e); })
;
164
165 r = sd_bus_message_append_basic(m, 's', word);
166 if (r < 0)
167 return bus_log_create_error(r);
168 }
169
170 r = sd_bus_message_close_container(m);
171 if (r < 0)
172 return bus_log_create_error(r);
173
174 r = sd_bus_message_close_container(m);
175 if (r < 0)
176 return bus_log_create_error(r);
177
178 r = sd_bus_message_close_container(m);
179 if (r < 0)
180 return bus_log_create_error(r);
181
182 return 1;
183}
184
185static int bus_append_byte_array(sd_bus_message *m, const char *field, const void *buf, size_t n) {
186 int r;
187
188 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
189 if (r < 0)
190 return bus_log_create_error(r);
191
192 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
193 if (r < 0)
194 return bus_log_create_error(r);
195
196 r = sd_bus_message_open_container(m, 'v', "ay");
197 if (r < 0)
198 return bus_log_create_error(r);
199
200 r = sd_bus_message_append_array(m, 'y', buf, n);
201 if (r < 0)
202 return bus_log_create_error(r);
203
204 r = sd_bus_message_close_container(m);
205 if (r < 0)
206 return bus_log_create_error(r);
207
208 r = sd_bus_message_close_container(m);
209 if (r < 0)
210 return bus_log_create_error(r);
211
212 return 1;
213}
214
215static int bus_append_parse_sec_rename(sd_bus_message *m, const char *field, const char *eq) {
216 char *n;
217 usec_t t;
218 size_t l;
219 int r;
220
221 r = parse_sec(eq, &t);
222 if (r < 0)
223 return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 223, __func__, "Failed to parse %s=%s: %m"
, field, eq) : -abs(_e); })
;
224
225 l = strlen(field);
226 n = newa(char, l + 2)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(char), l + 2))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("!size_multiply_overflow(sizeof(char), l + 2)"), "../src/shared/bus-unit-util.c"
, 226, __PRETTY_FUNCTION__); } while (0); (char*) __builtin_alloca
(sizeof(char)*(l + 2)); })
;
227 /* Change suffix Sec → USec */
228 strcpy(mempcpy(n, field, l - 3), "USec");
229
230 r = sd_bus_message_append(m, "(sv)", n, "t", t);
231 if (r < 0)
232 return bus_log_create_error(r);
233
234 return 1;
235}
236
237static int bus_append_parse_size(sd_bus_message *m, const char *field, const char *eq, uint64_t base) {
238 uint64_t v;
239 int r;
240
241 r = parse_size(eq, base, &v);
242 if (r < 0)
243 return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 243, __func__, "Failed to parse %s=%s: %m"
, field, eq) : -abs(_e); })
;
244
245 r = sd_bus_message_append(m, "(sv)", field, "t", v);
246 if (r < 0)
247 return bus_log_create_error(r);
248
249 return 1;
250}
251
252static int bus_append_exec_command(sd_bus_message *m, const char *field, const char *eq) {
253 bool_Bool ignore_failure = false0, explicit_path = false0, done = false0;
254 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
255 _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0);
256 int r;
257
258 do {
259 switch (*eq) {
260
261 case '-':
262 if (ignore_failure)
263 done = true1;
264 else {
265 ignore_failure = true1;
266 eq++;
267 }
268 break;
269
270 case '@':
271 if (explicit_path)
272 done = true1;
273 else {
274 explicit_path = true1;
275 eq++;
276 }
277 break;
278
279 case '+':
280 case '!':
281 /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */
282 log_error("Sorry, but +, ! and !! are currently not supported for transient services.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 282, __func__, "Sorry, but +, ! and !! are currently not supported for transient services."
) : -abs(_e); })
;
283 return -EOPNOTSUPP95;
284
285 default:
286 done = true1;
287 break;
288 }
289 } while (!done);
290
291 if (explicit_path) {
292 r = extract_first_word(&eq, &path, NULL((void*)0), EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
293 if (r < 0)
294 return log_error_errno(r, "Failed to parse path: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 294, __func__, "Failed to parse path: %m"
) : -abs(_e); })
;
295 }
296
297 r = strv_split_extract(&l, eq, NULL((void*)0), EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
298 if (r < 0)
299 return log_error_errno(r, "Failed to parse command line: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 299, __func__, "Failed to parse command line: %m"
) : -abs(_e); })
;
300
301 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
302 if (r < 0)
303 return bus_log_create_error(r);
304
305 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
306 if (r < 0)
307 return bus_log_create_error(r);
308
309 r = sd_bus_message_open_container(m, 'v', "a(sasb)");
310 if (r < 0)
311 return bus_log_create_error(r);
312
313 r = sd_bus_message_open_container(m, 'a', "(sasb)");
314 if (r < 0)
315 return bus_log_create_error(r);
316
317 if (!strv_isempty(l)) {
318
319 r = sd_bus_message_open_container(m, 'r', "sasb");
320 if (r < 0)
321 return bus_log_create_error(r);
322
323 r = sd_bus_message_append(m, "s", path ?: l[0]);
324 if (r < 0)
325 return bus_log_create_error(r);
326
327 r = sd_bus_message_append_strv(m, l);
328 if (r < 0)
329 return bus_log_create_error(r);
330
331 r = sd_bus_message_append(m, "b", ignore_failure);
332 if (r < 0)
333 return bus_log_create_error(r);
334
335 r = sd_bus_message_close_container(m);
336 if (r < 0)
337 return bus_log_create_error(r);
338 }
339
340 r = sd_bus_message_close_container(m);
341 if (r < 0)
342 return bus_log_create_error(r);
343
344 r = sd_bus_message_close_container(m);
345 if (r < 0)
346 return bus_log_create_error(r);
347
348 r = sd_bus_message_close_container(m);
349 if (r < 0)
350 return bus_log_create_error(r);
351
352 return 1;
353}
354
355static int bus_append_ip_address_access(sd_bus_message *m, int family, const union in_addr_union *prefix, unsigned char prefixlen) {
356 int r;
357
358 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/shared/bus-unit-util.c", 358
, __PRETTY_FUNCTION__); } while (0)
;
359 assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefix"), "../src/shared/bus-unit-util.c"
, 359, __PRETTY_FUNCTION__); } while (0)
;
360
361 r = sd_bus_message_open_container(m, 'r', "iayu");
362 if (r < 0)
363 return r;
364
365 r = sd_bus_message_append(m, "i", family);
366 if (r < 0)
367 return r;
368
369 r = sd_bus_message_append_array(m, 'y', prefix, FAMILY_ADDRESS_SIZE(family));
370 if (r < 0)
371 return r;
372
373 r = sd_bus_message_append(m, "u", prefixlen);
374 if (r < 0)
375 return r;
376
377 return sd_bus_message_close_container(m);
378}
379
380static int bus_append_cgroup_property(sd_bus_message *m, const char *field, const char *eq) {
381 int r;
382
383 if (STR_IN_SET(field, "DevicePolicy", "Slice")(!!strv_find((((char**) ((const char*[]) { "DevicePolicy", "Slice"
, ((void*)0) }))), (field)))
)
384
385 return bus_append_string(m, field, eq);
386
387 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "CPUAccounting", "MemoryAccounting"
, "IOAccounting", "BlockIOAccounting", "TasksAccounting", "IPAccounting"
, ((void*)0) }))), (field)))
388 "CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting",(!!strv_find((((char**) ((const char*[]) { "CPUAccounting", "MemoryAccounting"
, "IOAccounting", "BlockIOAccounting", "TasksAccounting", "IPAccounting"
, ((void*)0) }))), (field)))
389 "TasksAccounting", "IPAccounting")(!!strv_find((((char**) ((const char*[]) { "CPUAccounting", "MemoryAccounting"
, "IOAccounting", "BlockIOAccounting", "TasksAccounting", "IPAccounting"
, ((void*)0) }))), (field)))
)
390
391 return bus_append_parse_boolean(m, field, eq);
392
393 if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight")(!!strv_find((((char**) ((const char*[]) { "CPUWeight", "StartupCPUWeight"
, "IOWeight", "StartupIOWeight", ((void*)0) }))), (field)))
)
394
395 return bus_append_cg_weight_parse(m, field, eq);
396
397 if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")(!!strv_find((((char**) ((const char*[]) { "CPUShares", "StartupCPUShares"
, ((void*)0) }))), (field)))
)
398
399 return bus_append_cg_cpu_shares_parse(m, field, eq);
400
401 if (STR_IN_SET(field, "AllowedCPUs", "AllowedMemoryNodes")(!!strv_find((((char**) ((const char*[]) { "AllowedCPUs", "AllowedMemoryNodes"
, ((void*)0) }))), (field)))
) {
402 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet cpuset = {};
403 _cleanup_free___attribute__((cleanup(freep))) uint8_t *array = NULL((void*)0);
404 size_t allocated;
405
406 r = parse_cpu_set(eq, &cpuset);
407 if (r < 0)
408 return log_error_errno(r, "Failed to parse %s value: %s", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 408, __func__, "Failed to parse %s value: %s"
, field, eq) : -abs(_e); })
;
409
410 r = cpu_set_to_dbus(&cpuset, &array, &allocated);
411 if (r < 0)
412 return log_error_errno(r, "Failed to serialize CPUSet: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 412, __func__, "Failed to serialize CPUSet: %m"
) : -abs(_e); })
;
413
414 return bus_append_byte_array(m, field, array, allocated);
415 }
416
417 if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")(!!strv_find((((char**) ((const char*[]) { "BlockIOWeight", "StartupBlockIOWeight"
, ((void*)0) }))), (field)))
)
418
419 return bus_append_cg_blkio_weight_parse(m, field, eq);
420
421 if (streq(field, "Delegate")(strcmp((field),("Delegate")) == 0)) {
422
423 r = parse_boolean(eq);
424 if (r < 0)
425 return bus_append_strv(m, "DelegateControllers", eq, EXTRACT_QUOTES);
426
427 r = sd_bus_message_append(m, "(sv)", "Delegate", "b", r);
428 if (r < 0)
429 return bus_log_create_error(r);
430
431 return 1;
432 }
433
434 if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")(!!strv_find((((char**) ((const char*[]) { "MemoryMin", "DefaultMemoryLow"
, "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax",
"MemorySwapMax", "MemoryLimit", "TasksMax", ((void*)0) }))),
(field)))
) {
435
436 if (isempty(eq) || streq(eq, "infinity")(strcmp((eq),("infinity")) == 0)) {
437 r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX((uint64_t) -1));
438 if (r < 0)
439 return bus_log_create_error(r);
440 return 1;
441 }
442
443 r = parse_percent(eq);
444 if (r >= 0) {
445 char *n;
446
447 /* When this is a percentage we'll convert this into a relative value in the range
448 * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related
449 * ones). This way the physical memory size can be determined server-side */
450
451 n = strjoina(field, "Scale")({ const char *_appendees_[] = { field, "Scale" }; char *_d_,
*_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
452 r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX(4294967295U) * r) / 100U));
453 if (r < 0)
454 return bus_log_create_error(r);
455
456 return 1;
457 }
458
459 if (streq(field, "TasksMax")(strcmp((field),("TasksMax")) == 0))
460 return bus_append_safe_atou64(m, field, eq);
461
462 return bus_append_parse_size(m, field, eq, 1024);
463 }
464
465 if (streq(field, "CPUQuota")(strcmp((field),("CPUQuota")) == 0)) {
466
467 if (isempty(eq))
468 r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY((usec_t) -1));
469 else {
470 r = parse_percent_unbounded(eq);
471 if (r <= 0) {
472 log_error_errno(r, "CPU quota '%s' invalid.", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 472, __func__, "CPU quota '%s' invalid."
, eq) : -abs(_e); })
;
473 return -EINVAL22;
474 }
475
476 r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC((usec_t) 1000000ULL) / 100U);
477 }
478
479 if (r < 0)
480 return bus_log_create_error(r);
481
482 return 1;
483 }
484
485 if (streq(field, "CPUQuotaPeriodSec")(strcmp((field),("CPUQuotaPeriodSec")) == 0)) {
486 usec_t u = USEC_INFINITY((usec_t) -1);
487
488 r = parse_sec_def_infinity(eq, &u);
489 if (r < 0)
490 return log_error_errno(r, "CPU quota period '%s' invalid.", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 490, __func__, "CPU quota period '%s' invalid."
, eq) : -abs(_e); })
;
491
492 r = sd_bus_message_append(m, "(sv)", "CPUQuotaPeriodUSec", "t", u);
493 if (r < 0)
494 return bus_log_create_error(r);
495
496 return 1;
497 }
498
499 if (streq(field, "DeviceAllow")(strcmp((field),("DeviceAllow")) == 0)) {
500
501 if (isempty(eq))
502 r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 0);
503 else {
504 const char *path = eq, *rwm = NULL((void*)0), *e;
505
506 e = strchr(eq, ' ');
507 if (e) {
508 path = strndupa(eq, e - eq)(__extension__ ({ const char *__old = (eq); size_t __len = strnlen
(__old, (e - eq)); char *__new = (char *) __builtin_alloca (
__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
509 rwm = e+1;
510 }
511
512 r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 1, path, strempty(rwm));
513 }
514
515 if (r < 0)
516 return bus_log_create_error(r);
517
518 return 1;
519 }
520
521 if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")(!!strv_find((((char**) ((const char*[]) { "BlockIOReadBandwidth"
, "BlockIOWriteBandwidth", ((void*)0) }))), (field)))
) {
522
523 if (isempty(eq))
524 r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
525 else {
526 const char *path, *bandwidth, *e;
527 uint64_t bytes;
528
529 e = strchr(eq, ' ');
530 if (!e) {
531 log_error("Failed to parse %s value %s.", field, eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 531, __func__, "Failed to parse %s value %s."
, field, eq) : -abs(_e); })
;
532 return -EINVAL22;
533 }
534
535 path = strndupa(eq, e - eq)(__extension__ ({ const char *__old = (eq); size_t __len = strnlen
(__old, (e - eq)); char *__new = (char *) __builtin_alloca (
__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
536 bandwidth = e+1;
537
538 if (streq(bandwidth, "infinity")(strcmp((bandwidth),("infinity")) == 0)) {
539 bytes = CGROUP_LIMIT_MAX((uint64_t) -1);
540 } else {
541 r = parse_size(bandwidth, 1000, &bytes);
542 if (r < 0)
543 return log_error_errno(r, "Failed to parse byte value %s: %m", bandwidth)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 543, __func__, "Failed to parse byte value %s: %m"
, bandwidth) : -abs(_e); })
;
544 }
545
546 r = sd_bus_message_append(m, "(sv)", field, "a(st)", 1, path, bytes);
547 }
548
549 if (r < 0)
550 return bus_log_create_error(r);
551
552 return 1;
553 }
554
555 if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")(!!strv_find((((char**) ((const char*[]) { "IODeviceWeight", "BlockIODeviceWeight"
, ((void*)0) }))), (field)))
) {
556
557 if (isempty(eq))
558 r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
559 else {
560 const char *path, *weight, *e;
561 uint64_t u;
562
563 e = strchr(eq, ' ');
564 if (!e) {
565 log_error("Failed to parse %s value %s.", field, eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 565, __func__, "Failed to parse %s value %s."
, field, eq) : -abs(_e); })
;
566 return -EINVAL22;
567 }
568
569 path = strndupa(eq, e - eq)(__extension__ ({ const char *__old = (eq); size_t __len = strnlen
(__old, (e - eq)); char *__new = (char *) __builtin_alloca (
__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
570 weight = e+1;
571
572 r = safe_atou64(weight, &u);
573 if (r < 0)
574 return log_error_errno(r, "Failed to parse %s value %s: %m", field, weight)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 574, __func__, "Failed to parse %s value %s: %m"
, field, weight) : -abs(_e); })
;
575
576 r = sd_bus_message_append(m, "(sv)", field, "a(st)", 1, path, u);
577 }
578
579 if (r < 0)
580 return bus_log_create_error(r);
581
582 return 1;
583 }
584
585 if (streq(field, "IODeviceLatencyTargetSec")(strcmp((field),("IODeviceLatencyTargetSec")) == 0)) {
586 const char *field_usec = "IODeviceLatencyTargetUSec";
587
588 if (isempty(eq))
589 r = sd_bus_message_append(m, "(sv)", field_usec, "a(st)", USEC_INFINITY((usec_t) -1));
590 else {
591 const char *path, *target, *e;
592 usec_t usec;
593
594 e = strchr(eq, ' ');
595 if (!e) {
596 log_error("Failed to parse %s value %s.", field, eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 596, __func__, "Failed to parse %s value %s."
, field, eq) : -abs(_e); })
;
597 return -EINVAL22;
598 }
599
600 path = strndupa(eq, e - eq)(__extension__ ({ const char *__old = (eq); size_t __len = strnlen
(__old, (e - eq)); char *__new = (char *) __builtin_alloca (
__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
601 target = e+1;
602
603 r = parse_sec(target, &usec);
604 if (r < 0)
605 return log_error_errno(r, "Failed to parse %s value %s: %m", field, target)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 605, __func__, "Failed to parse %s value %s: %m"
, field, target) : -abs(_e); })
;
606
607 r = sd_bus_message_append(m, "(sv)", field_usec, "a(st)", 1, path, usec);
608 }
609
610 if (r < 0)
611 return bus_log_create_error(r);
612
613 return 1;
614 }
615
616 if (STR_IN_SET(field, "IPAddressAllow", "IPAddressDeny")(!!strv_find((((char**) ((const char*[]) { "IPAddressAllow", "IPAddressDeny"
, ((void*)0) }))), (field)))
) {
617 unsigned char prefixlen;
618 union in_addr_union prefix = {};
619 int family;
620
621 if (isempty(eq)) {
622 r = sd_bus_message_append(m, "(sv)", field, "a(iayu)", 0);
623 if (r < 0)
624 return bus_log_create_error(r);
625
626 return 1;
627 }
628
629 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
630 if (r < 0)
631 return bus_log_create_error(r);
632
633 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
634 if (r < 0)
635 return bus_log_create_error(r);
636
637 r = sd_bus_message_open_container(m, 'v', "a(iayu)");
638 if (r < 0)
639 return bus_log_create_error(r);
640
641 r = sd_bus_message_open_container(m, 'a', "(iayu)");
642 if (r < 0)
643 return bus_log_create_error(r);
644
645 if (streq(eq, "any")(strcmp((eq),("any")) == 0)) {
646 /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */
647
648 r = bus_append_ip_address_access(m, AF_INET2, &prefix, 0);
649 if (r < 0)
650 return bus_log_create_error(r);
651
652 r = bus_append_ip_address_access(m, AF_INET610, &prefix, 0);
653 if (r < 0)
654 return bus_log_create_error(r);
655
656 } else if (is_localhost(eq)) {
657 /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */
658
659 prefix.in.s_addr = htobe32(0x7f000000)__bswap_32 (0x7f000000);
660 r = bus_append_ip_address_access(m, AF_INET2, &prefix, 8);
661 if (r < 0)
662 return bus_log_create_error(r);
663
664 prefix.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } };
665 r = bus_append_ip_address_access(m, AF_INET610, &prefix, 128);
666 if (r < 0)
667 return r;
668
669 } else if (streq(eq, "link-local")(strcmp((eq),("link-local")) == 0)) {
670 /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */
671
672 prefix.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16))__bswap_32 ((169U << 24 | 254U << 16));
673 r = bus_append_ip_address_access(m, AF_INET2, &prefix, 16);
674 if (r < 0)
675 return bus_log_create_error(r);
676
677 prefix.in6 = (struct in6_addr) {
678 .s6_addr32__in6_u.__u6_addr32[0] = htobe32(0xfe800000)__bswap_32 (0xfe800000)
679 };
680 r = bus_append_ip_address_access(m, AF_INET610, &prefix, 64);
681 if (r < 0)
682 return bus_log_create_error(r);
683
684 } else if (streq(eq, "multicast")(strcmp((eq),("multicast")) == 0)) {
685 /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */
686
687 prefix.in.s_addr = htobe32((UINT32_C(224) << 24))__bswap_32 ((224U << 24));
688 r = bus_append_ip_address_access(m, AF_INET2, &prefix, 4);
689 if (r < 0)
690 return bus_log_create_error(r);
691
692 prefix.in6 = (struct in6_addr) {
693 .s6_addr32__in6_u.__u6_addr32[0] = htobe32(0xff000000)__bswap_32 (0xff000000)
694 };
695 r = bus_append_ip_address_access(m, AF_INET610, &prefix, 8);
696 if (r < 0)
697 return bus_log_create_error(r);
698
699 } else {
700 r = in_addr_prefix_from_string_auto(eq, &family, &prefix, &prefixlen);
701 if (r < 0)
702 return log_error_errno(r, "Failed to parse IP address prefix: %s", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 702, __func__, "Failed to parse IP address prefix: %s"
, eq) : -abs(_e); })
;
703
704 r = bus_append_ip_address_access(m, family, &prefix, prefixlen);
705 if (r < 0)
706 return bus_log_create_error(r);
707 }
708
709 r = sd_bus_message_close_container(m);
710 if (r < 0)
711 return bus_log_create_error(r);
712
713 r = sd_bus_message_close_container(m);
714 if (r < 0)
715 return bus_log_create_error(r);
716
717 r = sd_bus_message_close_container(m);
718 if (r < 0)
719 return bus_log_create_error(r);
720
721 return 1;
722 }
723
724 return 0;
725}
726
727static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) {
728
729 if (streq(field, "Where")(strcmp((field),("Where")) == 0))
730
731 return bus_append_string(m, field, eq);
732
733 if (streq(field, "DirectoryMode")(strcmp((field),("DirectoryMode")) == 0))
734
735 return bus_append_parse_mode(m, field, eq);
736
737 if (streq(field, "TimeoutIdleSec")(strcmp((field),("TimeoutIdleSec")) == 0))
738
739 return bus_append_parse_sec_rename(m, field, eq);
740
741 return 0;
742}
743
744static int bus_append_execute_property(sd_bus_message *m, const char *field, const char *eq) {
745 const char *suffix;
746 int r;
747
748 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
749 "User", "Group",(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
750 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
751 "WorkingDirectory", "RootDirectory", "SyslogIdentifier",(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
752 "ProtectSystem", "ProtectHome", "SELinuxContext", "RootImage",(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
753 "RuntimeDirectoryPreserve", "Personality", "KeyringMode")(!!strv_find((((char**) ((const char*[]) { "User", "Group", "UtmpIdentifier"
, "UtmpMode", "PAMName", "TTYPath", "WorkingDirectory", "RootDirectory"
, "SyslogIdentifier", "ProtectSystem", "ProtectHome", "SELinuxContext"
, "RootImage", "RuntimeDirectoryPreserve", "Personality", "KeyringMode"
, ((void*)0) }))), (field)))
)
754
755 return bus_append_string(m, field, eq);
756
757 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
758 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
759 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
760 "PrivateMounts", "NoNewPrivileges", "SyslogLevelPrefix",(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
761 "MemoryDenyWriteExecute", "RestrictRealtime", "DynamicUser", "RemoveIPC",(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
762 "ProtectKernelTunables", "ProtectKernelModules", "ProtectControlGroups",(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
763 "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality" "RestrictSUIDSGID")(!!strv_find((((char**) ((const char*[]) { "IgnoreSIGPIPE", "TTYVHangup"
, "TTYReset", "TTYVTDisallocate", "PrivateTmp", "PrivateDevices"
, "PrivateNetwork", "PrivateUsers", "PrivateMounts", "NoNewPrivileges"
, "SyslogLevelPrefix", "MemoryDenyWriteExecute", "RestrictRealtime"
, "DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules"
, "ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork"
, "LockPersonality" "RestrictSUIDSGID", ((void*)0) }))), (field
)))
)
764
765 return bus_append_parse_boolean(m, field, eq);
766
767 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "ReadWriteDirectories"
, "ReadOnlyDirectories", "InaccessibleDirectories", "ReadWritePaths"
, "ReadOnlyPaths", "InaccessiblePaths", "RuntimeDirectory", "StateDirectory"
, "CacheDirectory", "LogsDirectory", "ConfigurationDirectory"
, "SupplementaryGroups", "SystemCallArchitectures", ((void*)0
) }))), (field)))
768 "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",(!!strv_find((((char**) ((const char*[]) { "ReadWriteDirectories"
, "ReadOnlyDirectories", "InaccessibleDirectories", "ReadWritePaths"
, "ReadOnlyPaths", "InaccessiblePaths", "RuntimeDirectory", "StateDirectory"
, "CacheDirectory", "LogsDirectory", "ConfigurationDirectory"
, "SupplementaryGroups", "SystemCallArchitectures", ((void*)0
) }))), (field)))
769 "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths",(!!strv_find((((char**) ((const char*[]) { "ReadWriteDirectories"
, "ReadOnlyDirectories", "InaccessibleDirectories", "ReadWritePaths"
, "ReadOnlyPaths", "InaccessiblePaths", "RuntimeDirectory", "StateDirectory"
, "CacheDirectory", "LogsDirectory", "ConfigurationDirectory"
, "SupplementaryGroups", "SystemCallArchitectures", ((void*)0
) }))), (field)))
770 "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory",(!!strv_find((((char**) ((const char*[]) { "ReadWriteDirectories"
, "ReadOnlyDirectories", "InaccessibleDirectories", "ReadWritePaths"
, "ReadOnlyPaths", "InaccessiblePaths", "RuntimeDirectory", "StateDirectory"
, "CacheDirectory", "LogsDirectory", "ConfigurationDirectory"
, "SupplementaryGroups", "SystemCallArchitectures", ((void*)0
) }))), (field)))
771 "SupplementaryGroups", "SystemCallArchitectures")(!!strv_find((((char**) ((const char*[]) { "ReadWriteDirectories"
, "ReadOnlyDirectories", "InaccessibleDirectories", "ReadWritePaths"
, "ReadOnlyPaths", "InaccessiblePaths", "RuntimeDirectory", "StateDirectory"
, "CacheDirectory", "LogsDirectory", "ConfigurationDirectory"
, "SupplementaryGroups", "SystemCallArchitectures", ((void*)0
) }))), (field)))
)
772
773 return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
774
775 if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax")(!!strv_find((((char**) ((const char*[]) { "SyslogLevel", "LogLevelMax"
, ((void*)0) }))), (field)))
)
776
777 return bus_append_log_level_from_string(m, field, eq);
778
779 if (streq(field, "SyslogFacility")(strcmp((field),("SyslogFacility")) == 0))
780
781 return bus_append_log_facility_unshifted_from_string(m, field, eq);
782
783 if (streq(field, "SecureBits")(strcmp((field),("SecureBits")) == 0))
784
785 return bus_append_secure_bits_from_string(m, field, eq);
786
787 if (streq(field, "CPUSchedulingPolicy")(strcmp((field),("CPUSchedulingPolicy")) == 0))
788
789 return bus_append_sched_policy_from_string(m, field, eq);
790
791 if (STR_IN_SET(field, "CPUSchedulingPriority", "OOMScoreAdjust")(!!strv_find((((char**) ((const char*[]) { "CPUSchedulingPriority"
, "OOMScoreAdjust", ((void*)0) }))), (field)))
)
792
793 return bus_append_safe_atoi(m, field, eq);
794
795 if (streq(field, "Nice")(strcmp((field),("Nice")) == 0))
796
797 return bus_append_parse_nice(m, field, eq);
798
799 if (streq(field, "SystemCallErrorNumber")(strcmp((field),("SystemCallErrorNumber")) == 0))
800
801 return bus_append_parse_errno(m, field, eq);
802
803 if (streq(field, "IOSchedulingClass")(strcmp((field),("IOSchedulingClass")) == 0))
804
805 return bus_append_ioprio_class_from_string(m, field, eq);
806
807 if (streq(field, "IOSchedulingPriority")(strcmp((field),("IOSchedulingPriority")) == 0))
808
809 return bus_append_ioprio_parse_priority(m, field, eq);
810
811 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "RuntimeDirectoryMode"
, "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode"
, "ConfigurationDirectoryMode", "UMask", ((void*)0) }))), (field
)))
812 "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode",(!!strv_find((((char**) ((const char*[]) { "RuntimeDirectoryMode"
, "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode"
, "ConfigurationDirectoryMode", "UMask", ((void*)0) }))), (field
)))
813 "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")(!!strv_find((((char**) ((const char*[]) { "RuntimeDirectoryMode"
, "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode"
, "ConfigurationDirectoryMode", "UMask", ((void*)0) }))), (field
)))
)
814
815 return bus_append_parse_mode(m, field, eq);
816
817 if (streq(field, "TimerSlackNSec")(strcmp((field),("TimerSlackNSec")) == 0))
818
819 return bus_append_parse_nsec(m, field, eq);
820
821 if (STR_IN_SET(field, "LogRateLimitIntervalSec")(!!strv_find((((char**) ((const char*[]) { "LogRateLimitIntervalSec"
, ((void*)0) }))), (field)))
)
822
823 return bus_append_parse_sec_rename(m, field, eq);
824
825 if (streq(field, "LogRateLimitBurst")(strcmp((field),("LogRateLimitBurst")) == 0))
826
827 return bus_append_safe_atou(m, field, eq);
828
829 if (streq(field, "MountFlags")(strcmp((field),("MountFlags")) == 0))
830
831 return bus_append_mount_propagation_flags_from_string(m, field, eq);
832
833 if (STR_IN_SET(field, "Environment", "UnsetEnvironment", "PassEnvironment")(!!strv_find((((char**) ((const char*[]) { "Environment", "UnsetEnvironment"
, "PassEnvironment", ((void*)0) }))), (field)))
)
834
835 return bus_append_strv(m, field, eq, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
836
837 if (streq(field, "EnvironmentFile")(strcmp((field),("EnvironmentFile")) == 0)) {
838
839 if (isempty(eq))
840 r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 0);
841 else
842 r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 1,
843 eq[0] == '-' ? eq + 1 : eq,
844 eq[0] == '-');
845 if (r < 0)
846 return bus_log_create_error(r);
847
848 return 1;
849 }
850
851 if (streq(field, "LogExtraFields")(strcmp((field),("LogExtraFields")) == 0)) {
852
853 r = sd_bus_message_open_container(m, 'r', "sv");
854 if (r < 0)
855 return bus_log_create_error(r);
856
857 r = sd_bus_message_append_basic(m, 's', "LogExtraFields");
858 if (r < 0)
859 return bus_log_create_error(r);
860
861 r = sd_bus_message_open_container(m, 'v', "aay");
862 if (r < 0)
863 return bus_log_create_error(r);
864
865 r = sd_bus_message_open_container(m, 'a', "ay");
866 if (r < 0)
867 return bus_log_create_error(r);
868
869 r = sd_bus_message_append_array(m, 'y', eq, strlen(eq));
870 if (r < 0)
871 return bus_log_create_error(r);
872
873 r = sd_bus_message_close_container(m);
874 if (r < 0)
875 return bus_log_create_error(r);
876
877 r = sd_bus_message_close_container(m);
878 if (r < 0)
879 return bus_log_create_error(r);
880
881 r = sd_bus_message_close_container(m);
882 if (r < 0)
883 return bus_log_create_error(r);
884
885 return 1;
886 }
887
888 if (STR_IN_SET(field, "StandardInput", "StandardOutput", "StandardError")(!!strv_find((((char**) ((const char*[]) { "StandardInput", "StandardOutput"
, "StandardError", ((void*)0) }))), (field)))
) {
889 const char *n, *appended;
890
891 if ((n = startswith(eq, "fd:"))) {
892 appended = strjoina(field, "FileDescriptorName")({ const char *_appendees_[] = { field, "FileDescriptorName" }
; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0
; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
893 r = sd_bus_message_append(m, "(sv)", appended, "s", n);
894 } else if ((n = startswith(eq, "file:"))) {
895 appended = strjoina(field, "File")({ const char *_appendees_[] = { field, "File" }; char *_d_, *
_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
896 r = sd_bus_message_append(m, "(sv)", appended, "s", n);
897 } else
898 r = sd_bus_message_append(m, "(sv)", field, "s", eq);
899
900 if (r < 0)
901 return bus_log_create_error(r);
902
903 return 1;
904 }
905
906 if (streq(field, "StandardInputText")(strcmp((field),("StandardInputText")) == 0)) {
907 _cleanup_free___attribute__((cleanup(freep))) char *unescaped = NULL((void*)0);
908
909 r = cunescape(eq, 0, &unescaped);
910 if (r < 0)
911 return log_error_errno(r, "Failed to unescape text '%s': %m", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 911, __func__, "Failed to unescape text '%s': %m"
, eq) : -abs(_e); })
;
912
913 if (!strextend(&unescaped, "\n", NULL)strextend_with_separator(&unescaped, ((void*)0), "\n", ((
void*)0))
)
914 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 914, __func__)
;
915
916 /* Note that we don't expand specifiers here, but that should be OK, as this is a programmatic
917 * interface anyway */
918
919 return bus_append_byte_array(m, field, unescaped, strlen(unescaped));
920 }
921
922 if (streq(field, "StandardInputData")(strcmp((field),("StandardInputData")) == 0)) {
923 _cleanup_free___attribute__((cleanup(freep))) void *decoded = NULL((void*)0);
924 size_t sz;
925
926 r = unbase64mem(eq, (size_t) -1, &decoded, &sz);
927 if (r < 0)
928 return log_error_errno(r, "Failed to decode base64 data '%s': %m", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 928, __func__, "Failed to decode base64 data '%s': %m"
, eq) : -abs(_e); })
;
929
930 return bus_append_byte_array(m, field, decoded, sz);
931 }
932
933 if ((suffix = startswith(field, "Limit"))) {
934 int rl;
935
936 rl = rlimit_from_string(suffix);
937 if (rl >= 0) {
938 const char *sn;
939 struct rlimit l;
940
941 r = rlimit_parse(rl, eq, &l);
942 if (r < 0)
943 return log_error_errno(r, "Failed to parse resource limit: %s", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 943, __func__, "Failed to parse resource limit: %s"
, eq) : -abs(_e); })
;
944
945 r = sd_bus_message_append(m, "(sv)", field, "t", l.rlim_max);
946 if (r < 0)
947 return bus_log_create_error(r);
948
949 sn = strjoina(field, "Soft")({ const char *_appendees_[] = { field, "Soft" }; char *_d_, *
_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
950 r = sd_bus_message_append(m, "(sv)", sn, "t", l.rlim_cur);
951 if (r < 0)
952 return bus_log_create_error(r);
953
954 return 1;
955 }
956 }
957
958 if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")(!!strv_find((((char**) ((const char*[]) { "AppArmorProfile",
"SmackProcessLabel", ((void*)0) }))), (field)))
) {
959 int ignore = 0;
960 const char *s = eq;
961
962 if (eq[0] == '-') {
963 ignore = 1;
964 s = eq + 1;
965 }
966
967 r = sd_bus_message_append(m, "(sv)", field, "(bs)", ignore, s);
968 if (r < 0)
969 return bus_log_create_error(r);
970
971 return 1;
972 }
973
974 if (STR_IN_SET(field, "CapabilityBoundingSet", "AmbientCapabilities")(!!strv_find((((char**) ((const char*[]) { "CapabilityBoundingSet"
, "AmbientCapabilities", ((void*)0) }))), (field)))
) {
975 uint64_t sum = 0;
976 bool_Bool invert = false0;
977 const char *p = eq;
978
979 if (*p == '~') {
980 invert = true1;
981 p++;
982 }
983
984 r = capability_set_from_string(p, &sum);
985 if (r < 0)
986 return log_error_errno(r, "Failed to parse %s value %s: %m", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 986, __func__, "Failed to parse %s value %s: %m"
, field, eq) : -abs(_e); })
;
987
988 sum = invert ? ~sum : sum;
989
990 r = sd_bus_message_append(m, "(sv)", field, "t", sum);
991 if (r < 0)
992 return bus_log_create_error(r);
993
994 return 1;
995 }
996
997 if (streq(field, "CPUAffinity")(strcmp((field),("CPUAffinity")) == 0)) {
998 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet cpuset = {};
999 _cleanup_free___attribute__((cleanup(freep))) uint8_t *array = NULL((void*)0);
1000 size_t allocated;
1001
1002 if (eq && streq(eq, "numa")(strcmp((eq),("numa")) == 0)) {
1003 r = sd_bus_message_append(m, "(sv)", "CPUAffinityFromNUMA", "b", true1);
1004 if (r < 0)
1005 return bus_log_create_error(r);
1006 return r;
1007 }
1008
1009 r = parse_cpu_set(eq, &cpuset);
1010 if (r < 0)
1011 return log_error_errno(r, "Failed to parse %s value: %s", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1011, __func__, "Failed to parse %s value: %s"
, field, eq) : -abs(_e); })
;
1012
1013 r = cpu_set_to_dbus(&cpuset, &array, &allocated);
1014 if (r < 0)
1015 return log_error_errno(r, "Failed to serialize CPUAffinity: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1015, __func__, "Failed to serialize CPUAffinity: %m"
) : -abs(_e); })
;
1016
1017 return bus_append_byte_array(m, field, array, allocated);
1018 }
1019
1020 if (streq(field, "NUMAPolicy")(strcmp((field),("NUMAPolicy")) == 0)) {
1021 r = mpol_from_string(eq);
1022 if (r < 0)
1023 return log_error_errno(r, "Failed to parse %s value: %s", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1023, __func__, "Failed to parse %s value: %s"
, field, eq) : -abs(_e); })
;
1024
1025 r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t) r);
1026 if (r < 0)
1027 return bus_log_create_error(r);
1028
1029 return 1;
1030 }
1031
1032 if (streq(field, "NUMAMask")(strcmp((field),("NUMAMask")) == 0)) {
1033 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet nodes = {};
1034 _cleanup_free___attribute__((cleanup(freep))) uint8_t *array = NULL((void*)0);
1035 size_t allocated;
1036
1037 r = parse_cpu_set(eq, &nodes);
1038 if (r < 0)
1039 return log_error_errno(r, "Failed to parse %s value: %s", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1039, __func__, "Failed to parse %s value: %s"
, field, eq) : -abs(_e); })
;
1040
1041 r = cpu_set_to_dbus(&nodes, &array, &allocated);
1042 if (r < 0)
1043 return log_error_errno(r, "Failed to serialize NUMAMask: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1043, __func__, "Failed to serialize NUMAMask: %m"
) : -abs(_e); })
;
1044
1045 return bus_append_byte_array(m, field, array, allocated);
1046 }
1047
1048 if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")(!!strv_find((((char**) ((const char*[]) { "RestrictAddressFamilies"
, "SystemCallFilter", ((void*)0) }))), (field)))
) {
1049 int whitelist = 1;
1050 const char *p = eq;
1051
1052 if (*p == '~') {
1053 whitelist = 0;
1054 p++;
1055 }
1056
1057 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
1058 if (r < 0)
1059 return bus_log_create_error(r);
1060
1061 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1062 if (r < 0)
1063 return bus_log_create_error(r);
1064
1065 r = sd_bus_message_open_container(m, 'v', "(bas)");
1066 if (r < 0)
1067 return bus_log_create_error(r);
1068
1069 r = sd_bus_message_open_container(m, 'r', "bas");
1070 if (r < 0)
1071 return bus_log_create_error(r);
1072
1073 r = sd_bus_message_append_basic(m, 'b', &whitelist);
1074 if (r < 0)
1075 return bus_log_create_error(r);
1076
1077 r = sd_bus_message_open_container(m, 'a', "s");
1078 if (r < 0)
1079 return bus_log_create_error(r);
1080
1081 for (;;) {
1082 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
1083
1084 r = extract_first_word(&p, &word, NULL((void*)0), EXTRACT_QUOTES);
1085 if (r == 0)
1086 break;
1087 if (r == -ENOMEM12)
1088 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 1088, __func__)
;
1089 if (r < 0)
1090 return log_error_errno(r, "Invalid syntax: %s", eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1090, __func__, "Invalid syntax: %s"
, eq) : -abs(_e); })
;
1091
1092 r = sd_bus_message_append_basic(m, 's', word);
1093 if (r < 0)
1094 return bus_log_create_error(r);
1095 }
1096
1097 r = sd_bus_message_close_container(m);
1098 if (r < 0)
1099 return bus_log_create_error(r);
1100
1101 r = sd_bus_message_close_container(m);
1102 if (r < 0)
1103 return bus_log_create_error(r);
1104
1105 r = sd_bus_message_close_container(m);
1106 if (r < 0)
1107 return bus_log_create_error(r);
1108
1109 r = sd_bus_message_close_container(m);
1110 if (r < 0)
1111 return bus_log_create_error(r);
1112
1113 return 1;
1114 }
1115
1116 if (streq(field, "RestrictNamespaces")(strcmp((field),("RestrictNamespaces")) == 0)) {
1117 bool_Bool invert = false0;
1118 unsigned long flags;
1119
1120 r = parse_boolean(eq);
1121 if (r > 0)
1122 flags = 0;
1123 else if (r == 0)
1124 flags = NAMESPACE_FLAGS_ALL((unsigned long) (0x02000000| 0x08000000| 0x40000000| 0x00020000
| 0x20000000| 0x10000000| 0x04000000))
;
1125 else {
1126 if (eq[0] == '~') {
1127 invert = true1;
1128 eq++;
1129 }
1130
1131 r = namespace_flags_from_string(eq, &flags);
1132 if (r < 0)
1133 return log_error_errno(r, "Failed to parse %s value %s.", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1133, __func__, "Failed to parse %s value %s."
, field, eq) : -abs(_e); })
;
1134 }
1135
1136 if (invert)
1137 flags = (~flags) & NAMESPACE_FLAGS_ALL((unsigned long) (0x02000000| 0x08000000| 0x40000000| 0x00020000
| 0x20000000| 0x10000000| 0x04000000))
;
1138
1139 r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t) flags);
1140 if (r < 0)
1141 return bus_log_create_error(r);
1142
1143 return 1;
1144 }
1145
1146 if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")(!!strv_find((((char**) ((const char*[]) { "BindPaths", "BindReadOnlyPaths"
, ((void*)0) }))), (field)))
) {
1147 const char *p = eq;
1148
1149 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
1150 if (r < 0)
1151 return bus_log_create_error(r);
1152
1153 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1154 if (r < 0)
1155 return bus_log_create_error(r);
1156
1157 r = sd_bus_message_open_container(m, 'v', "a(ssbt)");
1158 if (r < 0)
1159 return bus_log_create_error(r);
1160
1161 r = sd_bus_message_open_container(m, 'a', "(ssbt)");
1162 if (r < 0)
1163 return bus_log_create_error(r);
1164
1165 for (;;) {
1166 _cleanup_free___attribute__((cleanup(freep))) char *source = NULL((void*)0), *destination = NULL((void*)0);
1167 char *s = NULL((void*)0), *d = NULL((void*)0);
1168 bool_Bool ignore_enoent = false0;
1169 uint64_t flags = MS_REC16384;
1170
1171 r = extract_first_word(&p, &source, ":" WHITESPACE" \t\n\r", EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
1172 if (r < 0)
1173 return log_error_errno(r, "Failed to parse argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1173, __func__, "Failed to parse argument: %m"
) : -abs(_e); })
;
1174 if (r == 0)
1175 break;
1176
1177 s = source;
1178 if (s[0] == '-') {
1179 ignore_enoent = true1;
1180 s++;
1181 }
1182
1183 if (p && p[-1] == ':') {
1184 r = extract_first_word(&p, &destination, ":" WHITESPACE" \t\n\r", EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
1185 if (r < 0)
1186 return log_error_errno(r, "Failed to parse argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1186, __func__, "Failed to parse argument: %m"
) : -abs(_e); })
;
1187 if (r == 0) {
1188 log_error("Missing argument after ':': %s", eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1188, __func__, "Missing argument after ':': %s"
, eq) : -abs(_e); })
;
1189 return -EINVAL22;
1190 }
1191
1192 d = destination;
1193
1194 if (p && p[-1] == ':') {
1195 _cleanup_free___attribute__((cleanup(freep))) char *options = NULL((void*)0);
1196
1197 r = extract_first_word(&p, &options, NULL((void*)0), EXTRACT_QUOTES);
1198 if (r < 0)
1199 return log_error_errno(r, "Failed to parse argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1199, __func__, "Failed to parse argument: %m"
) : -abs(_e); })
;
1200
1201 if (isempty(options) || streq(options, "rbind")(strcmp((options),("rbind")) == 0))
1202 flags = MS_REC16384;
1203 else if (streq(options, "norbind")(strcmp((options),("norbind")) == 0))
1204 flags = 0;
1205 else {
1206 log_error("Unknown options: %s", eq)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1206, __func__, "Unknown options: %s"
, eq) : -abs(_e); })
;
1207 return -EINVAL22;
1208 }
1209 }
1210 } else
1211 d = s;
1212
1213 r = sd_bus_message_append(m, "(ssbt)", s, d, ignore_enoent, flags);
1214 if (r < 0)
1215 return bus_log_create_error(r);
1216 }
1217
1218 r = sd_bus_message_close_container(m);
1219 if (r < 0)
1220 return bus_log_create_error(r);
1221
1222 r = sd_bus_message_close_container(m);
1223 if (r < 0)
1224 return bus_log_create_error(r);
1225
1226 r = sd_bus_message_close_container(m);
1227 if (r < 0)
1228 return bus_log_create_error(r);
1229
1230 return 1;
1231 }
1232
1233 if (streq(field, "TemporaryFileSystem")(strcmp((field),("TemporaryFileSystem")) == 0)) {
1234 const char *p = eq;
1235
1236 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
1237 if (r < 0)
1238 return bus_log_create_error(r);
1239
1240 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1241 if (r < 0)
1242 return bus_log_create_error(r);
1243
1244 r = sd_bus_message_open_container(m, 'v', "a(ss)");
1245 if (r < 0)
1246 return bus_log_create_error(r);
1247
1248 r = sd_bus_message_open_container(m, 'a', "(ss)");
1249 if (r < 0)
1250 return bus_log_create_error(r);
1251
1252 for (;;) {
1253 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0), *path = NULL((void*)0);
1254 const char *w;
1255
1256 r = extract_first_word(&p, &word, NULL((void*)0), EXTRACT_QUOTES);
1257 if (r < 0)
1258 return log_error_errno(r, "Failed to parse argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1258, __func__, "Failed to parse argument: %m"
) : -abs(_e); })
;
1259 if (r == 0)
1260 break;
1261
1262 w = word;
1263 r = extract_first_word(&w, &path, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
1264 if (r < 0)
1265 return log_error_errno(r, "Failed to parse argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1265, __func__, "Failed to parse argument: %m"
) : -abs(_e); })
;
1266 if (r == 0) {
1267 log_error("Failed to parse argument: %s", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1267, __func__, "Failed to parse argument: %s"
, p) : -abs(_e); })
;
1268 return -EINVAL22;
1269 }
1270
1271 r = sd_bus_message_append(m, "(ss)", path, w);
1272 if (r < 0)
1273 return bus_log_create_error(r);
1274 }
1275
1276 r = sd_bus_message_close_container(m);
1277 if (r < 0)
1278 return bus_log_create_error(r);
1279
1280 r = sd_bus_message_close_container(m);
1281 if (r < 0)
1282 return bus_log_create_error(r);
1283
1284 r = sd_bus_message_close_container(m);
1285 if (r < 0)
1286 return bus_log_create_error(r);
1287
1288 return 1;
1289 }
1290
1291 return 0;
1292}
1293
1294static int bus_append_kill_property(sd_bus_message *m, const char *field, const char *eq) {
1295
1296 if (streq(field, "KillMode")(strcmp((field),("KillMode")) == 0))
1297
1298 return bus_append_string(m, field, eq);
1299
1300 if (STR_IN_SET(field, "SendSIGHUP", "SendSIGKILL")(!!strv_find((((char**) ((const char*[]) { "SendSIGHUP", "SendSIGKILL"
, ((void*)0) }))), (field)))
)
1301
1302 return bus_append_parse_boolean(m, field, eq);
1303
1304 if (streq(field, "KillSignal")(strcmp((field),("KillSignal")) == 0))
1305
1306 return bus_append_signal_from_string(m, field, eq);
1307
1308 return 0;
1309}
1310
1311static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) {
1312
1313 if (STR_IN_SET(field, "What", "Where", "Options", "Type")(!!strv_find((((char**) ((const char*[]) { "What", "Where", "Options"
, "Type", ((void*)0) }))), (field)))
)
1314
1315 return bus_append_string(m, field, eq);
1316
1317 if (streq(field, "TimeoutSec")(strcmp((field),("TimeoutSec")) == 0))
1318
1319 return bus_append_parse_sec_rename(m, field, eq);
1320
1321 if (streq(field, "DirectoryMode")(strcmp((field),("DirectoryMode")) == 0))
1322
1323 return bus_append_parse_mode(m, field, eq);
1324
1325 if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount")(!!strv_find((((char**) ((const char*[]) { "SloppyOptions", "LazyUnmount"
, "ForceUnmount", ((void*)0) }))), (field)))
)
1326
1327 return bus_append_parse_boolean(m, field, eq);
1328
1329 return 0;
1330}
1331
1332static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) {
1333 int r;
1334
1335 if (streq(field, "MakeDirectory")(strcmp((field),("MakeDirectory")) == 0))
1336
1337 return bus_append_parse_boolean(m, field, eq);
1338
1339 if (streq(field, "DirectoryMode")(strcmp((field),("DirectoryMode")) == 0))
1340
1341 return bus_append_parse_mode(m, field, eq);
1342
1343 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "PathExists", "PathExistsGlob"
, "PathChanged", "PathModified", "DirectoryNotEmpty", ((void*
)0) }))), (field)))
1344 "PathExists", "PathExistsGlob", "PathChanged",(!!strv_find((((char**) ((const char*[]) { "PathExists", "PathExistsGlob"
, "PathChanged", "PathModified", "DirectoryNotEmpty", ((void*
)0) }))), (field)))
1345 "PathModified", "DirectoryNotEmpty")(!!strv_find((((char**) ((const char*[]) { "PathExists", "PathExistsGlob"
, "PathChanged", "PathModified", "DirectoryNotEmpty", ((void*
)0) }))), (field)))
) {
1346
1347 if (isempty(eq))
1348 r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0);
1349 else
1350 r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 1, field, eq);
1351 if (r < 0)
1352 return bus_log_create_error(r);
1353
1354 return 1;
1355 }
1356
1357 return 0;
1358}
1359
1360static int bus_append_service_property(sd_bus_message *m, const char *field, const char *eq) {
1361 int r;
1362
1363 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "PIDFile", "Type",
"Restart", "BusName", "NotifyAccess", "USBFunctionDescriptors"
, "USBFunctionStrings", ((void*)0) }))), (field)))
1364 "PIDFile", "Type", "Restart", "BusName", "NotifyAccess",(!!strv_find((((char**) ((const char*[]) { "PIDFile", "Type",
"Restart", "BusName", "NotifyAccess", "USBFunctionDescriptors"
, "USBFunctionStrings", ((void*)0) }))), (field)))
1365 "USBFunctionDescriptors", "USBFunctionStrings")(!!strv_find((((char**) ((const char*[]) { "PIDFile", "Type",
"Restart", "BusName", "NotifyAccess", "USBFunctionDescriptors"
, "USBFunctionStrings", ((void*)0) }))), (field)))
)
1366
1367 return bus_append_string(m, field, eq);
1368
1369 if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID")(!!strv_find((((char**) ((const char*[]) { "PermissionsStartOnly"
, "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID"
, ((void*)0) }))), (field)))
)
1370
1371 return bus_append_parse_boolean(m, field, eq);
1372
1373 if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec")(!!strv_find((((char**) ((const char*[]) { "RestartSec", "TimeoutStartSec"
, "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec", ((void*)0
) }))), (field)))
)
1374
1375 return bus_append_parse_sec_rename(m, field, eq);
1376
1377 if (streq(field, "TimeoutSec")(strcmp((field),("TimeoutSec")) == 0)) {
1378
1379 r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq);
1380 if (r < 0)
1381 return r;
1382
1383 return bus_append_parse_sec_rename(m, "TimeoutStopSec", eq);
1384 }
1385
1386 if (streq(field, "FileDescriptorStoreMax")(strcmp((field),("FileDescriptorStoreMax")) == 0))
1387
1388 return bus_append_safe_atou(m, field, eq);
1389
1390 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "ExecCondition", "ExecStartPre"
, "ExecStart", "ExecStartPost", "ExecReload", "ExecStop", "ExecStopPost"
, ((void*)0) }))), (field)))
1391 "ExecCondition", "ExecStartPre", "ExecStart", "ExecStartPost",(!!strv_find((((char**) ((const char*[]) { "ExecCondition", "ExecStartPre"
, "ExecStart", "ExecStartPost", "ExecReload", "ExecStop", "ExecStopPost"
, ((void*)0) }))), (field)))
1392 "ExecReload", "ExecStop", "ExecStopPost")(!!strv_find((((char**) ((const char*[]) { "ExecCondition", "ExecStartPre"
, "ExecStart", "ExecStartPost", "ExecReload", "ExecStop", "ExecStopPost"
, ((void*)0) }))), (field)))
)
1393
1394 return bus_append_exec_command(m, field, eq);
1395
1396 if (STR_IN_SET(field, "RestartPreventExitStatus", "RestartForceExitStatus", "SuccessExitStatus")(!!strv_find((((char**) ((const char*[]) { "RestartPreventExitStatus"
, "RestartForceExitStatus", "SuccessExitStatus", ((void*)0) }
))), (field)))
) {
1397 _cleanup_free___attribute__((cleanup(freep))) int *status = NULL((void*)0), *signal = NULL((void*)0);
1398 size_t sz_status = 0, sz_signal = 0;
1399 const char *p;
1400
1401 for (p = eq;;) {
1402 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
1403 int val;
1404
1405 r = extract_first_word(&p, &word, NULL((void*)0), EXTRACT_QUOTES);
1406 if (r == 0)
1407 break;
1408 if (r == -ENOMEM12)
1409 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 1409, __func__)
;
1410 if (r < 0)
1411 return log_error_errno(r, "Invalid syntax in %s: %s", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1411, __func__, "Invalid syntax in %s: %s"
, field, eq) : -abs(_e); })
;
1412
1413 r = safe_atoi(word, &val);
1414 if (r < 0) {
1415 val = signal_from_string(word);
1416 if (val < 0)
1417 return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1417, __func__, "Invalid status or signal %s in %s: %m"
, word, field) : -abs(_e); })
;
1418
1419 signal = reallocarray(signal, sz_signal + 1, sizeof(int));
1420 if (!signal)
1421 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 1421, __func__)
;
1422
1423 signal[sz_signal++] = val;
1424 } else {
1425 status = reallocarray(status, sz_status + 1, sizeof(int));
1426 if (!status)
1427 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 1427, __func__)
;
1428
1429 status[sz_status++] = val;
1430 }
1431 }
1432
1433 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
1434 if (r < 0)
1435 return bus_log_create_error(r);
1436
1437 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1438 if (r < 0)
1439 return bus_log_create_error(r);
1440
1441 r = sd_bus_message_open_container(m, 'v', "(aiai)");
1442 if (r < 0)
1443 return bus_log_create_error(r);
1444
1445 r = sd_bus_message_open_container(m, 'r', "aiai");
1446 if (r < 0)
1447 return bus_log_create_error(r);
1448
1449 r = sd_bus_message_append_array(m, 'i', status, sz_status);
1450 if (r < 0)
1451 return bus_log_create_error(r);
1452
1453 r = sd_bus_message_append_array(m, 'i', signal, sz_signal);
1454 if (r < 0)
1455 return bus_log_create_error(r);
1456
1457 r = sd_bus_message_close_container(m);
1458 if (r < 0)
1459 return bus_log_create_error(r);
1460
1461 r = sd_bus_message_close_container(m);
1462 if (r < 0)
1463 return bus_log_create_error(r);
1464
1465 r = sd_bus_message_close_container(m);
1466 if (r < 0)
1467 return bus_log_create_error(r);
1468
1469 return 1;
1470 }
1471
1472 return 0;
1473}
1474
1475static int bus_append_socket_property(sd_bus_message *m, const char *field, const char *eq) {
1476 int r;
1477
1478 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "Accept", "Writable"
, "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast"
, "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop"
, "SELinuxContextFromNet", "FlushPending", "PassPacketInfo", (
(void*)0) }))), (field)))
1479 "Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast",(!!strv_find((((char**) ((const char*[]) { "Accept", "Writable"
, "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast"
, "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop"
, "SELinuxContextFromNet", "FlushPending", "PassPacketInfo", (
(void*)0) }))), (field)))
1480 "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet",(!!strv_find((((char**) ((const char*[]) { "Accept", "Writable"
, "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast"
, "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop"
, "SELinuxContextFromNet", "FlushPending", "PassPacketInfo", (
(void*)0) }))), (field)))
1481 "FlushPending", "PassPacketInfo")(!!strv_find((((char**) ((const char*[]) { "Accept", "Writable"
, "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast"
, "PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop"
, "SELinuxContextFromNet", "FlushPending", "PassPacketInfo", (
(void*)0) }))), (field)))
)
1482 return bus_append_parse_boolean(m, field, eq);
1483
1484 if (STR_IN_SET(field, "Priority", "IPTTL", "Mark")(!!strv_find((((char**) ((const char*[]) { "Priority", "IPTTL"
, "Mark", ((void*)0) }))), (field)))
)
1485
1486 return bus_append_safe_atoi(m, field, eq);
1487
1488 if (streq(field, "IPTOS")(strcmp((field),("IPTOS")) == 0))
1489
1490 return bus_append_ip_tos_from_string(m, field, eq);
1491
1492 if (STR_IN_SET(field, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst")(!!strv_find((((char**) ((const char*[]) { "Backlog", "MaxConnections"
, "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst"
, ((void*)0) }))), (field)))
)
1493
1494 return bus_append_safe_atou(m, field, eq);
1495
1496 if (STR_IN_SET(field, "SocketMode", "DirectoryMode")(!!strv_find((((char**) ((const char*[]) { "SocketMode", "DirectoryMode"
, ((void*)0) }))), (field)))
)
1497
1498 return bus_append_parse_mode(m, field, eq);
1499
1500 if (STR_IN_SET(field, "MessageQueueMaxMessages", "MessageQueueMessageSize")(!!strv_find((((char**) ((const char*[]) { "MessageQueueMaxMessages"
, "MessageQueueMessageSize", ((void*)0) }))), (field)))
)
1501
1502 return bus_append_safe_atoi64(m, field, eq);
1503
1504 if (STR_IN_SET(field, "TimeoutSec", "KeepAliveTimeSec", "KeepAliveIntervalSec", "DeferAcceptSec", "TriggerLimitIntervalSec")(!!strv_find((((char**) ((const char*[]) { "TimeoutSec", "KeepAliveTimeSec"
, "KeepAliveIntervalSec", "DeferAcceptSec", "TriggerLimitIntervalSec"
, ((void*)0) }))), (field)))
)
1505
1506 return bus_append_parse_sec_rename(m, field, eq);
1507
1508 if (STR_IN_SET(field, "ReceiveBuffer", "SendBuffer", "PipeSize")(!!strv_find((((char**) ((const char*[]) { "ReceiveBuffer", "SendBuffer"
, "PipeSize", ((void*)0) }))), (field)))
)
1509
1510 return bus_append_parse_size(m, field, eq, 1024);
1511
1512 if (STR_IN_SET(field, "ExecStartPre", "ExecStartPost", "ExecReload", "ExecStopPost")(!!strv_find((((char**) ((const char*[]) { "ExecStartPre", "ExecStartPost"
, "ExecReload", "ExecStopPost", ((void*)0) }))), (field)))
)
1513
1514 return bus_append_exec_command(m, field, eq);
1515
1516 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "SmackLabel", "SmackLabelIPIn"
, "SmackLabelIPOut", "TCPCongestion", "BindToDevice", "BindIPv6Only"
, "FileDescriptorName", "SocketUser", "SocketGroup", ((void*)
0) }))), (field)))
1517 "SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion",(!!strv_find((((char**) ((const char*[]) { "SmackLabel", "SmackLabelIPIn"
, "SmackLabelIPOut", "TCPCongestion", "BindToDevice", "BindIPv6Only"
, "FileDescriptorName", "SocketUser", "SocketGroup", ((void*)
0) }))), (field)))
1518 "BindToDevice", "BindIPv6Only", "FileDescriptorName",(!!strv_find((((char**) ((const char*[]) { "SmackLabel", "SmackLabelIPIn"
, "SmackLabelIPOut", "TCPCongestion", "BindToDevice", "BindIPv6Only"
, "FileDescriptorName", "SocketUser", "SocketGroup", ((void*)
0) }))), (field)))
1519 "SocketUser", "SocketGroup")(!!strv_find((((char**) ((const char*[]) { "SmackLabel", "SmackLabelIPIn"
, "SmackLabelIPOut", "TCPCongestion", "BindToDevice", "BindIPv6Only"
, "FileDescriptorName", "SocketUser", "SocketGroup", ((void*)
0) }))), (field)))
)
1520
1521 return bus_append_string(m, field, eq);
1522
1523 if (streq(field, "Symlinks")(strcmp((field),("Symlinks")) == 0))
1524
1525 return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
1526
1527 if (streq(field, "SocketProtocol")(strcmp((field),("SocketProtocol")) == 0))
1528
1529 return bus_append_socket_protocol_from_name(m, field, eq);
1530
1531 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "ListenStream", "ListenDatagram"
, "ListenSequentialPacket", "ListenNetlink", "ListenSpecial",
"ListenMessageQueue", "ListenFIFO", "ListenUSBFunction", ((void
*)0) }))), (field)))
1532 "ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",(!!strv_find((((char**) ((const char*[]) { "ListenStream", "ListenDatagram"
, "ListenSequentialPacket", "ListenNetlink", "ListenSpecial",
"ListenMessageQueue", "ListenFIFO", "ListenUSBFunction", ((void
*)0) }))), (field)))
1533 "ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")(!!strv_find((((char**) ((const char*[]) { "ListenStream", "ListenDatagram"
, "ListenSequentialPacket", "ListenNetlink", "ListenSpecial",
"ListenMessageQueue", "ListenFIFO", "ListenUSBFunction", ((void
*)0) }))), (field)))
) {
1534
1535 if (isempty(eq))
1536 r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0);
1537 else
1538 r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + STRLEN("Listen")(sizeof("""Listen""") - 1), eq);
1539 if (r < 0)
1540 return bus_log_create_error(r);
1541
1542 return 1;
1543 }
1544
1545 return 0;
1546}
1547static int bus_append_timer_property(sd_bus_message *m, const char *field, const char *eq) {
1548 int r;
1549
1550 if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent")(!!strv_find((((char**) ((const char*[]) { "WakeSystem", "RemainAfterElapse"
, "Persistent", ((void*)0) }))), (field)))
)
1551
1552 return bus_append_parse_boolean(m, field, eq);
1553
1554 if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec")(!!strv_find((((char**) ((const char*[]) { "AccuracySec", "RandomizedDelaySec"
, ((void*)0) }))), (field)))
)
1555
1556 return bus_append_parse_sec_rename(m, field, eq);
1557
1558 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "OnActiveSec", "OnBootSec"
, "OnStartupSec", "OnUnitActiveSec","OnUnitInactiveSec", ((void
*)0) }))), (field)))
1559 "OnActiveSec", "OnBootSec", "OnStartupSec",(!!strv_find((((char**) ((const char*[]) { "OnActiveSec", "OnBootSec"
, "OnStartupSec", "OnUnitActiveSec","OnUnitInactiveSec", ((void
*)0) }))), (field)))
1560 "OnUnitActiveSec","OnUnitInactiveSec")(!!strv_find((((char**) ((const char*[]) { "OnActiveSec", "OnBootSec"
, "OnStartupSec", "OnUnitActiveSec","OnUnitInactiveSec", ((void
*)0) }))), (field)))
) {
1561
1562 if (isempty(eq))
1563 r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0);
1564 else {
1565 usec_t t;
1566 r = parse_sec(eq, &t);
1567 if (r < 0)
1568 return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1568, __func__, "Failed to parse %s=%s: %m"
, field, eq) : -abs(_e); })
;
1569
1570 r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 1, field, t);
1571 }
1572 if (r < 0)
1573 return bus_log_create_error(r);
1574
1575 return 1;
1576 }
1577
1578 if (streq(field, "OnCalendar")(strcmp((field),("OnCalendar")) == 0)) {
1579
1580 if (isempty(eq))
1581 r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0);
1582 else
1583 r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 1, field, eq);
1584 if (r < 0)
1585 return bus_log_create_error(r);
1586
1587 return 1;
1588 }
1589
1590 return 0;
1591}
1592
1593static int bus_append_unit_property(sd_bus_message *m, const char *field, const char *eq) {
1594 ConditionType t = _CONDITION_TYPE_INVALID;
1595 bool_Bool is_condition = false0;
1596 int r;
1597
1598 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "Description", "SourcePath"
, "OnFailureJobMode", "JobTimeoutAction", "JobTimeoutRebootArgument"
, "StartLimitAction", "FailureAction", "SuccessAction", "RebootArgument"
, "CollectMode", ((void*)0) }))), (field)))
1599 "Description", "SourcePath", "OnFailureJobMode",(!!strv_find((((char**) ((const char*[]) { "Description", "SourcePath"
, "OnFailureJobMode", "JobTimeoutAction", "JobTimeoutRebootArgument"
, "StartLimitAction", "FailureAction", "SuccessAction", "RebootArgument"
, "CollectMode", ((void*)0) }))), (field)))
1600 "JobTimeoutAction", "JobTimeoutRebootArgument",(!!strv_find((((char**) ((const char*[]) { "Description", "SourcePath"
, "OnFailureJobMode", "JobTimeoutAction", "JobTimeoutRebootArgument"
, "StartLimitAction", "FailureAction", "SuccessAction", "RebootArgument"
, "CollectMode", ((void*)0) }))), (field)))
1601 "StartLimitAction", "FailureAction", "SuccessAction",(!!strv_find((((char**) ((const char*[]) { "Description", "SourcePath"
, "OnFailureJobMode", "JobTimeoutAction", "JobTimeoutRebootArgument"
, "StartLimitAction", "FailureAction", "SuccessAction", "RebootArgument"
, "CollectMode", ((void*)0) }))), (field)))
1602 "RebootArgument", "CollectMode")(!!strv_find((((char**) ((const char*[]) { "Description", "SourcePath"
, "OnFailureJobMode", "JobTimeoutAction", "JobTimeoutRebootArgument"
, "StartLimitAction", "FailureAction", "SuccessAction", "RebootArgument"
, "CollectMode", ((void*)0) }))), (field)))
)
1603
1604 return bus_append_string(m, field, eq);
1605
1606 if (STR_IN_SET(field,(!!strv_find((((char**) ((const char*[]) { "StopWhenUnneeded"
, "RefuseManualStart", "RefuseManualStop", "AllowIsolate", "IgnoreOnIsolate"
, "DefaultDependencies", ((void*)0) }))), (field)))
1607 "StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop",(!!strv_find((((char**) ((const char*[]) { "StopWhenUnneeded"
, "RefuseManualStart", "RefuseManualStop", "AllowIsolate", "IgnoreOnIsolate"
, "DefaultDependencies", ((void*)0) }))), (field)))
1608 "AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies")(!!strv_find((((char**) ((const char*[]) { "StopWhenUnneeded"
, "RefuseManualStart", "RefuseManualStop", "AllowIsolate", "IgnoreOnIsolate"
, "DefaultDependencies", ((void*)0) }))), (field)))
)
1609
1610 return bus_append_parse_boolean(m, field, eq);
1611
1612 if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec")(!!strv_find((((char**) ((const char*[]) { "JobTimeoutSec", "JobRunningTimeoutSec"
, "StartLimitIntervalSec", ((void*)0) }))), (field)))
)
1613
1614 return bus_append_parse_sec_rename(m, field, eq);
1615
1616 if (streq(field, "StartLimitBurst")(strcmp((field),("StartLimitBurst")) == 0))
1617
1618 return bus_append_safe_atou(m, field, eq);
1619
1620 if (unit_dependency_from_string(field) >= 0 ||
1621 STR_IN_SET(field, "Documentation", "RequiresMountsFor")(!!strv_find((((char**) ((const char*[]) { "Documentation", "RequiresMountsFor"
, ((void*)0) }))), (field)))
)
1622
1623 return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
1624
1625 t = condition_type_from_string(field);
1626 if (t >= 0)
1627 is_condition = true1;
1628 else
1629 t = assert_type_from_string(field);
1630 if (t >= 0) {
1631 if (isempty(eq))
1632 r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 0);
1633 else {
1634 const char *p = eq;
1635 int trigger, negate;
1636
1637 trigger = *p == '|';
1638 if (trigger)
1639 p++;
1640
1641 negate = *p == '!';
1642 if (negate)
1643 p++;
1644
1645 r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 1,
1646 field, trigger, negate, p);
1647 }
1648 if (r < 0)
1649 return bus_log_create_error(r);
1650
1651 return 1;
1652 }
1653
1654 return 0;
1655}
1656
1657int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const char *assignment) {
1658 const char *eq, *field;
1659 int r;
1660
1661 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/shared/bus-unit-util.c", 1661
, __PRETTY_FUNCTION__); } while (0)
;
1662 assert(assignment)do { if ((__builtin_expect(!!(!(assignment)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("assignment"), "../src/shared/bus-unit-util.c"
, 1662, __PRETTY_FUNCTION__); } while (0)
;
1663
1664 eq = strchr(assignment, '=');
1665 if (!eq) {
1666 log_error("Not an assignment: %s", assignment)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1666, __func__, "Not an assignment: %s"
, assignment) : -abs(_e); })
;
1667 return -EINVAL22;
1668 }
1669
1670 field = strndupa(assignment, eq - assignment)(__extension__ ({ const char *__old = (assignment); size_t __len
= strnlen (__old, (eq - assignment)); char *__new = (char *)
__builtin_alloca (__len + 1); __new[__len] = '\0'; (char *) memcpy
(__new, __old, __len); }))
;
1671 eq++;
1672
1673 switch (t) {
1674 case UNIT_SERVICE:
1675 r = bus_append_cgroup_property(m, field, eq);
1676 if (r != 0)
1677 return r;
1678
1679 r = bus_append_execute_property(m, field, eq);
1680 if (r != 0)
1681 return r;
1682
1683 r = bus_append_kill_property(m, field, eq);
1684 if (r != 0)
1685 return r;
1686
1687 r = bus_append_service_property(m, field, eq);
1688 if (r != 0)
1689 return r;
1690 break;
1691
1692 case UNIT_SOCKET:
1693 r = bus_append_cgroup_property(m, field, eq);
1694 if (r != 0)
1695 return r;
1696
1697 r = bus_append_execute_property(m, field, eq);
1698 if (r != 0)
1699 return r;
1700
1701 r = bus_append_kill_property(m, field, eq);
1702 if (r != 0)
1703 return r;
1704
1705 r = bus_append_socket_property(m, field, eq);
1706 if (r != 0)
1707 return r;
1708 break;
1709
1710 case UNIT_TIMER:
1711 r = bus_append_timer_property(m, field, eq);
1712 if (r != 0)
1713 return r;
1714 break;
1715
1716 case UNIT_PATH:
1717 r = bus_append_path_property(m, field, eq);
1718 if (r != 0)
1719 return r;
1720 break;
1721
1722 case UNIT_SLICE:
1723 r = bus_append_cgroup_property(m, field, eq);
1724 if (r != 0)
1725 return r;
1726 break;
1727
1728 case UNIT_SCOPE:
1729
1730 if (streq(field, "TimeoutStopSec")(strcmp((field),("TimeoutStopSec")) == 0))
1731 return bus_append_parse_sec_rename(m, field, eq);
1732
1733 r = bus_append_cgroup_property(m, field, eq);
1734 if (r != 0)
1735 return r;
1736
1737 r = bus_append_kill_property(m, field, eq);
1738 if (r != 0)
1739 return r;
1740 break;
1741
1742 case UNIT_MOUNT:
1743 r = bus_append_cgroup_property(m, field, eq);
1744 if (r != 0)
1745 return r;
1746
1747 r = bus_append_execute_property(m, field, eq);
1748 if (r != 0)
1749 return r;
1750
1751 r = bus_append_kill_property(m, field, eq);
1752 if (r != 0)
1753 return r;
1754
1755 r = bus_append_mount_property(m, field, eq);
1756 if (r != 0)
1757 return r;
1758
1759 break;
1760
1761 case UNIT_AUTOMOUNT:
1762 r = bus_append_automount_property(m, field, eq);
1763 if (r != 0)
1764 return r;
1765
1766 break;
1767
1768 case UNIT_TARGET:
1769 case UNIT_DEVICE:
1770 case UNIT_SWAP:
1771 log_error("Not supported unit type")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1771, __func__, "Not supported unit type"
) : -abs(_e); })
;
1772 return -EINVAL22;
1773
1774 default:
1775 log_error("Invalid unit type")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1775, __func__, "Invalid unit type"
) : -abs(_e); })
;
1776 return -EINVAL22;
1777 }
1778
1779 r = bus_append_unit_property(m, field, eq);
1780 if (r != 0)
1781 return r;
1782
1783 log_error("Unknown assignment: %s", assignment)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1783, __func__, "Unknown assignment: %s"
, assignment) : -abs(_e); })
;
1784 return -EINVAL22;
1785}
1786
1787int bus_append_unit_property_assignment_many(sd_bus_message *m, UnitType t, char **l) {
1788 char **i;
1789 int r;
1790
1791 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/shared/bus-unit-util.c", 1791
, __PRETTY_FUNCTION__); } while (0)
;
1792
1793 STRV_FOREACH(i, l)for ((i) = (l); (i) && *(i); (i)++) {
1794 r = bus_append_unit_property_assignment(m, t, *i);
1795 if (r < 0)
1796 return r;
1797 }
1798
1799 return 0;
1800}
1801
1802typedef struct BusWaitForJobs {
1803 sd_bus *bus;
1804 Set *jobs;
1805
1806 char *name;
1807 char *result;
1808
1809 sd_bus_slot *slot_job_removed;
1810 sd_bus_slot *slot_disconnected;
1811} BusWaitForJobs;
1812
1813static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1814 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/shared/bus-unit-util.c", 1814
, __PRETTY_FUNCTION__); } while (0)
;
1815
1816 log_error("Warning! D-Bus connection terminated.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1816, __func__, "Warning! D-Bus connection terminated."
) : -abs(_e); })
;
1817 sd_bus_close(sd_bus_message_get_bus(m));
1818
1819 return 0;
1820}
1821
1822static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1823 const char *path, *unit, *result;
1824 BusWaitForJobs *d = userdata;
1825 uint32_t id;
1826 char *found;
1827 int r;
1828
1829 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/shared/bus-unit-util.c", 1829
, __PRETTY_FUNCTION__); } while (0)
;
1830 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/shared/bus-unit-util.c", 1830
, __PRETTY_FUNCTION__); } while (0)
;
1831
1832 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1833 if (r < 0) {
1834 bus_log_parse_error(r);
1835 return 0;
1836 }
1837
1838 found = set_remove(d->jobs, (char*) path);
1839 if (!found)
1840 return 0;
1841
1842 free(found);
1843
1844 if (!isempty(result))
1845 d->result = strdup(result);
1846
1847 if (!isempty(unit))
1848 d->name = strdup(unit);
1849
1850 return 0;
1851}
1852
1853void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1854 if (!d)
1855 return;
1856
1857 set_free_free(d->jobs);
1858
1859 sd_bus_slot_unref(d->slot_disconnected);
1860 sd_bus_slot_unref(d->slot_job_removed);
1861
1862 sd_bus_unref(d->bus);
1863
1864 free(d->name);
1865 free(d->result);
1866
1867 free(d);
1868}
1869
1870int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1871 _cleanup_(bus_wait_for_jobs_freep)__attribute__((cleanup(bus_wait_for_jobs_freep))) BusWaitForJobs *d = NULL((void*)0);
1872 int r;
1873
1874 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/shared/bus-unit-util.c",
1874, __PRETTY_FUNCTION__); } while (0)
;
1875 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/shared/bus-unit-util.c",
1875, __PRETTY_FUNCTION__); } while (0)
;
1876
1877 d = new0(BusWaitForJobs, 1)((BusWaitForJobs*) calloc((1), sizeof(BusWaitForJobs)));
1878 if (!d)
1879 return -ENOMEM12;
1880
1881 d->bus = sd_bus_ref(bus);
1882
1883 /* When we are a bus client we match by sender. Direct
1884 * connections OTOH have no initialized sender field, and
1885 * hence we ignore the sender then */
1886 r = sd_bus_match_signal_async(
1887 bus,
1888 &d->slot_job_removed,
1889 bus->bus_client ? "org.freedesktop.systemd1" : NULL((void*)0),
1890 "/org/freedesktop/systemd1",
1891 "org.freedesktop.systemd1.Manager",
1892 "JobRemoved",
1893 match_job_removed, NULL((void*)0), d);
1894 if (r < 0)
1895 return r;
1896
1897 r = sd_bus_match_signal_async(
1898 bus,
1899 &d->slot_disconnected,
1900 "org.freedesktop.DBus.Local",
1901 NULL((void*)0),
1902 "org.freedesktop.DBus.Local",
1903 "Disconnected",
1904 match_disconnected, NULL((void*)0), d);
1905 if (r < 0)
1906 return r;
1907
1908 *ret = TAKE_PTR(d)({ typeof(d) _ptr_ = (d); (d) = ((void*)0); _ptr_; });
1909
1910 return 0;
1911}
1912
1913static int bus_process_wait(sd_bus *bus) {
1914 int r;
1915
1916 for (;;) {
1917 r = sd_bus_process(bus, NULL((void*)0));
1918 if (r < 0)
1919 return r;
1920 if (r > 0)
1921 return 0;
1922
1923 r = sd_bus_wait(bus, (uint64_t) -1);
1924 if (r < 0)
1925 return r;
1926 }
1927}
1928
1929static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1930 _cleanup_free___attribute__((cleanup(freep))) char *dbus_path = NULL((void*)0);
1931
1932 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/shared/bus-unit-util.c", 1932
, __PRETTY_FUNCTION__); } while (0)
;
1933 assert(d->name)do { if ((__builtin_expect(!!(!(d->name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->name"), "../src/shared/bus-unit-util.c"
, 1933, __PRETTY_FUNCTION__); } while (0)
;
1934 assert(result)do { if ((__builtin_expect(!!(!(result)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("result"), "../src/shared/bus-unit-util.c"
, 1934, __PRETTY_FUNCTION__); } while (0)
;
1935
1936 if (!endswith(d->name, ".service"))
1937 return -EINVAL22;
1938
1939 dbus_path = unit_dbus_path_from_name(d->name);
1940 if (!dbus_path)
1941 return -ENOMEM12;
1942
1943 return sd_bus_get_property_string(d->bus,
1944 "org.freedesktop.systemd1",
1945 dbus_path,
1946 "org.freedesktop.systemd1.Service",
1947 "Result",
1948 NULL((void*)0),
1949 result);
1950}
1951
1952static const struct {
1953 const char *result, *explanation;
1954} explanations [] = {
1955 { "resources", "of unavailable resources or another system error" },
1956 { "protocol", "the service did not take the steps required by its unit configuration" },
1957 { "timeout", "a timeout was exceeded" },
1958 { "exit-code", "the control process exited with error code" },
1959 { "signal", "a fatal signal was delivered to the control process" },
1960 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1961 { "watchdog", "the service failed to send watchdog ping" },
1962 { "start-limit", "start of the service was attempted too often" }
1963};
1964
1965static void log_job_error_with_service_result(const char* service, const char *result, const char* const* extra_args) {
1966 _cleanup_free___attribute__((cleanup(freep))) char *service_shell_quoted = NULL((void*)0);
1967 const char *systemctl = "systemctl", *journalctl = "journalctl";
1968
1969 assert(service)do { if ((__builtin_expect(!!(!(service)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("service"), "../src/shared/bus-unit-util.c"
, 1969, __PRETTY_FUNCTION__); } while (0)
;
1970
1971 service_shell_quoted = shell_maybe_quote(service, ESCAPE_BACKSLASH);
1972
1973 if (!strv_isempty((char**) extra_args)) {
1974 _cleanup_free___attribute__((cleanup(freep))) char *t;
1975
1976 t = strv_join((char**) extra_args, " ");
1977 systemctl = strjoina("systemctl ", t ? : "<args>")({ const char *_appendees_[] = { "systemctl ", t ? : "<args>"
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
1978 journalctl = strjoina("journalctl ", t ? : "<args>")({ const char *_appendees_[] = { "journalctl ", t ? : "<args>"
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
1979 }
1980
1981 if (!isempty(result)) {
1982 unsigned i;
1983
1984 for (i = 0; i < ELEMENTSOF(explanations)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(explanations), typeof(&*(explanations))), sizeof(
explanations)/sizeof((explanations)[0]), ((void)0)))
; ++i)
1985 if (streq(result, explanations[i].result)(strcmp((result),(explanations[i].result)) == 0))
1986 break;
1987
1988 if (i < ELEMENTSOF(explanations)__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(explanations), typeof(&*(explanations))), sizeof(
explanations)/sizeof((explanations)[0]), ((void)0)))
) {
1989 log_error("Job for %s failed because %s.\n"({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1990 "See \"%s status %s\" and \"%s -xe\" for details.\n",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1991 service,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1992 explanations[i].explanation,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1993 systemctl,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1994 service_shell_quoted ?: "<service>",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
1995 journalctl)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 1995, __func__, "Job for %s failed because %s.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, explanations[i].explanation, systemctl, service_shell_quoted
?: "<service>", journalctl) : -abs(_e); })
;
1996 goto finish;
1997 }
1998 }
1999
2000 log_error("Job for %s failed.\n"({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
2001 "See \"%s status %s\" and \"%s -xe\" for details.\n",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
2002 service,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
2003 systemctl,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
2004 service_shell_quoted ?: "<service>",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
2005 journalctl)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2005, __func__, "Job for %s failed.\n"
"See \"%s status %s\" and \"%s -xe\" for details.\n", service
, systemctl, service_shell_quoted ?: "<service>", journalctl
) : -abs(_e); })
;
2006
2007finish:
2008 /* For some results maybe additional explanation is required */
2009 if (streq_ptr(result, "start-limit"))
2010 log_info("To force a start use \"%1$s reset-failed %2$s\"\n"({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2013, __func__, "To force a start use \"%1$s reset-failed %2$s\"\n"
"followed by \"%1$s start %2$s\" again.", systemctl, service_shell_quoted
?: "<service>") : -abs(_e); })
2011 "followed by \"%1$s start %2$s\" again.",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2013, __func__, "To force a start use \"%1$s reset-failed %2$s\"\n"
"followed by \"%1$s start %2$s\" again.", systemctl, service_shell_quoted
?: "<service>") : -abs(_e); })
2012 systemctl,({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2013, __func__, "To force a start use \"%1$s reset-failed %2$s\"\n"
"followed by \"%1$s start %2$s\" again.", systemctl, service_shell_quoted
?: "<service>") : -abs(_e); })
2013 service_shell_quoted ?: "<service>")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2013, __func__, "To force a start use \"%1$s reset-failed %2$s\"\n"
"followed by \"%1$s start %2$s\" again.", systemctl, service_shell_quoted
?: "<service>") : -abs(_e); })
;
2014}
2015
2016static int check_wait_response(BusWaitForJobs *d, bool_Bool quiet, const char* const* extra_args) {
2017 assert(d->result)do { if ((__builtin_expect(!!(!(d->result)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d->result"), "../src/shared/bus-unit-util.c"
, 2017, __PRETTY_FUNCTION__); } while (0)
;
2018
2019 if (!quiet) {
2020 if (streq(d->result, "canceled")(strcmp((d->result),("canceled")) == 0))
2021 log_error("Job for %s canceled.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2021, __func__, "Job for %s canceled."
, strna(d->name)) : -abs(_e); })
;
2022 else if (streq(d->result, "timeout")(strcmp((d->result),("timeout")) == 0))
2023 log_error("Job for %s timed out.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2023, __func__, "Job for %s timed out."
, strna(d->name)) : -abs(_e); })
;
2024 else if (streq(d->result, "dependency")(strcmp((d->result),("dependency")) == 0))
2025 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2025, __func__, "A dependency job for %s failed. See 'journalctl -xe' for details."
, strna(d->name)) : -abs(_e); })
;
2026 else if (streq(d->result, "invalid")(strcmp((d->result),("invalid")) == 0))
2027 log_error("%s is not active, cannot reload.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2027, __func__, "%s is not active, cannot reload."
, strna(d->name)) : -abs(_e); })
;
2028 else if (streq(d->result, "assert")(strcmp((d->result),("assert")) == 0))
2029 log_error("Assertion failed on job for %s.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2029, __func__, "Assertion failed on job for %s."
, strna(d->name)) : -abs(_e); })
;
2030 else if (streq(d->result, "unsupported")(strcmp((d->result),("unsupported")) == 0))
2031 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2031, __func__, "Operation on or unit type of %s not supported on this system."
, strna(d->name)) : -abs(_e); })
;
2032 else if (streq(d->result, "collected")(strcmp((d->result),("collected")) == 0))
2033 log_error("Queued job for %s was garbage collected.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2033, __func__, "Queued job for %s was garbage collected."
, strna(d->name)) : -abs(_e); })
;
2034 else if (streq(d->result, "once")(strcmp((d->result),("once")) == 0))
2035 log_error("Unit %s was started already once and can't be started again.", strna(d->name))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2035, __func__, "Unit %s was started already once and can't be started again."
, strna(d->name)) : -abs(_e); })
;
2036 else if (!STR_IN_SET(d->result, "done", "skipped")(!!strv_find((((char**) ((const char*[]) { "done", "skipped",
((void*)0) }))), (d->result)))
) {
2037 if (d->name) {
2038 _cleanup_free___attribute__((cleanup(freep))) char *result = NULL((void*)0);
2039 int q;
2040
2041 q = bus_job_get_service_result(d, &result);
2042 if (q < 0)
2043 log_debug_errno(q, "Failed to get Result property of unit %s: %m", d->name)({ int _level = ((7)), _e = ((q)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2043, __func__, "Failed to get Result property of unit %s: %m"
, d->name) : -abs(_e); })
;
2044
2045 log_job_error_with_service_result(d->name, result, extra_args);
2046 } else
2047 log_error("Job failed. See \"journalctl -xe\" for details.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2047, __func__, "Job failed. See \"journalctl -xe\" for details."
) : -abs(_e); })
;
2048 }
2049 }
2050
2051 if (STR_IN_SET(d->result, "canceled", "collected")(!!strv_find((((char**) ((const char*[]) { "canceled", "collected"
, ((void*)0) }))), (d->result)))
)
2052 return -ECANCELED125;
2053 else if (streq(d->result, "timeout")(strcmp((d->result),("timeout")) == 0))
2054 return -ETIME62;
2055 else if (streq(d->result, "dependency")(strcmp((d->result),("dependency")) == 0))
2056 return -EIO5;
2057 else if (streq(d->result, "invalid")(strcmp((d->result),("invalid")) == 0))
2058 return -ENOEXEC8;
2059 else if (streq(d->result, "assert")(strcmp((d->result),("assert")) == 0))
2060 return -EPROTO71;
2061 else if (streq(d->result, "unsupported")(strcmp((d->result),("unsupported")) == 0))
2062 return -EOPNOTSUPP95;
2063 else if (streq(d->result, "once")(strcmp((d->result),("once")) == 0))
2064 return -ESTALE116;
2065 else if (STR_IN_SET(d->result, "done", "skipped")(!!strv_find((((char**) ((const char*[]) { "done", "skipped",
((void*)0) }))), (d->result)))
)
2066 return 0;
2067
2068 log_debug("Unexpected job result, assuming server side newer than us: %s", d->result)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2068, __func__, "Unexpected job result, assuming server side newer than us: %s"
, d->result) : -abs(_e); })
;
2069 return -EIO5;
2070}
2071
2072int bus_wait_for_jobs(BusWaitForJobs *d, bool_Bool quiet, const char* const* extra_args) {
2073 int r = 0;
2074
2075 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/shared/bus-unit-util.c", 2075
, __PRETTY_FUNCTION__); } while (0)
;
2076
2077 while (!set_isempty(d->jobs)) {
2078 int q;
2079
2080 q = bus_process_wait(d->bus);
2081 if (q < 0)
2082 return log_error_errno(q, "Failed to wait for response: %m")({ int _level = ((3)), _e = ((q)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2082, __func__, "Failed to wait for response: %m"
) : -abs(_e); })
;
2083
2084 if (d->result) {
2085 q = check_wait_response(d, quiet, extra_args);
2086 /* Return the first error as it is most likely to be
2087 * meaningful. */
2088 if (q < 0 && r == 0)
2089 r = q;
2090
2091 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name))({ int _level = ((7)), _e = ((q)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2091, __func__, "Got result %s/%m for job %s"
, strna(d->result), strna(d->name)) : -abs(_e); })
;
2092 }
2093
2094 d->name = mfree(d->name);
2095 d->result = mfree(d->result);
2096 }
2097
2098 return r;
2099}
2100
2101int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
2102 int r;
2103
2104 assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("d"), "../src/shared/bus-unit-util.c", 2104
, __PRETTY_FUNCTION__); } while (0)
;
2105
2106 r = set_ensure_allocated(&d->jobs, &string_hash_ops)internal_set_ensure_allocated(&d->jobs, &string_hash_ops
)
;
2107 if (r < 0)
2108 return r;
2109
2110 return set_put_strdup(d->jobs, path);
2111}
2112
2113int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool_Bool quiet) {
2114 int r;
2115
2116 r = bus_wait_for_jobs_add(d, path);
2117 if (r < 0)
2118 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 2118, __func__)
;
2119
2120 return bus_wait_for_jobs(d, quiet, NULL((void*)0));
2121}
2122
2123int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool_Bool quiet, UnitFileChange **changes, size_t *n_changes) {
2124 const char *type, *path, *source;
2125 int r;
2126
2127 /* changes is dereferenced when calling unit_file_dump_changes() later,
2128 * so we have to make sure this is not NULL. */
2129 assert(changes)do { if ((__builtin_expect(!!(!(changes)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("changes"), "../src/shared/bus-unit-util.c"
, 2129, __PRETTY_FUNCTION__); } while (0)
;
2130 assert(n_changes)do { if ((__builtin_expect(!!(!(n_changes)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("n_changes"), "../src/shared/bus-unit-util.c"
, 2130, __PRETTY_FUNCTION__); } while (0)
;
2131
2132 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
2133 if (r < 0)
2134 return bus_log_parse_error(r);
2135
2136 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
2137 /* We expect only "success" changes to be sent over the bus.
2138 Hence, reject anything negative. */
2139 UnitFileChangeType ch = unit_file_change_type_from_string(type);
2140
2141 if (ch < 0) {
2142 log_notice("Manager reported unknown change type \"%s\" for path \"%s\", ignoring.", type, path)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2142, __func__, "Manager reported unknown change type \"%s\" for path \"%s\", ignoring."
, type, path) : -abs(_e); })
;
2143 continue;
2144 }
2145
2146 r = unit_file_changes_add(changes, n_changes, ch, path, source);
2147 if (r < 0)
2148 return r;
2149 }
2150 if (r < 0)
2151 return bus_log_parse_error(r);
2152
2153 r = sd_bus_message_exit_container(m);
2154 if (r < 0)
2155 return bus_log_parse_error(r);
2156
2157 unit_file_dump_changes(0, NULL((void*)0), *changes, *n_changes, quiet);
2158 return 0;
2159}
2160
2161struct CGroupInfo {
2162 char *cgroup_path;
2163 bool_Bool is_const; /* If false, cgroup_path should be free()'d */
2164
2165 Hashmap *pids; /* PID → process name */
2166 bool_Bool done;
2167
2168 struct CGroupInfo *parent;
2169 LIST_FIELDS(struct CGroupInfo, siblings)struct CGroupInfo *siblings_next, *siblings_prev;
2170 LIST_HEAD(struct CGroupInfo, children)struct CGroupInfo *children;
2171 size_t n_children;
2172};
2173
2174static bool_Bool IS_ROOT(const char *p) {
2175 return isempty(p) || streq(p, "/")(strcmp((p),("/")) == 0);
2176}
2177
2178static int add_cgroup(Hashmap *cgroups, const char *path, bool_Bool is_const, struct CGroupInfo **ret) {
2179 struct CGroupInfo *parent = NULL((void*)0), *cg;
2180 int r;
2181
2182 assert(cgroups)do { if ((__builtin_expect(!!(!(cgroups)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("cgroups"), "../src/shared/bus-unit-util.c"
, 2182, __PRETTY_FUNCTION__); } while (0)
;
2183 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/shared/bus-unit-util.c",
2183, __PRETTY_FUNCTION__); } while (0)
;
2184
2185 if (IS_ROOT(path))
2186 path = "/";
2187
2188 cg = hashmap_get(cgroups, path);
2189 if (cg) {
2190 *ret = cg;
2191 return 0;
2192 }
2193
2194 if (!IS_ROOT(path)) {
2195 const char *e, *pp;
2196
2197 e = strrchr(path, '/');
2198 if (!e)
2199 return -EINVAL22;
2200
2201 pp = strndupa(path, e - path)(__extension__ ({ const char *__old = (path); size_t __len = strnlen
(__old, (e - path)); char *__new = (char *) __builtin_alloca
(__len + 1); __new[__len] = '\0'; (char *) memcpy (__new, __old
, __len); }))
;
2202 if (!pp)
2203 return -ENOMEM12;
2204
2205 r = add_cgroup(cgroups, pp, false0, &parent);
2206 if (r < 0)
2207 return r;
2208 }
2209
2210 cg = new0(struct CGroupInfo, 1)((struct CGroupInfo*) calloc((1), sizeof(struct CGroupInfo)));
2211 if (!cg)
2212 return -ENOMEM12;
2213
2214 if (is_const)
2215 cg->cgroup_path = (char*) path;
2216 else {
2217 cg->cgroup_path = strdup(path);
2218 if (!cg->cgroup_path) {
2219 free(cg);
2220 return -ENOMEM12;
2221 }
2222 }
2223
2224 cg->is_const = is_const;
2225 cg->parent = parent;
2226
2227 r = hashmap_put(cgroups, cg->cgroup_path, cg);
2228 if (r < 0) {
2229 if (!is_const)
2230 free(cg->cgroup_path);
2231 free(cg);
2232 return r;
2233 }
2234
2235 if (parent) {
2236 LIST_PREPEND(siblings, parent->children, cg)do { typeof(*(parent->children)) **_head = &(parent->
children), *_item = (cg); do { if ((__builtin_expect(!!(!(_item
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"),
"../src/shared/bus-unit-util.c", 2236, __PRETTY_FUNCTION__);
} while (0); if ((_item->siblings_next = *_head)) _item->
siblings_next->siblings_prev = _item; _item->siblings_prev
= ((void*)0); *_head = _item; } while (0)
;
2237 parent->n_children++;
2238 }
2239
2240 *ret = cg;
2241 return 1;
2242}
2243
2244static int add_process(
2245 Hashmap *cgroups,
2246 const char *path,
2247 pid_t pid,
2248 const char *name) {
2249
2250 struct CGroupInfo *cg;
2251 int r;
2252
2253 assert(cgroups)do { if ((__builtin_expect(!!(!(cgroups)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("cgroups"), "../src/shared/bus-unit-util.c"
, 2253, __PRETTY_FUNCTION__); } while (0)
;
2254 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/shared/bus-unit-util.c"
, 2254, __PRETTY_FUNCTION__); } while (0)
;
2255 assert(pid > 0)do { if ((__builtin_expect(!!(!(pid > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("pid > 0"), "../src/shared/bus-unit-util.c"
, 2255, __PRETTY_FUNCTION__); } while (0)
;
2256
2257 r = add_cgroup(cgroups, path, true1, &cg);
2258 if (r < 0)
2259 return r;
2260
2261 r = hashmap_ensure_allocated(&cg->pids, &trivial_hash_ops)internal_hashmap_ensure_allocated(&cg->pids, &trivial_hash_ops
)
;
2262 if (r < 0)
2263 return r;
2264
2265 return hashmap_put(cg->pids, PID_TO_PTR(pid), (void*) name);
2266}
2267
2268static void remove_cgroup(Hashmap *cgroups, struct CGroupInfo *cg) {
2269 assert(cgroups)do { if ((__builtin_expect(!!(!(cgroups)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("cgroups"), "../src/shared/bus-unit-util.c"
, 2269, __PRETTY_FUNCTION__); } while (0)
;
2270 assert(cg)do { if ((__builtin_expect(!!(!(cg)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("cg"), "../src/shared/bus-unit-util.c", 2270
, __PRETTY_FUNCTION__); } while (0)
;
2271
2272 while (cg->children)
2273 remove_cgroup(cgroups, cg->children);
2274
2275 hashmap_remove(cgroups, cg->cgroup_path);
2276
2277 if (!cg->is_const)
2278 free(cg->cgroup_path);
2279
2280 hashmap_free(cg->pids);
2281
2282 if (cg->parent)
2283 LIST_REMOVE(siblings, cg->parent->children, cg)do { typeof(*(cg->parent->children)) **_head = &(cg
->parent->children), *_item = (cg); do { if ((__builtin_expect
(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD,
("_item"), "../src/shared/bus-unit-util.c", 2283, __PRETTY_FUNCTION__
); } while (0); if (_item->siblings_next) _item->siblings_next
->siblings_prev = _item->siblings_prev; if (_item->siblings_prev
) _item->siblings_prev->siblings_next = _item->siblings_next
; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0)
)) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item"
), "../src/shared/bus-unit-util.c", 2283, __PRETTY_FUNCTION__
); } while (0); *_head = _item->siblings_next; } _item->
siblings_next = _item->siblings_prev = ((void*)0); } while
(0)
;
2284
2285 free(cg);
2286}
2287
2288static int cgroup_info_compare_func(const void *a, const void *b) {
2289 const struct CGroupInfo *x = *(const struct CGroupInfo* const*) a, *y = *(const struct CGroupInfo* const*) b;
2290
2291 assert(x)do { if ((__builtin_expect(!!(!(x)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x"), "../src/shared/bus-unit-util.c", 2291
, __PRETTY_FUNCTION__); } while (0)
;
2292 assert(y)do { if ((__builtin_expect(!!(!(y)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("y"), "../src/shared/bus-unit-util.c", 2292
, __PRETTY_FUNCTION__); } while (0)
;
2293
2294 return strcmp(x->cgroup_path, y->cgroup_path);
2295}
2296
2297static int dump_processes(
2298 Hashmap *cgroups,
2299 const char *cgroup_path,
2300 const char *prefix,
2301 unsigned n_columns,
2302 OutputFlags flags) {
2303
2304 struct CGroupInfo *cg;
2305 int r;
2306
2307 assert(prefix)do { if ((__builtin_expect(!!(!(prefix)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefix"), "../src/shared/bus-unit-util.c"
, 2307, __PRETTY_FUNCTION__); } while (0)
;
26
Taking false branch
27
Loop condition is false. Exiting loop
2308
2309 if (IS_ROOT(cgroup_path))
28
Taking true branch
2310 cgroup_path = "/";
2311
2312 cg = hashmap_get(cgroups, cgroup_path);
2313 if (!cg)
29
Assuming 'cg' is non-null
30
Taking false branch
2314 return 0;
2315
2316 if (!hashmap_isempty(cg->pids)) {
31
Calling 'hashmap_isempty'
34
Returning from 'hashmap_isempty'
35
Taking true branch
2317 const char *name;
2318 size_t n = 0, i;
2319 pid_t *pids;
2320 void *pidp;
2321 Iterator j;
2322 int width;
2323
2324 /* Order processes by their PID */
2325 pids = newa(pid_t, hashmap_size(cg->pids))({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(pid_t), hashmap_size(cg->pids)))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!size_multiply_overflow(sizeof(pid_t), hashmap_size(cg->pids))"
), "../src/shared/bus-unit-util.c", 2325, __PRETTY_FUNCTION__
); } while (0); (pid_t*) __builtin_alloca (sizeof(pid_t)*(hashmap_size
(cg->pids))); })
;
36
Taking false branch
37
Loop condition is false. Exiting loop
2326
2327 HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j)for ((j) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((cg->pids), &
(j), (void**)&(name), (const void**) &(pidp)); )
38
Loop condition is false. Execution continues on line 2330
2328 pids[n++] = PTR_TO_PID(pidp);
2329
2330 assert(n == hashmap_size(cg->pids))do { if ((__builtin_expect(!!(!(n == hashmap_size(cg->pids
))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n == hashmap_size(cg->pids)"
), "../src/shared/bus-unit-util.c", 2330, __PRETTY_FUNCTION__
); } while (0)
;
39
Assuming the condition is true
40
Taking false branch
41
Loop condition is false. Exiting loop
2331 qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
42
Calling 'qsort_safe'
44
Returning from 'qsort_safe'
2332
2333 width = DECIMAL_STR_WIDTH(pids[n-1])({ typeof(pids[n-1]) _x_ = (pids[n-1]); unsigned ans = 1; while
((_x_ /= 10) != 0) ans++; ans; })
;
45
Assigned value is garbage or undefined
2334
2335 for (i = 0; i < n; i++) {
2336 _cleanup_free___attribute__((cleanup(freep))) char *e = NULL((void*)0);
2337 const char *special;
2338 bool_Bool more;
2339
2340 name = hashmap_get(cg->pids, PID_TO_PTR(pids[i]));
2341 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/shared/bus-unit-util.c"
, 2341, __PRETTY_FUNCTION__); } while (0)
;
2342
2343 if (n_columns != 0) {
2344 unsigned k;
2345
2346 k = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U)__extension__ ({ const typeof((__extension__ ({ const typeof(
(n_columns)) __unique_prefix_A40 = ((n_columns)); const typeof
((2U + width + 1U)) __unique_prefix_B41 = ((2U + width + 1U))
; __unique_prefix_A40 > __unique_prefix_B41 ? __unique_prefix_A40
- __unique_prefix_B41 : 0; }))) __unique_prefix_A42 = ((__extension__
({ const typeof((n_columns)) __unique_prefix_A40 = ((n_columns
)); const typeof((2U + width + 1U)) __unique_prefix_B41 = ((2U
+ width + 1U)); __unique_prefix_A40 > __unique_prefix_B41
? __unique_prefix_A40 - __unique_prefix_B41 : 0; }))); const
typeof((20U)) __unique_prefix_B43 = ((20U)); __unique_prefix_A42
> __unique_prefix_B43 ? __unique_prefix_A42 : __unique_prefix_B43
; })
;
2347
2348 e = ellipsize(name, k, 100);
2349 if (e)
2350 name = e;
2351 }
2352
2353 more = i+1 < n || cg->children;
2354 special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
2355
2356 fprintf(stdoutstdout, "%s%s%*"PID_PRI"i"" %s\n",
2357 prefix,
2358 special,
2359 width, pids[i],
2360 name);
2361 }
2362 }
2363
2364 if (cg->children) {
2365 struct CGroupInfo **children, *child;
2366 size_t n = 0, i;
2367
2368 /* Order subcgroups by their name */
2369 children = newa(struct CGroupInfo*, cg->n_children)({ do { if ((__builtin_expect(!!(!(!size_multiply_overflow(sizeof
(struct CGroupInfo*), cg->n_children))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("!size_multiply_overflow(sizeof(struct CGroupInfo*), cg->n_children)"
), "../src/shared/bus-unit-util.c", 2369, __PRETTY_FUNCTION__
); } while (0); (struct CGroupInfo**) __builtin_alloca (sizeof
(struct CGroupInfo*)*(cg->n_children)); })
;
2370 LIST_FOREACH(siblings, child, cg->children)for ((child) = (cg->children); (child); (child) = (child)->
siblings_next)
2371 children[n++] = child;
2372 assert(n == cg->n_children)do { if ((__builtin_expect(!!(!(n == cg->n_children)),0)))
log_assert_failed_realm(LOG_REALM_SYSTEMD, ("n == cg->n_children"
), "../src/shared/bus-unit-util.c", 2372, __PRETTY_FUNCTION__
); } while (0)
;
2373 qsort_safe(children, n, sizeof(struct CGroupInfo*), cgroup_info_compare_func);
2374
2375 if (n_columns != 0)
2376 n_columns = MAX(LESS_BY(n_columns, 2U), 20U)__extension__ ({ const typeof((__extension__ ({ const typeof(
(n_columns)) __unique_prefix_A44 = ((n_columns)); const typeof
((2U)) __unique_prefix_B45 = ((2U)); __unique_prefix_A44 >
__unique_prefix_B45 ? __unique_prefix_A44 - __unique_prefix_B45
: 0; }))) __unique_prefix_A46 = ((__extension__ ({ const typeof
((n_columns)) __unique_prefix_A44 = ((n_columns)); const typeof
((2U)) __unique_prefix_B45 = ((2U)); __unique_prefix_A44 >
__unique_prefix_B45 ? __unique_prefix_A44 - __unique_prefix_B45
: 0; }))); const typeof((20U)) __unique_prefix_B47 = ((20U))
; __unique_prefix_A46 > __unique_prefix_B47 ? __unique_prefix_A46
: __unique_prefix_B47; })
;
2377
2378 for (i = 0; i < n; i++) {
2379 _cleanup_free___attribute__((cleanup(freep))) char *pp = NULL((void*)0);
2380 const char *name, *special;
2381 bool_Bool more;
2382
2383 child = children[i];
2384
2385 name = strrchr(child->cgroup_path, '/');
2386 if (!name)
2387 return -EINVAL22;
2388 name++;
2389
2390 more = i+1 < n;
2391 special = special_glyph(more ? TREE_BRANCH : TREE_RIGHT);
2392
2393 fputs(prefix, stdoutstdout);
2394 fputs(special, stdoutstdout);
2395 fputs(name, stdoutstdout);
2396 fputc('\n', stdoutstdout);
2397
2398 special = special_glyph(more ? TREE_VERTICAL : TREE_SPACE);
2399
2400 pp = strappend(prefix, special);
2401 if (!pp)
2402 return -ENOMEM12;
2403
2404 r = dump_processes(cgroups, child->cgroup_path, pp, n_columns, flags);
2405 if (r < 0)
2406 return r;
2407 }
2408 }
2409
2410 cg->done = true1;
2411 return 0;
2412}
2413
2414static int dump_extra_processes(
2415 Hashmap *cgroups,
2416 const char *prefix,
2417 unsigned n_columns,
2418 OutputFlags flags) {
2419
2420 _cleanup_free___attribute__((cleanup(freep))) pid_t *pids = NULL((void*)0);
2421 _cleanup_hashmap_free___attribute__((cleanup(hashmap_freep))) Hashmap *names = NULL((void*)0);
2422 struct CGroupInfo *cg;
2423 size_t n_allocated = 0, n = 0, k;
2424 Iterator i;
2425 int width, r;
2426
2427 /* Prints the extra processes, i.e. those that are in cgroups we haven't displayed yet. We show them as
2428 * combined, sorted, linear list. */
2429
2430 HASHMAP_FOREACH(cg, cgroups, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((cgroups), &(i)
, (void**)&(cg), ((void*)0)); )
{
2431 const char *name;
2432 void *pidp;
2433 Iterator j;
2434
2435 if (cg->done)
2436 continue;
2437
2438 if (hashmap_isempty(cg->pids))
2439 continue;
2440
2441 r = hashmap_ensure_allocated(&names, &trivial_hash_ops)internal_hashmap_ensure_allocated(&names, &trivial_hash_ops
)
;
2442 if (r < 0)
2443 return r;
2444
2445 if (!GREEDY_REALLOC(pids, n_allocated, n + hashmap_size(cg->pids))greedy_realloc((void**) &(pids), &(n_allocated), (n +
hashmap_size(cg->pids)), sizeof((pids)[0]))
)
2446 return -ENOMEM12;
2447
2448 HASHMAP_FOREACH_KEY(name, pidp, cg->pids, j)for ((j) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((cg->pids), &
(j), (void**)&(name), (const void**) &(pidp)); )
{
2449 pids[n++] = PTR_TO_PID(pidp);
2450
2451 r = hashmap_put(names, pidp, (void*) name);
2452 if (r < 0)
2453 return r;
2454 }
2455 }
2456
2457 if (n == 0)
2458 return 0;
2459
2460 qsort_safe(pids, n, sizeof(pid_t), pid_compare_func);
2461 width = DECIMAL_STR_WIDTH(pids[n-1])({ typeof(pids[n-1]) _x_ = (pids[n-1]); unsigned ans = 1; while
((_x_ /= 10) != 0) ans++; ans; })
;
2462
2463 for (k = 0; k < n; k++) {
2464 _cleanup_free___attribute__((cleanup(freep))) char *e = NULL((void*)0);
2465 const char *name;
2466
2467 name = hashmap_get(names, PID_TO_PTR(pids[k]));
2468 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/shared/bus-unit-util.c"
, 2468, __PRETTY_FUNCTION__); } while (0)
;
2469
2470 if (n_columns != 0) {
2471 unsigned z;
2472
2473 z = MAX(LESS_BY(n_columns, 2U + width + 1U), 20U)__extension__ ({ const typeof((__extension__ ({ const typeof(
(n_columns)) __unique_prefix_A48 = ((n_columns)); const typeof
((2U + width + 1U)) __unique_prefix_B49 = ((2U + width + 1U))
; __unique_prefix_A48 > __unique_prefix_B49 ? __unique_prefix_A48
- __unique_prefix_B49 : 0; }))) __unique_prefix_A50 = ((__extension__
({ const typeof((n_columns)) __unique_prefix_A48 = ((n_columns
)); const typeof((2U + width + 1U)) __unique_prefix_B49 = ((2U
+ width + 1U)); __unique_prefix_A48 > __unique_prefix_B49
? __unique_prefix_A48 - __unique_prefix_B49 : 0; }))); const
typeof((20U)) __unique_prefix_B51 = ((20U)); __unique_prefix_A50
> __unique_prefix_B51 ? __unique_prefix_A50 : __unique_prefix_B51
; })
;
2474
2475 e = ellipsize(name, z, 100);
2476 if (e)
2477 name = e;
2478 }
2479
2480 fprintf(stdoutstdout, "%s%s %*" PID_PRI"i" " %s\n",
2481 prefix,
2482 special_glyph(TRIANGULAR_BULLET),
2483 width, pids[k],
2484 name);
2485 }
2486
2487 return 0;
2488}
2489
2490int unit_show_processes(
2491 sd_bus *bus,
2492 const char *unit,
2493 const char *cgroup_path,
2494 const char *prefix,
2495 unsigned n_columns,
2496 OutputFlags flags,
2497 sd_bus_error *error) {
2498
2499 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
2500 Hashmap *cgroups = NULL((void*)0);
2501 struct CGroupInfo *cg;
2502 int r;
2503
2504 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/shared/bus-unit-util.c",
2504, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'bus' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
2505 assert(unit)do { if ((__builtin_expect(!!(!(unit)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("unit"), "../src/shared/bus-unit-util.c"
, 2505, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'unit' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
2506
2507 if (flags & OUTPUT_FULL_WIDTH)
7
Assuming the condition is false
8
Taking false branch
2508 n_columns = 0;
2509 else if (n_columns <= 0)
9
Assuming 'n_columns' is > 0
10
Taking false branch
2510 n_columns = columns();
2511
2512 prefix = strempty(prefix);
2513
2514 r = sd_bus_call_method(
2515 bus,
2516 "org.freedesktop.systemd1",
2517 "/org/freedesktop/systemd1",
2518 "org.freedesktop.systemd1.Manager",
2519 "GetUnitProcesses",
2520 error,
2521 &reply,
2522 "s",
2523 unit);
2524 if (r < 0)
11
Assuming 'r' is >= 0
12
Taking false branch
2525 return r;
2526
2527 cgroups = hashmap_new(&path_hash_ops)internal_hashmap_new(&path_hash_ops );
2528 if (!cgroups)
13
Assuming 'cgroups' is non-null
14
Taking false branch
2529 return -ENOMEM12;
2530
2531 r = sd_bus_message_enter_container(reply, 'a', "(sus)");
2532 if (r < 0)
15
Assuming 'r' is >= 0
16
Taking false branch
2533 goto finish;
2534
2535 for (;;) {
17
Loop condition is true. Entering loop body
2536 const char *path = NULL((void*)0), *name = NULL((void*)0);
2537 uint32_t pid;
2538
2539 r = sd_bus_message_read(reply, "(sus)", &path, &pid, &name);
2540 if (r < 0)
18
Assuming 'r' is >= 0
19
Taking false branch
2541 goto finish;
2542 if (r == 0)
20
Assuming 'r' is equal to 0
21
Taking true branch
2543 break;
22
Execution continues on line 2550
2544
2545 r = add_process(cgroups, path, pid, name);
2546 if (r < 0)
2547 goto finish;
2548 }
2549
2550 r = sd_bus_message_exit_container(reply);
2551 if (r < 0)
23
Assuming 'r' is >= 0
24
Taking false branch
2552 goto finish;
2553
2554 r = dump_processes(cgroups, cgroup_path, prefix, n_columns, flags);
25
Calling 'dump_processes'
2555 if (r < 0)
2556 goto finish;
2557
2558 r = dump_extra_processes(cgroups, prefix, n_columns, flags);
2559
2560finish:
2561 while ((cg = hashmap_first(cgroups)))
2562 remove_cgroup(cgroups, cg);
2563
2564 hashmap_free(cgroups);
2565
2566 return r;
2567}
2568
2569int unit_load_state(sd_bus *bus, const char *name, char **load_state) {
2570 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2571 _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0);
2572 int r;
2573
2574 path = unit_dbus_path_from_name(name);
2575 if (!path)
2576 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/shared/bus-unit-util.c"
, 2576, __func__)
;
2577
2578 /* This function warns on it's own, because otherwise it'd be awkward to pass
2579 * the dbus error message around. */
2580
2581 r = sd_bus_get_property_string(
2582 bus,
2583 "org.freedesktop.systemd1",
2584 path,
2585 "org.freedesktop.systemd1.Unit",
2586 "LoadState",
2587 &error,
2588 load_state);
2589 if (r < 0)
2590 return log_error_errno(r, "Failed to get load state of %s: %s", name, bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/shared/bus-unit-util.c", 2590, __func__, "Failed to get load state of %s: %s"
, name, bus_error_message(&error, r)) : -abs(_e); })
;
2591
2592 return 0;
2593}

../src/basic/hashmap.h

1/* SPDX-License-Identifier: LGPL-2.1+ */
2#pragma once
3
4
5#include <limits.h>
6#include <stdbool.h>
7#include <stddef.h>
8
9#include "hash-funcs.h"
10#include "macro.h"
11#include "util.h"
12
13/*
14 * A hash table implementation. As a minor optimization a NULL hashmap object
15 * will be treated as empty hashmap for all read operations. That way it is not
16 * necessary to instantiate an object for each Hashmap use.
17 *
18 * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
19 * the implemention will:
20 * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
21 * - perform extra checks for invalid use of iterators
22 */
23
24#define HASH_KEY_SIZE16 16
25
26/* The base type for all hashmap and set types. Many functions in the
27 * implementation take (HashmapBase*) parameters and are run-time polymorphic,
28 * though the API is not meant to be polymorphic (do not call functions
29 * internal_*() directly). */
30typedef struct HashmapBase HashmapBase;
31
32/* Specific hashmap/set types */
33typedef struct Hashmap Hashmap; /* Maps keys to values */
34typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */
35typedef struct Set Set; /* Stores just keys */
36
37typedef struct IteratedCache IteratedCache; /* Caches the iterated order of one of the above */
38
39/* Ideally the Iterator would be an opaque struct, but it is instantiated
40 * by hashmap users, so the definition has to be here. Do not use its fields
41 * directly. */
42typedef struct {
43 unsigned idx; /* index of an entry to be iterated next */
44 const void *next_key; /* expected value of that entry's key pointer */
45#if ENABLE_DEBUG_HASHMAP0
46 unsigned put_count; /* hashmap's put_count recorded at start of iteration */
47 unsigned rem_count; /* hashmap's rem_count in previous iteration */
48 unsigned prev_idx; /* idx in previous iteration */
49#endif
50} Iterator;
51
52#define _IDX_ITERATOR_FIRST((2147483647 *2U +1U) - 1) (UINT_MAX(2147483647 *2U +1U) - 1)
53#define ITERATOR_FIRST((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .next_key = (
(void*)0) })
((Iterator) { .idx = _IDX_ITERATOR_FIRST((2147483647 *2U +1U) - 1), .next_key = NULL((void*)0) })
54
55/* Macros for type checking */
56#define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h)(__builtin_types_compatible_p(typeof(h), HashmapBase*) || __builtin_types_compatible_p
(typeof(h), Hashmap*) || __builtin_types_compatible_p(typeof(
h), OrderedHashmap*) || __builtin_types_compatible_p(typeof(h
), Set*))
\
57 (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \
58 __builtin_types_compatible_p(typeof(h), Hashmap*) || \
59 __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \
60 __builtin_types_compatible_p(typeof(h), Set*))
61
62#define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h)(__builtin_types_compatible_p(typeof(h), Hashmap*) || __builtin_types_compatible_p
(typeof(h), OrderedHashmap*))
\
63 (__builtin_types_compatible_p(typeof(h), Hashmap*) || \
64 __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \
65
66#define HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
\
67 __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h)(__builtin_types_compatible_p(typeof(h), HashmapBase*) || __builtin_types_compatible_p
(typeof(h), Hashmap*) || __builtin_types_compatible_p(typeof(
h), OrderedHashmap*) || __builtin_types_compatible_p(typeof(h
), Set*))
, \
68 (HashmapBase*)(h), \
69 (void)0)
70
71#define PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
\
72 __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h)(__builtin_types_compatible_p(typeof(h), Hashmap*) || __builtin_types_compatible_p
(typeof(h), OrderedHashmap*))
, \
73 (Hashmap*)(h), \
74 (void)0)
75
76#if ENABLE_DEBUG_HASHMAP0
77# define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
78# define HASHMAP_DEBUG_SRC_ARGS , __func__, __FILE__"../src/basic/hashmap.h", __LINE__78
79# define HASHMAP_DEBUG_PASS_ARGS , func, file, line
80#else
81# define HASHMAP_DEBUG_PARAMS
82# define HASHMAP_DEBUG_SRC_ARGS
83# define HASHMAP_DEBUG_PASS_ARGS
84#endif
85
86Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
87OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
88#define hashmap_new(ops)internal_hashmap_new(ops ) internal_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
89#define ordered_hashmap_new(ops)internal_ordered_hashmap_new(ops ) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
90
91HashmapBase *internal_hashmap_free(HashmapBase *h);
92static inline Hashmap *hashmap_free(Hashmap *h) {
93 return (void*)internal_hashmap_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
94}
95static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
96 return (void*)internal_hashmap_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
97}
98
99HashmapBase *internal_hashmap_free_free(HashmapBase *h);
100static inline Hashmap *hashmap_free_free(Hashmap *h) {
101 return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
102}
103static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
104 return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
105}
106
107Hashmap *hashmap_free_free_free(Hashmap *h);
108static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
109 return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
);
110}
111
112IteratedCache *iterated_cache_free(IteratedCache *cache);
113int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
114
115HashmapBase *internal_hashmap_copy(HashmapBase *h);
116static inline Hashmap *hashmap_copy(Hashmap *h) {
117 return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
118}
119static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
120 return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
121}
122
123int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
124int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
125#define hashmap_ensure_allocated(h, ops)internal_hashmap_ensure_allocated(h, ops ) internal_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
126#define ordered_hashmap_ensure_allocated(h, ops)internal_ordered_hashmap_ensure_allocated(h, ops ) internal_ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
127
128IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h);
129static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
130 return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
131}
132static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
133 return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
134}
135
136int hashmap_put(Hashmap *h, const void *key, void *value);
137static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
138 return hashmap_put(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, value);
139}
140
141int hashmap_update(Hashmap *h, const void *key, void *value);
142static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
143 return hashmap_update(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, value);
144}
145
146int hashmap_replace(Hashmap *h, const void *key, void *value);
147static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
148 return hashmap_replace(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, value);
149}
150
151void *internal_hashmap_get(HashmapBase *h, const void *key);
152static inline void *hashmap_get(Hashmap *h, const void *key) {
153 return internal_hashmap_get(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
154}
155static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
156 return internal_hashmap_get(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
157}
158
159void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
160static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
161 return hashmap_get2(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, rkey);
162}
163
164bool_Bool internal_hashmap_contains(HashmapBase *h, const void *key);
165static inline bool_Bool hashmap_contains(Hashmap *h, const void *key) {
166 return internal_hashmap_contains(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
167}
168static inline bool_Bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
169 return internal_hashmap_contains(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
170}
171
172void *internal_hashmap_remove(HashmapBase *h, const void *key);
173static inline void *hashmap_remove(Hashmap *h, const void *key) {
174 return internal_hashmap_remove(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
175}
176static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
177 return internal_hashmap_remove(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, key);
178}
179
180void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
181static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
182 return hashmap_remove2(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, rkey);
183}
184
185void *hashmap_remove_value(Hashmap *h, const void *key, void *value);
186static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
187 return hashmap_remove_value(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, key, value);
188}
189
190int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
191static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
192 return hashmap_remove_and_put(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, old_key, new_key, value);
193}
194
195int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
196static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
197 return hashmap_remove_and_replace(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, old_key, new_key, value);
198}
199
200/* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
201 * should just work, allow this by having looser type-checking here. */
202int internal_hashmap_merge(Hashmap *h, Hashmap *other);
203#define hashmap_merge(h, other)internal_hashmap_merge(__builtin_choose_expr((__builtin_types_compatible_p
(typeof(h), Hashmap*) || __builtin_types_compatible_p(typeof(
h), OrderedHashmap*)), (Hashmap*)(h), (void)0), __builtin_choose_expr
((__builtin_types_compatible_p(typeof(other), Hashmap*) || __builtin_types_compatible_p
(typeof(other), OrderedHashmap*)), (Hashmap*)(other), (void)0
))
internal_hashmap_merge(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
, PLAIN_HASHMAP(other)__builtin_choose_expr((__builtin_types_compatible_p(typeof(other
), Hashmap*) || __builtin_types_compatible_p(typeof(other), OrderedHashmap
*)), (Hashmap*)(other), (void)0)
)
204#define ordered_hashmap_merge(h, other)internal_hashmap_merge(__builtin_choose_expr((__builtin_types_compatible_p
(typeof(h), Hashmap*) || __builtin_types_compatible_p(typeof(
h), OrderedHashmap*)), (Hashmap*)(h), (void)0), __builtin_choose_expr
((__builtin_types_compatible_p(typeof(other), Hashmap*) || __builtin_types_compatible_p
(typeof(other), OrderedHashmap*)), (Hashmap*)(other), (void)0
))
hashmap_merge(h, other)internal_hashmap_merge(__builtin_choose_expr((__builtin_types_compatible_p
(typeof(h), Hashmap*) || __builtin_types_compatible_p(typeof(
h), OrderedHashmap*)), (Hashmap*)(h), (void)0), __builtin_choose_expr
((__builtin_types_compatible_p(typeof(other), Hashmap*) || __builtin_types_compatible_p
(typeof(other), OrderedHashmap*)), (Hashmap*)(other), (void)0
))
205
206int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
207static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
208 return internal_hashmap_reserve(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, entries_add);
209}
210static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
211 return internal_hashmap_reserve(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, entries_add);
212}
213
214int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
215/* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
216static inline int hashmap_move(Hashmap *h, Hashmap *other) {
217 return internal_hashmap_move(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, HASHMAP_BASE(other)__builtin_choose_expr((__builtin_types_compatible_p(typeof(other
), HashmapBase*) || __builtin_types_compatible_p(typeof(other
), Hashmap*) || __builtin_types_compatible_p(typeof(other), OrderedHashmap
*) || __builtin_types_compatible_p(typeof(other), Set*)), (HashmapBase
*)(other), (void)0)
);
218}
219static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
220 return internal_hashmap_move(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, HASHMAP_BASE(other)__builtin_choose_expr((__builtin_types_compatible_p(typeof(other
), HashmapBase*) || __builtin_types_compatible_p(typeof(other
), Hashmap*) || __builtin_types_compatible_p(typeof(other), OrderedHashmap
*) || __builtin_types_compatible_p(typeof(other), Set*)), (HashmapBase
*)(other), (void)0)
);
221}
222
223int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
224static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
225 return internal_hashmap_move_one(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, HASHMAP_BASE(other)__builtin_choose_expr((__builtin_types_compatible_p(typeof(other
), HashmapBase*) || __builtin_types_compatible_p(typeof(other
), Hashmap*) || __builtin_types_compatible_p(typeof(other), OrderedHashmap
*) || __builtin_types_compatible_p(typeof(other), Set*)), (HashmapBase
*)(other), (void)0)
, key);
226}
227static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
228 return internal_hashmap_move_one(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, HASHMAP_BASE(other)__builtin_choose_expr((__builtin_types_compatible_p(typeof(other
), HashmapBase*) || __builtin_types_compatible_p(typeof(other
), Hashmap*) || __builtin_types_compatible_p(typeof(other), OrderedHashmap
*) || __builtin_types_compatible_p(typeof(other), Set*)), (HashmapBase
*)(other), (void)0)
, key);
229}
230
231unsigned internal_hashmap_size(HashmapBase *h) _pure___attribute__ ((pure));
232static inline unsigned hashmap_size(Hashmap *h) {
233 return internal_hashmap_size(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
234}
235static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
236 return internal_hashmap_size(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
237}
238
239static inline bool_Bool hashmap_isempty(Hashmap *h) {
240 return hashmap_size(h) == 0;
32
Assuming the condition is false
33
Returning zero, which participates in a condition later
241}
242static inline bool_Bool ordered_hashmap_isempty(OrderedHashmap *h) {
243 return ordered_hashmap_size(h) == 0;
244}
245
246unsigned internal_hashmap_buckets(HashmapBase *h) _pure___attribute__ ((pure));
247static inline unsigned hashmap_buckets(Hashmap *h) {
248 return internal_hashmap_buckets(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
249}
250static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
251 return internal_hashmap_buckets(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
252}
253
254bool_Bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
255static inline bool_Bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
256 return internal_hashmap_iterate(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, i, value, key);
257}
258static inline bool_Bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
259 return internal_hashmap_iterate(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
, i, value, key);
260}
261
262void internal_hashmap_clear(HashmapBase *h);
263static inline void hashmap_clear(Hashmap *h) {
264 internal_hashmap_clear(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
265}
266static inline void ordered_hashmap_clear(OrderedHashmap *h) {
267 internal_hashmap_clear(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
268}
269
270void internal_hashmap_clear_free(HashmapBase *h);
271static inline void hashmap_clear_free(Hashmap *h) {
272 internal_hashmap_clear_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
273}
274static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
275 internal_hashmap_clear_free(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
276}
277
278void hashmap_clear_free_free(Hashmap *h);
279static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
280 hashmap_clear_free_free(PLAIN_HASHMAP(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, Hashmap*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap
*)), (Hashmap*)(h), (void)0)
);
281}
282
283/*
284 * Note about all *_first*() functions
285 *
286 * For plain Hashmaps and Sets the order of entries is undefined.
287 * The functions find whatever entry is first in the implementation
288 * internal order.
289 *
290 * Only for OrderedHashmaps the order is well defined and finding
291 * the first entry is O(1).
292 */
293
294void *internal_hashmap_steal_first(HashmapBase *h);
295static inline void *hashmap_steal_first(Hashmap *h) {
296 return internal_hashmap_steal_first(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
297}
298static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
299 return internal_hashmap_steal_first(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
300}
301
302void *internal_hashmap_steal_first_key(HashmapBase *h);
303static inline void *hashmap_steal_first_key(Hashmap *h) {
304 return internal_hashmap_steal_first_key(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
305}
306static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
307 return internal_hashmap_steal_first_key(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
308}
309
310void *internal_hashmap_first_key(HashmapBase *h) _pure___attribute__ ((pure));
311static inline void *hashmap_first_key(Hashmap *h) {
312 return internal_hashmap_first_key(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
313}
314static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
315 return internal_hashmap_first_key(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
316}
317
318void *internal_hashmap_first(HashmapBase *h) _pure___attribute__ ((pure));
319static inline void *hashmap_first(Hashmap *h) {
320 return internal_hashmap_first(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
321}
322static inline void *ordered_hashmap_first(OrderedHashmap *h) {
323 return internal_hashmap_first(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
324}
325
326#define hashmap_clear_with_destructor(_s, _f)({ void *_item; while ((_item = hashmap_steal_first(_s))) _f(
_item); })
\
327 ({ \
328 void *_item; \
329 while ((_item = hashmap_steal_first(_s))) \
330 _f(_item); \
331 })
332#define hashmap_free_with_destructor(_s, _f)({ ({ void *_item; while ((_item = hashmap_steal_first(_s))) _f
(_item); }); hashmap_free(_s); })
\
333 ({ \
334 hashmap_clear_with_destructor(_s, _f)({ void *_item; while ((_item = hashmap_steal_first(_s))) _f(
_item); })
; \
335 hashmap_free(_s); \
336 })
337#define ordered_hashmap_clear_with_destructor(_s, _f)({ void *_item; while ((_item = ordered_hashmap_steal_first(_s
))) _f(_item); })
\
338 ({ \
339 void *_item; \
340 while ((_item = ordered_hashmap_steal_first(_s))) \
341 _f(_item); \
342 })
343#define ordered_hashmap_free_with_destructor(_s, _f)({ ({ void *_item; while ((_item = ordered_hashmap_steal_first
(_s))) _f(_item); }); ordered_hashmap_free(_s); })
\
344 ({ \
345 ordered_hashmap_clear_with_destructor(_s, _f)({ void *_item; while ((_item = ordered_hashmap_steal_first(_s
))) _f(_item); })
; \
346 ordered_hashmap_free(_s); \
347 })
348
349/* no hashmap_next */
350void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
351
352char **internal_hashmap_get_strv(HashmapBase *h);
353static inline char **hashmap_get_strv(Hashmap *h) {
354 return internal_hashmap_get_strv(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
355}
356static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
357 return internal_hashmap_get_strv(HASHMAP_BASE(h)__builtin_choose_expr((__builtin_types_compatible_p(typeof(h)
, HashmapBase*) || __builtin_types_compatible_p(typeof(h), Hashmap
*) || __builtin_types_compatible_p(typeof(h), OrderedHashmap*
) || __builtin_types_compatible_p(typeof(h), Set*)), (HashmapBase
*)(h), (void)0)
);
358}
359
360/*
361 * Hashmaps are iterated in unpredictable order.
362 * OrderedHashmaps are an exception to this. They are iterated in the order
363 * the entries were inserted.
364 * It is safe to remove the current entry.
365 */
366#define HASHMAP_FOREACH(e, h, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((h), &(i), (void
**)&(e), ((void*)0)); )
\
367 for ((i) = ITERATOR_FIRST((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .next_key = (
(void*)0) })
; hashmap_iterate((h), &(i), (void**)&(e), NULL((void*)0)); )
368
369#define ORDERED_HASHMAP_FOREACH(e, h, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); ordered_hashmap_iterate((h), &(
i), (void**)&(e), ((void*)0)); )
\
370 for ((i) = ITERATOR_FIRST((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .next_key = (
(void*)0) })
; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL((void*)0)); )
371
372#define HASHMAP_FOREACH_KEY(e, k, h, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((h), &(i), (void
**)&(e), (const void**) &(k)); )
\
373 for ((i) = ITERATOR_FIRST((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .next_key = (
(void*)0) })
; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
374
375#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); ordered_hashmap_iterate((h), &(
i), (void**)&(e), (const void**) &(k)); )
\
376 for ((i) = ITERATOR_FIRST((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .next_key = (
(void*)0) })
; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
377
378DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free)static inline void hashmap_freep(Hashmap* *p) { if (*p) hashmap_free
(*p); }
;
379DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free)static inline void hashmap_free_freep(Hashmap* *p) { if (*p) hashmap_free_free
(*p); }
;
380DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free)static inline void hashmap_free_free_freep(Hashmap* *p) { if (
*p) hashmap_free_free_free(*p); }
;
381DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free)static inline void ordered_hashmap_freep(OrderedHashmap* *p) {
if (*p) ordered_hashmap_free(*p); }
;
382DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free)static inline void ordered_hashmap_free_freep(OrderedHashmap*
*p) { if (*p) ordered_hashmap_free_free(*p); }
;
383DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free)static inline void ordered_hashmap_free_free_freep(OrderedHashmap
* *p) { if (*p) ordered_hashmap_free_free_free(*p); }
;
384
385#define _cleanup_hashmap_free___attribute__((cleanup(hashmap_freep))) _cleanup_(hashmap_freep)__attribute__((cleanup(hashmap_freep)))
386#define _cleanup_hashmap_free_free___attribute__((cleanup(hashmap_free_freep))) _cleanup_(hashmap_free_freep)__attribute__((cleanup(hashmap_free_freep)))
387#define _cleanup_hashmap_free_free_free___attribute__((cleanup(hashmap_free_free_freep))) _cleanup_(hashmap_free_free_freep)__attribute__((cleanup(hashmap_free_free_freep)))
388#define _cleanup_ordered_hashmap_free___attribute__((cleanup(ordered_hashmap_freep))) _cleanup_(ordered_hashmap_freep)__attribute__((cleanup(ordered_hashmap_freep)))
389#define _cleanup_ordered_hashmap_free_free___attribute__((cleanup(ordered_hashmap_free_freep))) _cleanup_(ordered_hashmap_free_freep)__attribute__((cleanup(ordered_hashmap_free_freep)))
390#define _cleanup_ordered_hashmap_free_free_free___attribute__((cleanup(ordered_hashmap_free_free_freep))) _cleanup_(ordered_hashmap_free_free_freep)__attribute__((cleanup(ordered_hashmap_free_free_freep)))
391
392DEFINE_TRIVIAL_CLEANUP_FUNC(IteratedCache*, iterated_cache_free)static inline void iterated_cache_freep(IteratedCache* *p) { if
(*p) iterated_cache_free(*p); }
;
393
394#define _cleanup_iterated_cache_free___attribute__((cleanup(iterated_cache_freep))) _cleanup_(iterated_cache_freep)__attribute__((cleanup(iterated_cache_freep)))

../src/basic/util.h

1/* SPDX-License-Identifier: LGPL-2.1+ */
2#pragma once
3
4#include <alloca.h>
5#include <errno(*__errno_location ()).h>
6#include <fcntl.h>
7#include <inttypes.h>
8#include <limits.h>
9#include <locale.h>
10#include <stdarg.h>
11#include <stdbool.h>
12#include <stddef.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <sys/inotify.h>
18#include <sys/socket.h>
19#include <sys/stat.h>
20#include <sys/statfs.h>
21#include <sys/sysmacros.h>
22#include <sys/types.h>
23#include <time.h>
24#include <unistd.h>
25
26#include "format-util.h"
27#include "macro.h"
28#include "missing.h"
29#include "time-util.h"
30
31size_t page_size(void) _pure___attribute__ ((pure));
32#define PAGE_ALIGN(l)ALIGN_TO((l), page_size()) ALIGN_TO((l), page_size())
33
34static inline const char* yes_no(bool_Bool b) {
35 return b ? "yes" : "no";
36}
37
38static inline const char* true_false(bool_Bool b) {
39 return b ? "true" : "false";
40}
41
42static inline const char* one_zero(bool_Bool b) {
43 return b ? "1" : "0";
44}
45
46static inline const char* enable_disable(bool_Bool b) {
47 return b ? "enable" : "disable";
48}
49
50bool_Bool plymouth_running(void);
51
52bool_Bool display_is_local(const char *display) _pure___attribute__ ((pure));
53int socket_from_display(const char *display, char **path);
54
55#define NULSTR_FOREACH(i, l)for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) \
56 for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
57
58#define NULSTR_FOREACH_PAIR(i, j, l)for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (
i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
\
59 for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
60
61extern int saved_argc;
62extern char **saved_argv;
63
64bool_Bool kexec_loaded(void);
65
66int prot_from_flags(int flags) _const___attribute__ ((const));
67
68bool_Bool in_initrd(void);
69void in_initrd_force(bool_Bool value);
70
71void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
72 int (*compar) (const void *, const void *, void *),
73 void *arg);
74
75/**
76 * Normal bsearch requires base to be nonnull. Here were require
77 * that only if nmemb > 0.
78 */
79static inline void* bsearch_safe(const void *key, const void *base,
80 size_t nmemb, size_t size, comparison_fn_t compar) {
81 if (nmemb <= 0)
82 return NULL((void*)0);
83
84 assert(base)do { if ((__builtin_expect(!!(!(base)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("base"), "../src/basic/util.h", 84, __PRETTY_FUNCTION__
); } while (0)
;
85 return bsearch(key, base, nmemb, size, compar);
86}
87
88/**
89 * Normal qsort requires base to be nonnull. Here were require
90 * that only if nmemb > 0.
91 */
92static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
93 if (nmemb
42.1
'nmemb' is <= 1
42.1
'nmemb' is <= 1
42.1
'nmemb' is <= 1
<= 1)
43
Taking true branch
94 return;
95
96 assert(base)do { if ((__builtin_expect(!!(!(base)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("base"), "../src/basic/util.h", 96, __PRETTY_FUNCTION__
); } while (0)
;
97 qsort(base, nmemb, size, compar);
98}
99
100/* A wrapper around the above, but that adds typesafety: the element size is automatically derived from the type and so
101 * is the prototype for the comparison function */
102#define typesafe_qsort(p, n, func)({ int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func
; qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_
); })
\
103 ({ \
104 int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
105 qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \
106 })
107
108static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void *userdata) {
109 if (nmemb <= 1)
110 return;
111
112 assert(base)do { if ((__builtin_expect(!!(!(base)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("base"), "../src/basic/util.h", 112, __PRETTY_FUNCTION__
); } while (0)
;
113 qsort_r(base, nmemb, size, compar, userdata);
114}
115
116/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */
117static inline void memcpy_safe(void *dst, const void *src, size_t n) {
118 if (n == 0)
119 return;
120 assert(src)do { if ((__builtin_expect(!!(!(src)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("src"), "../src/basic/util.h", 120, __PRETTY_FUNCTION__
); } while (0)
;
121 memcpy(dst, src, n);
122}
123
124/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */
125static inline int memcmp_safe(const void *s1, const void *s2, size_t n) {
126 if (n == 0)
127 return 0;
128 assert(s1)do { if ((__builtin_expect(!!(!(s1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s1"), "../src/basic/util.h", 128, __PRETTY_FUNCTION__
); } while (0)
;
129 assert(s2)do { if ((__builtin_expect(!!(!(s2)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s2"), "../src/basic/util.h", 129, __PRETTY_FUNCTION__
); } while (0)
;
130 return memcmp(s1, s2, n);
131}
132
133int on_ac_power(void);
134
135#define memzero(x,l)({ size_t _l_ = (l); void *_x_ = (x); _l_ == 0 ? _x_ : memset
(_x_, 0, _l_); })
\
136 ({ \
137 size_t _l_ = (l); \
138 void *_x_ = (x); \
139 _l_ == 0 ? _x_ : memset(_x_, 0, _l_); \
140 })
141
142#define zero(x)(({ size_t _l_ = (sizeof(x)); void *_x_ = (&(x)); _l_ == 0
? _x_ : memset(_x_, 0, _l_); }))
(memzero(&(x), sizeof(x))({ size_t _l_ = (sizeof(x)); void *_x_ = (&(x)); _l_ == 0
? _x_ : memset(_x_, 0, _l_); })
)
143
144static inline void *mempset(void *s, int c, size_t n) {
145 memset(s, c, n);
146 return (uint8_t*)s + n;
147}
148
149static inline void _reset_errno_(int *saved_errno) {
150 if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
151 return;
152
153 errno(*__errno_location ()) = *saved_errno;
154}
155
156#define PROTECT_ERRNO__attribute__((cleanup(_reset_errno_))) __attribute__((unused
)) int _saved_errno_ = (*__errno_location ())
_cleanup_(_reset_errno_)__attribute__((cleanup(_reset_errno_))) __attribute__((unused)) int _saved_errno_ = errno(*__errno_location ())
157
158#define UNPROTECT_ERRNOdo { (*__errno_location ()) = _saved_errno_; _saved_errno_ = -
1; } while (0)
\
159 do { \
160 errno(*__errno_location ()) = _saved_errno_; \
161 _saved_errno_ = -1; \
162 } while (false0)
163
164static inline int negative_errno(void) {
165 /* This helper should be used to shut up gcc if you know 'errno' is
166 * negative. Instead of "return -errno;", use "return negative_errno();"
167 * It will suppress bogus gcc warnings in case it assumes 'errno' might
168 * be 0 and thus the caller's error-handling might not be triggered. */
169 assert_return(errno > 0, -EINVAL)do { if (!(((__builtin_expect(!!((*__errno_location ()) > 0
),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("errno > 0"), "../src/basic/util.h", 169, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
170 return -errno(*__errno_location ());
171}
172
173static inline unsigned u64log2(uint64_t n) {
174#if __SIZEOF_LONG_LONG__8 == 8
175 return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
176#else
177#error "Wut?"
178#endif
179}
180
181static inline unsigned u32ctz(uint32_t n) {
182#if __SIZEOF_INT__4 == 4
183 return __builtin_ctz(n);
184#else
185#error "Wut?"
186#endif
187}
188
189static inline unsigned log2i(int x) {
190 assert(x > 0)do { if ((__builtin_expect(!!(!(x > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x > 0"), "../src/basic/util.h", 190,
__PRETTY_FUNCTION__); } while (0)
;
191
192 return __SIZEOF_INT__4 * 8 - __builtin_clz(x) - 1;
193}
194
195static inline unsigned log2u(unsigned x) {
196 assert(x > 0)do { if ((__builtin_expect(!!(!(x > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x > 0"), "../src/basic/util.h", 196,
__PRETTY_FUNCTION__); } while (0)
;
197
198 return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
199}
200
201static inline unsigned log2u_round_up(unsigned x) {
202 assert(x > 0)do { if ((__builtin_expect(!!(!(x > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("x > 0"), "../src/basic/util.h", 202,
__PRETTY_FUNCTION__); } while (0)
;
203
204 if (x == 1)
205 return 0;
206
207 return log2u(x - 1) + 1;
208}
209
210int container_get_leader(const char *machine, pid_t *pid);
211
212int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
213int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
214
215uint64_t physical_memory(void);
216uint64_t physical_memory_scale(uint64_t v, uint64_t max);
217
218uint64_t system_tasks_max(void);
219uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
220
221int version(void);
222
223int str_verscmp(const char *s1, const char *s2);
224
225void disable_coredumps(void);