]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-util.h
Merge pull request #7759 from yuwata/dbus-api
[thirdparty/systemd.git] / src / core / dbus-util.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 #pragma once
3
4 /***
5 This file is part of systemd.
6
7 Copyright 2010 Lennart Poettering
8
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include "sd-bus.h"
24 #include "unit.h"
25
26 #define BUS_DEFINE_SET_TRANSIENT(function, bus_type, type, cast_type, fmt) \
27 int bus_set_transient_##function( \
28 Unit *u, \
29 const char *name, \
30 cast_type *p, \
31 sd_bus_message *message, \
32 UnitWriteFlags flags, \
33 sd_bus_error *error) { \
34 \
35 type v; \
36 int r; \
37 \
38 assert(p); \
39 \
40 r = sd_bus_message_read(message, bus_type, &v); \
41 if (r < 0) \
42 return r; \
43 \
44 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
45 *p = (cast_type) v; \
46 unit_write_settingf(u, flags, name, \
47 "%s=" fmt, name, v); \
48 } \
49 \
50 return 1; \
51 } \
52 struct __useless_struct_to_allow_trailing_semicolon__
53
54 #define BUS_DEFINE_SET_TRANSIENT_IS_VALID(function, bus_type, type, cast_type, fmt, check) \
55 int bus_set_transient_##function( \
56 Unit *u, \
57 const char *name, \
58 cast_type *p, \
59 sd_bus_message *message, \
60 UnitWriteFlags flags, \
61 sd_bus_error *error) { \
62 \
63 type v; \
64 int r; \
65 \
66 assert(p); \
67 \
68 r = sd_bus_message_read(message, bus_type, &v); \
69 if (r < 0) \
70 return r; \
71 \
72 if (!check(v)) \
73 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
74 "Invalid %s setting: " fmt, name, v); \
75 \
76 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
77 *p = (cast_type) v; \
78 unit_write_settingf(u, flags, name, \
79 "%s=" fmt, name, v); \
80 } \
81 \
82 return 1; \
83 } \
84 struct __useless_struct_to_allow_trailing_semicolon__
85
86 #define BUS_DEFINE_SET_TRANSIENT_TO_STRING(function, bus_type, type, cast_type, fmt, to_string) \
87 int bus_set_transient_##function( \
88 Unit *u, \
89 const char *name, \
90 cast_type *p, \
91 sd_bus_message *message, \
92 UnitWriteFlags flags, \
93 sd_bus_error *error) { \
94 \
95 const char *s; \
96 type v; \
97 int r; \
98 \
99 assert(p); \
100 \
101 r = sd_bus_message_read(message, bus_type, &v); \
102 if (r < 0) \
103 return r; \
104 \
105 s = to_string(v); \
106 if (!s) \
107 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
108 "Invalid %s setting: " fmt, name, v); \
109 \
110 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
111 *p = (cast_type) v; \
112 unit_write_settingf(u, flags, name, \
113 "%s=%s", name, s); \
114 } \
115 \
116 return 1; \
117 } \
118 struct __useless_struct_to_allow_trailing_semicolon__
119
120 #define BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(function, bus_type, type, cast_type, fmt, to_string) \
121 int bus_set_transient_##function( \
122 Unit *u, \
123 const char *name, \
124 cast_type *p, \
125 sd_bus_message *message, \
126 UnitWriteFlags flags, \
127 sd_bus_error *error) { \
128 \
129 _cleanup_free_ char *s = NULL; \
130 type v; \
131 int r; \
132 \
133 assert(p); \
134 \
135 r = sd_bus_message_read(message, bus_type, &v); \
136 if (r < 0) \
137 return r; \
138 \
139 r = to_string(v, &s); \
140 if (r == -EINVAL) \
141 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
142 "Invalid %s setting: " fmt, name, v); \
143 if (r < 0) \
144 return r; \
145 \
146 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
147 *p = (cast_type) v; \
148 unit_write_settingf(u, flags, name, \
149 "%s=%s", name, s); \
150 } \
151 \
152 return 1; \
153 } \
154 struct __useless_struct_to_allow_trailing_semicolon__
155
156 #define BUS_DEFINE_SET_TRANSIENT_PARSE(function, type, parse) \
157 int bus_set_transient_##function( \
158 Unit *u, \
159 const char *name, \
160 type *p, \
161 sd_bus_message *message, \
162 UnitWriteFlags flags, \
163 sd_bus_error *error) { \
164 \
165 const char *s; \
166 type v; \
167 int r; \
168 \
169 assert(p); \
170 \
171 r = sd_bus_message_read(message, "s", &s); \
172 if (r < 0) \
173 return r; \
174 \
175 v = parse(s); \
176 if (v < 0) \
177 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
178 "Invalid %s setting: %s", name, s); \
179 \
180 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
181 *p = v; \
182 unit_write_settingf(u, flags, name, \
183 "%s=%s", name, s); \
184 } \
185 \
186 return 1; \
187 } \
188 struct __useless_struct_to_allow_trailing_semicolon__
189
190 #define BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(function, type, parse) \
191 int bus_set_transient_##function( \
192 Unit *u, \
193 const char *name, \
194 type *p, \
195 sd_bus_message *message, \
196 UnitWriteFlags flags, \
197 sd_bus_error *error) { \
198 \
199 const char *s; \
200 type v; \
201 int r; \
202 \
203 assert(p); \
204 \
205 r = sd_bus_message_read(message, "s", &s); \
206 if (r < 0) \
207 return r; \
208 \
209 r = parse(s, &v); \
210 if (r < 0) \
211 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
212 "Invalid %s setting: %s", name, s); \
213 \
214 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
215 *p = v; \
216 unit_write_settingf(u, flags, name, \
217 "%s=%s", name, strempty(s)); \
218 } \
219 \
220 return 1; \
221 } \
222 struct __useless_struct_to_allow_trailing_semicolon__
223
224 #define BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(function, check) \
225 int bus_set_transient_##function( \
226 Unit *u, \
227 const char *name, \
228 char **p, \
229 sd_bus_message *message, \
230 UnitWriteFlags flags, \
231 sd_bus_error *error) { \
232 \
233 const char *v; \
234 int r; \
235 \
236 assert(p); \
237 \
238 r = sd_bus_message_read(message, "s", &v); \
239 if (r < 0) \
240 return r; \
241 \
242 if (!isempty(v) && !check(v)) \
243 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
244 "Invalid %s setting: %s", name, v); \
245 \
246 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
247 r = free_and_strdup(p, empty_to_null(v)); \
248 if (r < 0) \
249 return r; \
250 \
251 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, \
252 "%s=%s", name, strempty(v)); \
253 } \
254 \
255 return 1; \
256 } \
257 struct __useless_struct_to_allow_trailing_semicolon__
258
259 #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val, str) \
260 int bus_cgroup_set_##function( \
261 Unit *u, \
262 const char *name, \
263 uint64_t *p, \
264 sd_bus_message *message, \
265 UnitWriteFlags flags, \
266 sd_bus_error *error) { \
267 \
268 uint64_t v; \
269 int r; \
270 \
271 assert(p); \
272 \
273 r = sd_bus_message_read(message, "t", &v); \
274 if (r < 0) \
275 return r; \
276 \
277 if (!check(v)) \
278 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
279 "Value specified in %s is out of range", name); \
280 \
281 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
282 *p = v; \
283 unit_invalidate_cgroup(u, (mask)); \
284 \
285 if (v == (val)) \
286 unit_write_settingf(u, flags, name, \
287 "%s=" str, name); \
288 else \
289 unit_write_settingf(u, flags, name, \
290 "%s=%" PRIu64, name, v); \
291 } \
292 \
293 return 1; \
294 } \
295 struct __useless_struct_to_allow_trailing_semicolon__
296
297 #define BUS_DEFINE_SET_CGROUP_SCALE(function, mask, scale) \
298 int bus_cgroup_set_##function##_scale( \
299 Unit *u, \
300 const char *name, \
301 uint64_t *p, \
302 sd_bus_message *message, \
303 UnitWriteFlags flags, \
304 sd_bus_error *error) { \
305 \
306 uint64_t v; \
307 uint32_t raw; \
308 int r; \
309 \
310 assert(p); \
311 \
312 r = sd_bus_message_read(message, "u", &raw); \
313 if (r < 0) \
314 return r; \
315 \
316 v = scale(raw, UINT32_MAX); \
317 if (v <= 0 || v >= UINT64_MAX) \
318 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
319 "Value specified in %s is out of range", name); \
320 \
321 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
322 const char *e; \
323 \
324 *p = v; \
325 unit_invalidate_cgroup(u, (mask)); \
326 \
327 /* Chop off suffix */ \
328 assert_se(e = endswith(name, "Scale")); \
329 name = strndupa(name, e - name); \
330 \
331 unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \
332 (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
333 } \
334 \
335 return 1; \
336 } \
337 struct __useless_struct_to_allow_trailing_semicolon__
338
339 int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
340 int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
341 int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
342 int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
343 int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
344 int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
345 int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
346 static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
347 return bus_set_transient_usec_internal(u, name, p, false, message, flags, error);
348 }
349 static inline int bus_set_transient_usec_fix_0(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
350 return bus_set_transient_usec_internal(u, name, p, true, message, flags, error);
351 }