File: | build-scan/../src/shared/bus-unit-util.c |
Warning: | line 2333, column 25 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
39 | int 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 | ||||
101 | DEFINE_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; }; | |||
102 | DEFINE_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; }; | |||
103 | DEFINE_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; }; | |||
104 | DEFINE_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; }; | |||
105 | DEFINE_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; }; | |||
106 | DEFINE_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; }; | |||
107 | DEFINE_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; }; | |||
108 | DEFINE_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; }; | |||
109 | DEFINE_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; }; | |||
110 | DEFINE_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; }; | |||
111 | DEFINE_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 ; }; | |||
112 | DEFINE_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 ; }; | |||
113 | DEFINE_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 ; }; | |||
114 | DEFINE_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 ; }; | |||
115 | DEFINE_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; }; | |||
116 | DEFINE_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 ; }; | |||
117 | DEFINE_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 ; }; | |||
118 | DEFINE_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; }; | |||
119 | DEFINE_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 ; }; | |||
120 | DEFINE_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 ; }; | |||
121 | DEFINE_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 ; }; | |||
122 | DEFINE_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 | ||||
124 | static 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 | ||||
134 | static 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 | ||||
185 | static 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 | ||||
215 | static 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 | ||||
237 | static 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 | ||||
252 | static 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 | ||||
355 | static 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 | ||||
380 | static 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 | ||||
727 | static 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 | ||||
744 | static 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 | ||||
1294 | static 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 | ||||
1311 | static 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 | ||||
1332 | static 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 | ||||
1360 | static 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 | ||||
1475 | static 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 | } | |||
1547 | static 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 | ||||
1593 | static 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 | ||||
1657 | int 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 | ||||
1787 | int 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 | ||||
1802 | typedef 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 | ||||
1813 | static 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 | ||||
1822 | static 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 | ||||
1853 | void 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 | ||||
1870 | int 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 | ||||
1913 | static 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 | ||||
1929 | static 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 | ||||
1952 | static 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 | ||||
1965 | static 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 | ||||
2007 | finish: | |||
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 | ||||
2016 | static 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 | ||||
2072 | int 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 | ||||
2101 | int 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 | ||||
2113 | int 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 | ||||
2123 | int 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 | ||||
2161 | struct 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 | ||||
2174 | static bool_Bool IS_ROOT(const char *p) { | |||
2175 | return isempty(p) || streq(p, "/")(strcmp((p),("/")) == 0); | |||
2176 | } | |||
2177 | ||||
2178 | static 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 | ||||
2244 | static 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 | ||||
2268 | static 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 | ||||
2288 | static 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 | ||||
2297 | static 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); | |||
2308 | ||||
2309 | if (IS_ROOT(cgroup_path)) | |||
2310 | cgroup_path = "/"; | |||
2311 | ||||
2312 | cg = hashmap_get(cgroups, cgroup_path); | |||
2313 | if (!cg) | |||
2314 | return 0; | |||
2315 | ||||
2316 | if (!hashmap_isempty(cg->pids)) { | |||
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))); }); | |||
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)); ) | |||
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); | |||
2331 | qsort_safe(pids, n, sizeof(pid_t), pid_compare_func); | |||
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; }); | |||
| ||||
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 | ||||
2414 | static 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 | ||||
2490 | int 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); | |||
| ||||
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); | |||
2506 | ||||
2507 | if (flags & OUTPUT_FULL_WIDTH) | |||
2508 | n_columns = 0; | |||
2509 | else if (n_columns <= 0) | |||
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) | |||
2525 | return r; | |||
2526 | ||||
2527 | cgroups = hashmap_new(&path_hash_ops)internal_hashmap_new(&path_hash_ops ); | |||
2528 | if (!cgroups) | |||
2529 | return -ENOMEM12; | |||
2530 | ||||
2531 | r = sd_bus_message_enter_container(reply, 'a', "(sus)"); | |||
2532 | if (r < 0) | |||
2533 | goto finish; | |||
2534 | ||||
2535 | for (;;) { | |||
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) | |||
2541 | goto finish; | |||
2542 | if (r == 0) | |||
2543 | break; | |||
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) | |||
2552 | goto finish; | |||
2553 | ||||
2554 | r = dump_processes(cgroups, cgroup_path, prefix, n_columns, flags); | |||
2555 | if (r < 0) | |||
2556 | goto finish; | |||
2557 | ||||
2558 | r = dump_extra_processes(cgroups, prefix, n_columns, flags); | |||
2559 | ||||
2560 | finish: | |||
2561 | while ((cg = hashmap_first(cgroups))) | |||
2562 | remove_cgroup(cgroups, cg); | |||
2563 | ||||
2564 | hashmap_free(cgroups); | |||
2565 | ||||
2566 | return r; | |||
2567 | } | |||
2568 | ||||
2569 | int 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 | } |
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). */ |
30 | typedef struct HashmapBase HashmapBase; |
31 | |
32 | /* Specific hashmap/set types */ |
33 | typedef struct Hashmap Hashmap; /* Maps keys to values */ |
34 | typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */ |
35 | typedef struct Set Set; /* Stores just keys */ |
36 | |
37 | typedef 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. */ |
42 | typedef 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 | |
86 | Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); |
87 | OrderedHashmap *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 | |
91 | HashmapBase *internal_hashmap_free(HashmapBase *h); |
92 | static 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 | } |
95 | static 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 | |
99 | HashmapBase *internal_hashmap_free_free(HashmapBase *h); |
100 | static 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 | } |
103 | static 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 | |
107 | Hashmap *hashmap_free_free_free(Hashmap *h); |
108 | static 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 | |
112 | IteratedCache *iterated_cache_free(IteratedCache *cache); |
113 | int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries); |
114 | |
115 | HashmapBase *internal_hashmap_copy(HashmapBase *h); |
116 | static 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 | } |
119 | static 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 | |
123 | int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); |
124 | int 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 | |
128 | IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h); |
129 | static 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 | } |
132 | static 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 | |
136 | int hashmap_put(Hashmap *h, const void *key, void *value); |
137 | static 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 | |
141 | int hashmap_update(Hashmap *h, const void *key, void *value); |
142 | static 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 | |
146 | int hashmap_replace(Hashmap *h, const void *key, void *value); |
147 | static 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 | |
151 | void *internal_hashmap_get(HashmapBase *h, const void *key); |
152 | static 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 | } |
155 | static 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 | |
159 | void *hashmap_get2(Hashmap *h, const void *key, void **rkey); |
160 | static 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 | |
164 | bool_Bool internal_hashmap_contains(HashmapBase *h, const void *key); |
165 | static 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 | } |
168 | static 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 | |
172 | void *internal_hashmap_remove(HashmapBase *h, const void *key); |
173 | static 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 | } |
176 | static 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 | |
180 | void *hashmap_remove2(Hashmap *h, const void *key, void **rkey); |
181 | static 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 | |
185 | void *hashmap_remove_value(Hashmap *h, const void *key, void *value); |
186 | static 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 | |
190 | int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); |
191 | static 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 | |
195 | int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); |
196 | static 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. */ |
202 | int 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 | |
206 | int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add); |
207 | static 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 | } |
210 | static 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 | |
214 | int internal_hashmap_move(HashmapBase *h, HashmapBase *other); |
215 | /* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */ |
216 | static 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 | } |
219 | static 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 | |
223 | int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key); |
224 | static 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 | } |
227 | static 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 | |
231 | unsigned internal_hashmap_size(HashmapBase *h) _pure___attribute__ ((pure)); |
232 | static 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 | } |
235 | static 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 | |
239 | static inline bool_Bool hashmap_isempty(Hashmap *h) { |
240 | return hashmap_size(h) == 0; |
241 | } |
242 | static inline bool_Bool ordered_hashmap_isempty(OrderedHashmap *h) { |
243 | return ordered_hashmap_size(h) == 0; |
244 | } |
245 | |
246 | unsigned internal_hashmap_buckets(HashmapBase *h) _pure___attribute__ ((pure)); |
247 | static 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 | } |
250 | static 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 | |
254 | bool_Bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key); |
255 | static 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 | } |
258 | static 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 | |
262 | void internal_hashmap_clear(HashmapBase *h); |
263 | static 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 | } |
266 | static 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 | |
270 | void internal_hashmap_clear_free(HashmapBase *h); |
271 | static 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 | } |
274 | static 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 | |
278 | void hashmap_clear_free_free(Hashmap *h); |
279 | static 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 | |
294 | void *internal_hashmap_steal_first(HashmapBase *h); |
295 | static 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 | } |
298 | static 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 | |
302 | void *internal_hashmap_steal_first_key(HashmapBase *h); |
303 | static 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 | } |
306 | static 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 | |
310 | void *internal_hashmap_first_key(HashmapBase *h) _pure___attribute__ ((pure)); |
311 | static 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 | } |
314 | static 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 | |
318 | void *internal_hashmap_first(HashmapBase *h) _pure___attribute__ ((pure)); |
319 | static 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 | } |
322 | static 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 */ |
350 | void *ordered_hashmap_next(OrderedHashmap *h, const void *key); |
351 | |
352 | char **internal_hashmap_get_strv(HashmapBase *h); |
353 | static 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 | } |
356 | static 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 | |
378 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free)static inline void hashmap_freep(Hashmap* *p) { if (*p) hashmap_free (*p); }; |
379 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free)static inline void hashmap_free_freep(Hashmap* *p) { if (*p) hashmap_free_free (*p); }; |
380 | DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free)static inline void hashmap_free_free_freep(Hashmap* *p) { if ( *p) hashmap_free_free_free(*p); }; |
381 | DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free)static inline void ordered_hashmap_freep(OrderedHashmap* *p) { if (*p) ordered_hashmap_free(*p); }; |
382 | DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free)static inline void ordered_hashmap_free_freep(OrderedHashmap* *p) { if (*p) ordered_hashmap_free_free(*p); }; |
383 | DEFINE_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 | |
392 | DEFINE_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))) |
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 | |||||||
31 | size_t page_size(void) _pure___attribute__ ((pure)); | ||||||
32 | #define PAGE_ALIGN(l)ALIGN_TO((l), page_size()) ALIGN_TO((l), page_size()) | ||||||
33 | |||||||
34 | static inline const char* yes_no(bool_Bool b) { | ||||||
35 | return b ? "yes" : "no"; | ||||||
36 | } | ||||||
37 | |||||||
38 | static inline const char* true_false(bool_Bool b) { | ||||||
39 | return b ? "true" : "false"; | ||||||
40 | } | ||||||
41 | |||||||
42 | static inline const char* one_zero(bool_Bool b) { | ||||||
43 | return b ? "1" : "0"; | ||||||
44 | } | ||||||
45 | |||||||
46 | static inline const char* enable_disable(bool_Bool b) { | ||||||
47 | return b ? "enable" : "disable"; | ||||||
48 | } | ||||||
49 | |||||||
50 | bool_Bool plymouth_running(void); | ||||||
51 | |||||||
52 | bool_Bool display_is_local(const char *display) _pure___attribute__ ((pure)); | ||||||
53 | int 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 | |||||||
61 | extern int saved_argc; | ||||||
62 | extern char **saved_argv; | ||||||
63 | |||||||
64 | bool_Bool kexec_loaded(void); | ||||||
65 | |||||||
66 | int prot_from_flags(int flags) _const___attribute__ ((const)); | ||||||
67 | |||||||
68 | bool_Bool in_initrd(void); | ||||||
69 | void in_initrd_force(bool_Bool value); | ||||||
70 | |||||||
71 | void *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 | */ | ||||||
79 | static 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 | */ | ||||||
92 | static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) { | ||||||
93 | if (nmemb
| ||||||
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 | |||||||
108 | static 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. */ | ||||||
117 | static 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. */ | ||||||
125 | static 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 | |||||||
133 | int 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 | |||||||
144 | static inline void *mempset(void *s, int c, size_t n) { | ||||||
145 | memset(s, c, n); | ||||||
146 | return (uint8_t*)s + n; | ||||||
147 | } | ||||||
148 | |||||||
149 | static 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 | |||||||
164 | static 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 | |||||||
173 | static 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 | |||||||
181 | static 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 | |||||||
189 | static 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 | |||||||
195 | static 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 | |||||||
201 | static 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 | |||||||
210 | int container_get_leader(const char *machine, pid_t *pid); | ||||||
211 | |||||||
212 | int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd); | ||||||
213 | int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd); | ||||||
214 | |||||||
215 | uint64_t physical_memory(void); | ||||||
216 | uint64_t physical_memory_scale(uint64_t v, uint64_t max); | ||||||
217 | |||||||
218 | uint64_t system_tasks_max(void); | ||||||
219 | uint64_t system_tasks_max_scale(uint64_t v, uint64_t max); | ||||||
220 | |||||||
221 | int version(void); | ||||||
222 | |||||||
223 | int str_verscmp(const char *s1, const char *s2); | ||||||
224 | |||||||
225 | void disable_coredumps(void); |