1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "time-util.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
36 #include "bus-signature.h"
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45 if (old_base == new_base)
48 if ((uint8_t*) p < (uint8_t*) old_base)
51 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
54 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
61 if (part->memfd >= 0) {
62 /* If we can reuse the memfd, try that. For that it
63 * can't be sealed yet. */
66 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
69 assert_se(munmap(part->data, part->mapped) == 0);
71 close_nointr_nofail(part->memfd);
74 } else if (part->munmap_this)
75 munmap(part->data, part->mapped);
76 else if (part->free_this)
83 static void message_reset_parts(sd_bus_message *m) {
84 struct bus_body_part *part;
89 while (m->n_body_parts > 0) {
90 struct bus_body_part *next = part->next;
91 message_free_part(m, part);
98 m->cached_rindex_part = NULL;
99 m->cached_rindex_part_begin = 0;
102 static void message_reset_containers(sd_bus_message *m) {
107 for (i = 0; i < m->n_containers; i++)
108 free(m->containers[i].signature);
111 m->containers = NULL;
114 m->root_container.index = 0;
117 static void message_free(sd_bus_message *m) {
123 message_reset_parts(m);
128 if (m->release_kdbus) {
131 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
136 sd_bus_unref(m->bus);
139 close_many(m->fds, m->n_fds);
143 if (m->iovec != m->iovec_fixed)
146 free(m->cmdline_array);
148 message_reset_containers(m);
149 free(m->root_container.signature);
151 free(m->peeked_signature);
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
161 size_t old_size, new_size, start;
168 old_size = sizeof(struct bus_header) + m->header->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
172 if (old_size == new_size)
173 return (uint8_t*) m->header + old_size;
175 if (new_size > (size_t) ((uint32_t) -1))
178 if (m->free_header) {
179 np = realloc(m->header, ALIGN8(new_size));
183 /* Initially, the header is allocated as part of of
184 * the sd_bus_message itself, let's replace it by
187 np = malloc(ALIGN8(new_size));
191 memcpy(np, m->header, sizeof(struct bus_header));
194 /* Zero out padding */
195 if (start > old_size)
196 memset((uint8_t*) np + old_size, 0, start - old_size);
200 m->header->fields_size = new_size - sizeof(struct bus_header);
202 /* Adjust quick access pointers */
203 m->path = adjust_pointer(m->path, op, old_size, m->header);
204 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205 m->member = adjust_pointer(m->member, op, old_size, m->header);
206 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210 m->free_header = true;
212 return (uint8_t*) np + start;
219 static int message_append_field_string(
232 if (l > (size_t) (uint32_t) -1)
235 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
245 ((uint32_t*) p)[1] = l;
246 memcpy(p + 8, s, l + 1);
249 *ret = (char*) p + 8;
254 static int message_append_field_signature(
269 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
276 p[2] = SD_BUS_TYPE_SIGNATURE;
279 memcpy(p + 5, s, l + 1);
282 *ret = (const char*) p + 5;
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
292 /* field id byte + signature length + signature 'u' + NUL + value */
293 p = message_extend_fields(m, 8, 4 + 4);
299 p[2] = SD_BUS_TYPE_UINT32;
302 ((uint32_t*) p)[1] = x;
307 int bus_message_from_header(
312 const struct ucred *ucred,
315 sd_bus_message **ret) {
318 struct bus_header *h;
321 assert(buffer || length <= 0);
322 assert(fds || n_fds <= 0);
325 if (length < sizeof(struct bus_header))
335 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
338 if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339 h->endian != SD_BUS_BIG_ENDIAN)
342 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
345 label_sz = strlen(label);
363 m->uid_valid = m->gid_valid = true;
367 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368 memcpy(m->label, label, label_sz + 1);
375 int bus_message_from_malloc(
380 const struct ucred *ucred,
382 sd_bus_message **ret) {
387 r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
391 if (length != BUS_MESSAGE_SIZE(m)) {
397 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398 m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399 m->body.sealed = true;
403 m->iovec = m->iovec_fixed;
404 m->iovec[0].iov_base = buffer;
405 m->iovec[0].iov_len = length;
407 r = bus_message_parse_fields(m);
411 /* We take possession of the memory and fds now */
412 m->free_header = true;
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
426 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
431 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432 m->header->endian = SD_BUS_NATIVE_ENDIAN;
433 m->header->type = type;
434 m->header->version = bus ? bus->message_version : 1;
435 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
438 m->bus = sd_bus_ref(bus);
443 int sd_bus_message_new_signal(
446 const char *interface,
448 sd_bus_message **m) {
461 if (bus && bus->state == BUS_UNSET)
464 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
468 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
470 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
473 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
476 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
484 sd_bus_message_unref(t);
488 int sd_bus_message_new_method_call(
490 const char *destination,
492 const char *interface,
494 sd_bus_message **m) {
499 if (destination && !service_name_is_valid(destination))
501 if (!object_path_is_valid(path))
503 if (interface && !interface_name_is_valid(interface))
505 if (!member_name_is_valid(member))
509 if (bus && bus->state == BUS_UNSET)
512 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
516 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
519 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
524 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
530 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
543 static int message_new_reply(
545 sd_bus_message *call,
547 sd_bus_message **m) {
556 if (call->header->type != SD_BUS_MESSAGE_METHOD_CALL)
560 if (bus && bus->state == BUS_UNSET)
563 t = message_new(bus, type);
567 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
568 t->reply_serial = BUS_MESSAGE_SERIAL(call);
570 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
575 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
580 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
590 int sd_bus_message_new_method_return(
592 sd_bus_message *call,
593 sd_bus_message **m) {
595 return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
598 int sd_bus_message_new_method_error(
600 sd_bus_message *call,
601 const sd_bus_error *e,
602 sd_bus_message **m) {
607 if (!sd_bus_error_is_set(e))
612 r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
616 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
621 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
634 int sd_bus_message_new_method_errorf(
636 sd_bus_message *call,
642 _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
646 assert_return(name, -EINVAL);
647 assert_return(m, -EINVAL);
649 va_start(ap, format);
650 r = bus_error_setfv(&error, name, format, ap);
656 return sd_bus_message_new_method_error(bus, call, &error, m);
659 int sd_bus_message_new_method_errno(
661 sd_bus_message *call,
663 const sd_bus_error *p,
664 sd_bus_message **m) {
666 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
668 if (sd_bus_error_is_set(p))
669 return sd_bus_message_new_method_error(bus, call, p, m);
671 sd_bus_error_set_errno(&berror, error);
673 return sd_bus_message_new_method_error(bus, call, &berror, m);
676 int sd_bus_message_new_method_errnof(
678 sd_bus_message *call,
684 _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
688 va_start(ap, format);
689 r = bus_error_set_errnofv(&berror, error, format, ap);
695 return sd_bus_message_new_method_error(bus, call, &berror, m);
698 int bus_message_new_synthetic_error(
701 const sd_bus_error *e,
702 sd_bus_message **m) {
707 assert(sd_bus_error_is_set(e));
710 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
714 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
715 t->reply_serial = serial;
717 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
721 if (bus && bus->unique_name) {
722 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
727 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
732 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
745 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
749 assert(m->n_ref > 0);
755 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
759 assert(m->n_ref > 0);
768 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
774 *type = m->header->type;
778 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
783 if (m->header->serial == 0)
786 *serial = BUS_MESSAGE_SERIAL(m);
790 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
795 if (m->reply_serial == 0)
798 *serial = m->reply_serial;
802 int sd_bus_message_get_no_reply(sd_bus_message *m) {
806 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
809 const char *sd_bus_message_get_path(sd_bus_message *m) {
816 const char *sd_bus_message_get_interface(sd_bus_message *m) {
823 const char *sd_bus_message_get_member(sd_bus_message *m) {
829 const char *sd_bus_message_get_destination(sd_bus_message *m) {
833 return m->destination;
836 const char *sd_bus_message_get_sender(sd_bus_message *m) {
843 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
847 if (!sd_bus_error_is_set(&m->error))
853 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
865 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
877 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
889 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
901 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
906 if (m->pid_starttime <= 0)
909 *usec = m->pid_starttime;
913 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
923 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
928 if (m->monotonic <= 0)
931 *usec = m->monotonic;
935 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
940 if (m->realtime <= 0)
947 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
959 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
971 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
983 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
995 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
1006 r = cg_path_get_unit(m->cgroup, &m->unit);
1015 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
1025 if (!m->user_unit) {
1026 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
1031 *ret = m->user_unit;
1035 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
1046 r = cg_path_get_session(m->cgroup, &m->session);
1055 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
1063 return cg_path_get_owner_uid(m->cgroup, uid);
1066 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
1077 for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
1081 m->cmdline_array = new(char*, n + 1);
1082 if (!m->cmdline_array)
1085 for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
1087 m->cmdline_array[i++] = (char*) p;
1092 m->cmdline_array[i] = NULL;
1093 *cmdline = m->cmdline_array;
1098 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1106 *sessionid = m->audit->sessionid;
1110 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1118 *uid = m->audit->loginuid;
1122 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1132 sz = m->capability_size / 4;
1133 if ((unsigned) capability >= sz*8)
1136 return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1139 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1143 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1146 if (interface && (!m->interface || !streq(m->interface, interface)))
1149 if (member && (!m->member || !streq(m->member, member)))
1155 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1159 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1162 if (interface && (!m->interface || !streq(m->interface, interface)))
1165 if (member && (!m->member || !streq(m->member, member)))
1171 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1175 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1178 if (name && (!m->error.name || !streq(m->error.name, name)))
1184 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1189 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1193 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1195 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1200 static struct bus_container *message_get_container(sd_bus_message *m) {
1203 if (m->n_containers == 0)
1204 return &m->root_container;
1206 assert(m->containers);
1207 return m->containers + m->n_containers - 1;
1210 struct bus_body_part *message_append_part(sd_bus_message *m) {
1211 struct bus_body_part *part;
1218 if (m->n_body_parts <= 0) {
1222 assert(m->body_end);
1224 part = new0(struct bus_body_part, 1);
1230 m->body_end->next = part;
1240 static void part_zero(struct bus_body_part *part, size_t sz) {
1245 /* All other fields can be left in their defaults */
1246 assert(!part->data);
1247 assert(part->memfd < 0);
1250 part->is_zero = true;
1251 part->sealed = true;
1254 static int part_make_space(
1255 struct sd_bus_message *m,
1256 struct bus_body_part *part,
1265 assert(!part->sealed);
1270 if (!part->data && part->memfd < 0)
1271 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1273 if (part->memfd >= 0) {
1276 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1282 if (!part->data || sz > part->mapped) {
1283 size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1285 if (part->mapped <= 0)
1286 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1288 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1290 if (n == MAP_FAILED) {
1299 part->munmap_this = true;
1301 n = realloc(part->data, MAX(sz, 1u));
1308 part->free_this = true;
1312 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1318 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1319 struct bus_container *c;
1326 /* Update counters */
1327 for (c = m->containers; c < m->containers + m->n_containers; c++)
1329 *c->array_size += expand;
1332 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1333 struct bus_body_part *part = NULL;
1334 size_t start_body, end_body, padding, start_part, end_part, added;
1346 start_body = ALIGN_TO((size_t) m->header->body_size, align);
1347 end_body = start_body + sz;
1349 padding = start_body - m->header->body_size;
1350 added = padding + sz;
1352 /* Check for 32bit overflows */
1353 if (end_body > (size_t) ((uint32_t) -1)) {
1359 m->n_body_parts <= 0 ||
1360 m->body_end->sealed ||
1361 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1365 part = message_append_part(m);
1369 part_zero(part, padding);
1372 part = message_append_part(m);
1376 r = part_make_space(m, part, sz, &p);
1380 struct bus_container *c;
1388 start_part = ALIGN_TO(part->size, align);
1389 end_part = start_part + sz;
1391 r = part_make_space(m, part, end_part, &p);
1396 memset(p, 0, padding);
1397 p = (uint8_t*) p + padding;
1400 /* Readjust pointers */
1401 for (c = m->containers; c < m->containers + m->n_containers; c++)
1402 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1404 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1407 m->header->body_size = end_body;
1408 message_extend_containers(m, added);
1413 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1414 struct bus_container *c;
1428 if (!bus_type_is_basic(type))
1433 c = message_get_container(m);
1435 if (c->signature && c->signature[c->index]) {
1436 /* Container signature is already set */
1438 if (c->signature[c->index] != type)
1443 /* Maybe we can append to the signature? But only if this is the top-level container*/
1444 if (c->enclosing != 0)
1447 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1456 case SD_BUS_TYPE_STRING:
1457 case SD_BUS_TYPE_OBJECT_PATH:
1460 sz = 4 + strlen(p) + 1;
1463 case SD_BUS_TYPE_SIGNATURE:
1466 sz = 1 + strlen(p) + 1;
1469 case SD_BUS_TYPE_BOOLEAN:
1472 assert_cc(sizeof(int) == sizeof(uint32_t));
1478 case SD_BUS_TYPE_UNIX_FD: {
1481 if (!m->allow_fds) {
1494 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1500 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1515 align = bus_type_get_alignment(type);
1516 sz = bus_type_get_size(type);
1523 a = message_extend_body(m, align, sz);
1529 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1530 *(uint32_t*) a = sz - 5;
1531 memcpy((uint8_t*) a + 4, p, sz - 4);
1534 *stored = (const uint8_t*) a + 4;
1536 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1537 *(uint8_t*) a = sz - 1;
1538 memcpy((uint8_t*) a + 1, p, sz - 1);
1541 *stored = (const uint8_t*) a + 1;
1542 } else if (type == SD_BUS_TYPE_UNIX_FD) {
1543 *(uint32_t*) a = fdi;
1557 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1564 close_nointr_nofail(fd);
1569 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1570 return message_append_basic(m, type, p, NULL);
1573 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1574 struct bus_container *c;
1586 c = message_get_container(m);
1588 if (c->signature && c->signature[c->index]) {
1589 /* Container signature is already set */
1591 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1596 /* Maybe we can append to the signature? But only if this is the top-level container*/
1597 if (c->enclosing != 0)
1600 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1607 a = message_extend_body(m, 4, 4 + size + 1);
1611 *(uint32_t*) a = size;
1616 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1622 static int bus_message_open_array(
1624 struct bus_container *c,
1625 const char *contents,
1626 uint32_t **array_size) {
1632 struct bus_body_part *o;
1639 if (!signature_is_single(contents, true))
1642 alignment = bus_type_get_alignment(contents[0]);
1646 if (c->signature && c->signature[c->index]) {
1648 /* Verify the existing signature */
1650 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1653 if (!startswith(c->signature + c->index + 1, contents))
1656 nindex = c->index + 1 + strlen(contents);
1660 if (c->enclosing != 0)
1663 /* Extend the existing signature */
1665 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1671 nindex = e - c->signature;
1674 a = message_extend_body(m, 4, 4);
1679 op = m->body_end->data;
1680 os = m->body_end->size;
1682 /* Add alignment between size and first element */
1683 if (!message_extend_body(m, alignment, 0))
1686 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1689 /* location of array size might have changed so let's readjust a */
1690 if (o == m->body_end)
1691 a = adjust_pointer(a, op, os, m->body_end->data);
1698 static int bus_message_open_variant(
1700 struct bus_container *c,
1701 const char *contents) {
1710 if (!signature_is_single(contents, false))
1713 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1716 if (c->signature && c->signature[c->index]) {
1718 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1724 if (c->enclosing != 0)
1727 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1734 l = strlen(contents);
1735 a = message_extend_body(m, 1, 1 + l + 1);
1740 memcpy((uint8_t*) a + 1, contents, l + 1);
1742 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1748 static int bus_message_open_struct(
1750 struct bus_container *c,
1751 const char *contents) {
1759 if (!signature_is_valid(contents, false))
1762 if (c->signature && c->signature[c->index]) {
1765 l = strlen(contents);
1767 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1768 !startswith(c->signature + c->index + 1, contents) ||
1769 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1772 nindex = c->index + 1 + l + 1;
1776 if (c->enclosing != 0)
1779 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1785 nindex = e - c->signature;
1788 /* Align contents to 8 byte boundary */
1789 if (!message_extend_body(m, 8, 0))
1792 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798 static int bus_message_open_dict_entry(
1800 struct bus_container *c,
1801 const char *contents) {
1809 if (!signature_is_pair(contents))
1812 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1815 if (c->signature && c->signature[c->index]) {
1818 l = strlen(contents);
1820 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1821 !startswith(c->signature + c->index + 1, contents) ||
1822 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1825 nindex = c->index + 1 + l + 1;
1829 /* Align contents to 8 byte boundary */
1830 if (!message_extend_body(m, 8, 0))
1833 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1839 int sd_bus_message_open_container(
1842 const char *contents) {
1844 struct bus_container *c, *w;
1845 uint32_t *array_size = NULL;
1859 /* Make sure we have space for one more container */
1860 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1868 c = message_get_container(m);
1870 signature = strdup(contents);
1876 /* Save old index in the parent container, in case we have to
1877 * abort this container */
1878 c->saved_index = c->index;
1879 before = m->header->body_size;
1881 if (type == SD_BUS_TYPE_ARRAY)
1882 r = bus_message_open_array(m, c, contents, &array_size);
1883 else if (type == SD_BUS_TYPE_VARIANT)
1884 r = bus_message_open_variant(m, c, contents);
1885 else if (type == SD_BUS_TYPE_STRUCT)
1886 r = bus_message_open_struct(m, c, contents);
1887 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1888 r = bus_message_open_dict_entry(m, c, contents);
1897 /* OK, let's fill it in */
1898 w += m->n_containers++;
1899 w->enclosing = type;
1900 w->signature = signature;
1902 w->array_size = array_size;
1904 w->begin = m->rindex;
1909 int sd_bus_message_close_container(sd_bus_message *m) {
1910 struct bus_container *c;
1916 if (m->n_containers <= 0)
1921 c = message_get_container(m);
1922 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1923 if (c->signature && c->signature[c->index] != 0)
1938 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1945 stack[*i].types = types;
1946 stack[*i].n_struct = n_struct;
1947 stack[*i].n_array = n_array;
1953 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1964 *types = stack[*i].types;
1965 *n_struct = stack[*i].n_struct;
1966 *n_array = stack[*i].n_array;
1971 int bus_message_append_ap(
1976 unsigned n_array, n_struct;
1977 TypeStack stack[BUS_CONTAINER_DEPTH];
1978 unsigned stack_ptr = 0;
1986 n_array = (unsigned) -1;
1987 n_struct = strlen(types);
1992 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1993 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1999 r = sd_bus_message_close_container(m);
2007 if (n_array != (unsigned) -1)
2016 case SD_BUS_TYPE_BYTE: {
2019 x = (uint8_t) va_arg(ap, int);
2020 r = sd_bus_message_append_basic(m, *t, &x);
2024 case SD_BUS_TYPE_BOOLEAN:
2025 case SD_BUS_TYPE_INT32:
2026 case SD_BUS_TYPE_UINT32:
2027 case SD_BUS_TYPE_UNIX_FD: {
2030 /* We assume a boolean is the same as int32_t */
2031 assert_cc(sizeof(int32_t) == sizeof(int));
2033 x = va_arg(ap, uint32_t);
2034 r = sd_bus_message_append_basic(m, *t, &x);
2038 case SD_BUS_TYPE_INT16:
2039 case SD_BUS_TYPE_UINT16: {
2042 x = (uint16_t) va_arg(ap, int);
2043 r = sd_bus_message_append_basic(m, *t, &x);
2047 case SD_BUS_TYPE_INT64:
2048 case SD_BUS_TYPE_UINT64:
2049 case SD_BUS_TYPE_DOUBLE: {
2052 x = va_arg(ap, uint64_t);
2053 r = sd_bus_message_append_basic(m, *t, &x);
2057 case SD_BUS_TYPE_STRING:
2058 case SD_BUS_TYPE_OBJECT_PATH:
2059 case SD_BUS_TYPE_SIGNATURE: {
2062 x = va_arg(ap, const char*);
2063 r = sd_bus_message_append_basic(m, *t, x);
2067 case SD_BUS_TYPE_ARRAY: {
2070 r = signature_element_length(t + 1, &k);
2076 memcpy(s, t + 1, k);
2079 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2084 if (n_array == (unsigned) -1) {
2089 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2095 n_array = va_arg(ap, unsigned);
2100 case SD_BUS_TYPE_VARIANT: {
2103 s = va_arg(ap, const char*);
2107 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2111 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2116 n_struct = strlen(s);
2117 n_array = (unsigned) -1;
2122 case SD_BUS_TYPE_STRUCT_BEGIN:
2123 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2126 r = signature_element_length(t, &k);
2133 memcpy(s, t + 1, k - 2);
2136 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2141 if (n_array == (unsigned) -1) {
2146 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2152 n_array = (unsigned) -1;
2168 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2181 va_start(ap, types);
2182 r = bus_message_append_ap(m, types, ap);
2188 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2197 if (!bus_type_is_trivial(type))
2199 if (!ptr && size > 0)
2204 align = bus_type_get_alignment(type);
2205 sz = bus_type_get_size(type);
2207 assert_se(align > 0);
2213 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2217 a = message_extend_body(m, align, size);
2221 r = sd_bus_message_close_container(m);
2229 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2233 if (!ptr && size > 0)
2236 r = sd_bus_message_append_array_space(m, type, size, &p);
2241 memcpy(p, ptr, size);
2246 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2247 _cleanup_close_ int copy_fd = -1;
2248 struct bus_body_part *part;
2260 if (!bus_type_is_trivial(type))
2265 r = sd_memfd_set_sealed(memfd, true);
2269 copy_fd = sd_memfd_dup_fd(memfd);
2273 r = sd_memfd_get_size(memfd, &size);
2277 align = bus_type_get_alignment(type);
2278 sz = bus_type_get_size(type);
2280 assert_se(align > 0);
2286 if (size > (uint64_t) (uint32_t) -1)
2289 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2293 a = message_extend_body(m, align, 0);
2297 part = message_append_part(m);
2301 part->memfd = copy_fd;
2302 part->sealed = true;
2306 message_extend_containers(m, size);
2307 m->header->body_size += size;
2309 return sd_bus_message_close_container(m);
2312 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2313 _cleanup_close_ int copy_fd = -1;
2314 struct bus_body_part *part;
2315 struct bus_container *c;
2320 assert_return(m, -EINVAL);
2321 assert_return(memfd, -EINVAL);
2322 assert_return(!m->sealed, -EPERM);
2323 assert_return(!m->poisoned, -ESTALE);
2325 r = sd_memfd_set_sealed(memfd, true);
2329 copy_fd = sd_memfd_dup_fd(memfd);
2333 r = sd_memfd_get_size(memfd, &size);
2337 /* We require this to be NUL terminated */
2341 if (size > (uint64_t) (uint32_t) -1)
2344 c = message_get_container(m);
2345 if (c->signature && c->signature[c->index]) {
2346 /* Container signature is already set */
2348 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2353 /* Maybe we can append to the signature? But only if this is the top-level container*/
2354 if (c->enclosing != 0)
2357 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2364 a = message_extend_body(m, 4, 4);
2368 *(uint32_t*) a = size - 1;
2370 part = message_append_part(m);
2374 part->memfd = copy_fd;
2375 part->sealed = true;
2379 message_extend_containers(m, size);
2380 m->header->body_size += size;
2382 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2388 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2392 assert_return(m, -EINVAL);
2393 assert_return(!m->sealed, -EPERM);
2394 assert_return(!m->poisoned, -ESTALE);
2396 r = sd_bus_message_open_container(m, 'a', "s");
2400 STRV_FOREACH(i, l) {
2401 r = sd_bus_message_append_basic(m, 's', *i);
2406 return sd_bus_message_close_container(m);
2409 int bus_body_part_map(struct bus_body_part *part) {
2418 if (part->size <= 0)
2421 /* For smaller zero parts (as used for padding) we don't need to map anything... */
2422 if (part->memfd < 0 && part->is_zero && part->size < 8) {
2423 static const uint8_t zeroes[7] = { };
2424 part->data = (void*) zeroes;
2428 psz = PAGE_ALIGN(part->size);
2430 if (part->memfd >= 0)
2431 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2432 else if (part->is_zero)
2433 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2437 if (p == MAP_FAILED)
2442 part->munmap_this = true;
2447 void bus_body_part_unmap(struct bus_body_part *part) {
2451 if (part->memfd < 0)
2457 if (!part->munmap_this)
2460 assert_se(munmap(part->data, part->mapped) == 0);
2464 part->munmap_this = false;
2469 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2470 size_t k, start, end;
2475 start = ALIGN_TO((size_t) *rindex, align);
2476 end = start + nbytes;
2481 /* Verify that padding is 0 */
2482 for (k = *rindex; k < start; k++)
2483 if (((const uint8_t*) p)[k] != 0)
2487 *r = (uint8_t*) p + start;
2494 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2495 struct bus_container *c;
2499 c = message_get_container(m);
2503 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2506 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2507 struct bus_body_part *part;
2513 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2514 part = m->cached_rindex_part;
2515 begin = m->cached_rindex_part_begin;
2525 if (index + sz <= begin + part->size) {
2527 r = bus_body_part_map(part);
2532 *p = (uint8_t*) part->data + index - begin;
2534 m->cached_rindex_part = part;
2535 m->cached_rindex_part_begin = begin;
2540 begin += part->size;
2547 static int message_peek_body(
2554 size_t k, start, end, padding;
2555 struct bus_body_part *part;
2562 if (message_end_of_array(m, *rindex))
2565 start = ALIGN_TO((size_t) *rindex, align);
2566 padding = start - *rindex;
2567 end = start + nbytes;
2569 if (end > BUS_MESSAGE_BODY_SIZE(m))
2572 part = find_part(m, *rindex, padding, (void**) &q);
2577 /* Verify padding */
2578 for (k = 0; k < padding; k++)
2583 part = find_part(m, start, nbytes, (void**) &q);
2595 static bool validate_nul(const char *s, size_t l) {
2597 /* Check for NUL chars in the string */
2598 if (memchr(s, 0, l))
2601 /* Check for NUL termination */
2608 static bool validate_string(const char *s, size_t l) {
2610 if (!validate_nul(s, l))
2613 /* Check if valid UTF8 */
2614 if (!utf8_is_valid(s))
2620 static bool validate_signature(const char *s, size_t l) {
2622 if (!validate_nul(s, l))
2625 /* Check if valid signature */
2626 if (!signature_is_valid(s, true))
2632 static bool validate_object_path(const char *s, size_t l) {
2634 if (!validate_nul(s, l))
2637 if (!object_path_is_valid(s))
2643 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2644 struct bus_container *c;
2652 if (!bus_type_is_basic(type))
2657 c = message_get_container(m);
2659 if (!c->signature || c->signature[c->index] == 0)
2662 if (message_end_of_array(m, m->rindex))
2665 if (c->signature[c->index] != type)
2670 case SD_BUS_TYPE_STRING:
2671 case SD_BUS_TYPE_OBJECT_PATH: {
2676 r = message_peek_body(m, &rindex, 4, 4, &q);
2680 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2681 r = message_peek_body(m, &rindex, 1, l+1, &q);
2687 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2688 if (!validate_object_path(q, l))
2691 if (!validate_string(q, l))
2696 *(const char**) p = q;
2700 case SD_BUS_TYPE_SIGNATURE: {
2705 r = message_peek_body(m, &rindex, 1, 1, &q);
2710 r = message_peek_body(m, &rindex, 1, l+1, &q);
2716 if (!validate_signature(q, l))
2720 *(const char**) p = q;
2728 align = bus_type_get_alignment(type);
2729 sz = bus_type_get_size(type);
2730 assert(align > 0 && sz > 0);
2733 r = message_peek_body(m, &rindex, align, sz, &q);
2739 case SD_BUS_TYPE_BYTE:
2740 *(uint8_t*) p = *(uint8_t*) q;
2743 case SD_BUS_TYPE_BOOLEAN:
2744 *(int*) p = !!*(uint32_t*) q;
2747 case SD_BUS_TYPE_INT16:
2748 case SD_BUS_TYPE_UINT16:
2749 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2752 case SD_BUS_TYPE_INT32:
2753 case SD_BUS_TYPE_UINT32:
2754 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2757 case SD_BUS_TYPE_INT64:
2758 case SD_BUS_TYPE_UINT64:
2759 case SD_BUS_TYPE_DOUBLE:
2760 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2763 case SD_BUS_TYPE_UNIX_FD: {
2766 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2770 *(int*) p = m->fds[j];
2775 assert_not_reached("Unknown basic type...");
2784 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2790 static int bus_message_enter_array(
2792 struct bus_container *c,
2793 const char *contents,
2794 uint32_t **array_size) {
2805 if (!signature_is_single(contents, true))
2808 alignment = bus_type_get_alignment(contents[0]);
2812 if (!c->signature || c->signature[c->index] == 0)
2815 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2818 if (!startswith(c->signature + c->index + 1, contents))
2822 r = message_peek_body(m, &rindex, 4, 4, &q);
2826 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2829 r = message_peek_body(m, &rindex, alignment, 0, NULL);
2835 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2836 c->index += 1 + strlen(contents);
2840 *array_size = (uint32_t*) q;
2845 static int bus_message_enter_variant(
2847 struct bus_container *c,
2848 const char *contents) {
2859 if (!signature_is_single(contents, false))
2862 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2865 if (!c->signature || c->signature[c->index] == 0)
2868 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2872 r = message_peek_body(m, &rindex, 1, 1, &q);
2877 r = message_peek_body(m, &rindex, 1, l+1, &q);
2883 if (!validate_signature(q, l))
2886 if (!streq(q, contents))
2889 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2897 static int bus_message_enter_struct(
2899 struct bus_container *c,
2900 const char *contents) {
2909 if (!signature_is_valid(contents, false))
2912 if (!c->signature || c->signature[c->index] == 0)
2915 l = strlen(contents);
2917 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2918 !startswith(c->signature + c->index + 1, contents) ||
2919 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2922 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2926 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2927 c->index += 1 + l + 1;
2932 static int bus_message_enter_dict_entry(
2934 struct bus_container *c,
2935 const char *contents) {
2944 if (!signature_is_pair(contents))
2947 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2950 if (!c->signature || c->signature[c->index] == 0)
2953 l = strlen(contents);
2955 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2956 !startswith(c->signature + c->index + 1, contents) ||
2957 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2960 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2964 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2965 c->index += 1 + l + 1;
2970 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2971 struct bus_container *c, *w;
2972 uint32_t *array_size = NULL;
2985 * We enforce a global limit on container depth, that is much
2986 * higher than the 32 structs and 32 arrays the specification
2987 * mandates. This is simpler to implement for us, and we need
2988 * this only to ensure our container array doesn't grow
2989 * without bounds. We are happy to return any data from a
2990 * message as long as the data itself is valid, even if the
2991 * overall message might be not.
2993 * Note that the message signature is validated when
2994 * parsing the headers, and that validation does check the
2997 * Note that the specification defines no limits on the depth
2998 * of stacked variants, but we do.
3000 if (m->n_containers >= BUS_CONTAINER_DEPTH)
3003 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
3008 c = message_get_container(m);
3010 if (!c->signature || c->signature[c->index] == 0)
3013 if (message_end_of_array(m, m->rindex))
3016 signature = strdup(contents);
3020 c->saved_index = c->index;
3023 if (type == SD_BUS_TYPE_ARRAY)
3024 r = bus_message_enter_array(m, c, contents, &array_size);
3025 else if (type == SD_BUS_TYPE_VARIANT)
3026 r = bus_message_enter_variant(m, c, contents);
3027 else if (type == SD_BUS_TYPE_STRUCT)
3028 r = bus_message_enter_struct(m, c, contents);
3029 else if (type == SD_BUS_TYPE_DICT_ENTRY)
3030 r = bus_message_enter_dict_entry(m, c, contents);
3039 /* OK, let's fill it in */
3040 w += m->n_containers++;
3041 w->enclosing = type;
3042 w->signature = signature;
3044 w->array_size = array_size;
3046 w->begin = m->rindex;
3051 int sd_bus_message_exit_container(sd_bus_message *m) {
3052 struct bus_container *c;
3058 if (m->n_containers <= 0)
3061 c = message_get_container(m);
3062 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3065 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3066 if (c->begin + l != m->rindex)
3070 if (c->signature && c->signature[c->index] != 0)
3080 static void message_quit_container(sd_bus_message *m) {
3081 struct bus_container *c;
3085 assert(m->n_containers > 0);
3087 c = message_get_container(m);
3090 assert(m->rindex >= c->before);
3091 m->rindex = c->before;
3093 /* Free container */
3097 /* Correct index of new top-level container */
3098 c = message_get_container(m);
3099 c->index = c->saved_index;
3102 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3103 struct bus_container *c;
3111 c = message_get_container(m);
3113 if (!c->signature || c->signature[c->index] == 0)
3116 if (message_end_of_array(m, m->rindex))
3119 if (bus_type_is_basic(c->signature[c->index])) {
3123 *type = c->signature[c->index];
3127 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3133 r = signature_element_length(c->signature+c->index+1, &l);
3139 sig = strndup(c->signature + c->index + 1, l);
3143 free(m->peeked_signature);
3144 m->peeked_signature = sig;
3150 *type = SD_BUS_TYPE_ARRAY;
3155 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3156 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3162 r = signature_element_length(c->signature+c->index, &l);
3167 sig = strndup(c->signature + c->index + 1, l - 2);
3171 free(m->peeked_signature);
3172 m->peeked_signature = sig;
3178 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3183 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3189 r = message_peek_body(m, &rindex, 1, 1, &q);
3196 r = message_peek_body(m, &rindex, 1, l+1, &q);
3202 if (!validate_signature(q, l))
3209 *type = SD_BUS_TYPE_VARIANT;
3218 *type = c->enclosing;
3224 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3225 struct bus_container *c;
3233 message_reset_containers(m);
3235 m->root_container.index = 0;
3237 c = message_get_container(m);
3239 c = message_get_container(m);
3242 m->rindex = c->begin;
3245 return !isempty(c->signature);
3247 static int message_read_ap(
3252 unsigned n_array, n_struct;
3253 TypeStack stack[BUS_CONTAINER_DEPTH];
3254 unsigned stack_ptr = 0;
3262 /* Ideally, we'd just call ourselves recursively on every
3263 * complex type. However, the state of a va_list that is
3264 * passed to a function is undefined after that function
3265 * returns. This means we need to docode the va_list linearly
3266 * in a single stackframe. We hence implement our own
3267 * home-grown stack in an array. */
3269 n_array = (unsigned) -1;
3270 n_struct = strlen(types);
3275 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3276 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3282 r = sd_bus_message_exit_container(m);
3290 if (n_array != (unsigned) -1)
3299 case SD_BUS_TYPE_BYTE:
3300 case SD_BUS_TYPE_BOOLEAN:
3301 case SD_BUS_TYPE_INT16:
3302 case SD_BUS_TYPE_UINT16:
3303 case SD_BUS_TYPE_INT32:
3304 case SD_BUS_TYPE_UINT32:
3305 case SD_BUS_TYPE_INT64:
3306 case SD_BUS_TYPE_UINT64:
3307 case SD_BUS_TYPE_DOUBLE:
3308 case SD_BUS_TYPE_STRING:
3309 case SD_BUS_TYPE_OBJECT_PATH:
3310 case SD_BUS_TYPE_SIGNATURE:
3311 case SD_BUS_TYPE_UNIX_FD: {
3314 p = va_arg(ap, void*);
3315 r = sd_bus_message_read_basic(m, *t, p);
3324 case SD_BUS_TYPE_ARRAY: {
3327 r = signature_element_length(t + 1, &k);
3333 memcpy(s, t + 1, k);
3336 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3343 if (n_array == (unsigned) -1) {
3348 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3354 n_array = va_arg(ap, unsigned);
3359 case SD_BUS_TYPE_VARIANT: {
3362 s = va_arg(ap, const char *);
3366 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3372 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3377 n_struct = strlen(s);
3378 n_array = (unsigned) -1;
3383 case SD_BUS_TYPE_STRUCT_BEGIN:
3384 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3387 r = signature_element_length(t, &k);
3393 memcpy(s, t + 1, k - 2);
3396 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3403 if (n_array == (unsigned) -1) {
3408 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3414 n_array = (unsigned) -1;
3427 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3438 va_start(ap, types);
3439 r = message_read_ap(m, types, ap);
3445 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3446 struct bus_container *c;
3456 if (!bus_type_is_trivial(type))
3462 if (BUS_MESSAGE_NEED_BSWAP(m))
3465 align = bus_type_get_alignment(type);
3469 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3473 c = message_get_container(m);
3474 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3476 r = message_peek_body(m, &m->rindex, align, sz, &p);
3484 r = sd_bus_message_exit_container(m);
3488 *ptr = (const void*) p;
3494 message_quit_container(m);
3498 static int message_peek_fields(
3509 return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3512 static int message_peek_field_uint32(
3523 r = message_peek_fields(m, ri, 4, 4, &q);
3528 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3533 static int message_peek_field_string(
3535 bool (*validate)(const char *p),
3546 r = message_peek_field_uint32(m, ri, &l);
3550 r = message_peek_fields(m, ri, 1, l+1, &q);
3555 if (!validate_nul(q, l))
3561 if (!validate_string(q, l))
3571 static int message_peek_field_signature(
3583 r = message_peek_fields(m, ri, 1, 1, &q);
3588 r = message_peek_fields(m, ri, 1, l+1, &q);
3592 if (!validate_signature(q, l))
3601 static int message_skip_fields(
3604 uint32_t array_size,
3605 const char **signature) {
3607 size_t original_index;
3614 original_index = *ri;
3620 if (array_size != (uint32_t) -1 &&
3621 array_size <= *ri - original_index)
3628 if (t == SD_BUS_TYPE_STRING) {
3630 r = message_peek_field_string(m, NULL, ri, NULL);
3636 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3638 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3644 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3646 r = message_peek_field_signature(m, ri, NULL);
3652 } else if (bus_type_is_basic(t)) {
3655 align = bus_type_get_alignment(t);
3656 k = bus_type_get_size(t);
3657 assert(align > 0 && k > 0);
3659 r = message_peek_fields(m, ri, align, k, NULL);
3665 } else if (t == SD_BUS_TYPE_ARRAY) {
3667 r = signature_element_length(*signature+1, &l);
3677 strncpy(sig, *signature + 1, l-1);
3680 alignment = bus_type_get_alignment(sig[0]);
3684 r = message_peek_field_uint32(m, ri, &nas);
3687 if (nas > BUS_ARRAY_MAX_SIZE)
3690 r = message_peek_fields(m, ri, alignment, 0, NULL);
3694 r = message_skip_fields(m, ri, nas, (const char**) &s);
3699 (*signature) += 1 + l;
3701 } else if (t == SD_BUS_TYPE_VARIANT) {
3704 r = message_peek_field_signature(m, ri, &s);
3708 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3714 } else if (t == SD_BUS_TYPE_STRUCT ||
3715 t == SD_BUS_TYPE_DICT_ENTRY) {
3717 r = signature_element_length(*signature, &l);
3724 strncpy(sig, *signature + 1, l-1);
3727 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
3738 int bus_message_parse_fields(sd_bus_message *m) {
3741 uint32_t unix_fds = 0;
3745 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
3746 const char *signature;
3749 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
3753 r = message_peek_field_signature(m, &ri, &signature);
3758 case _SD_BUS_MESSAGE_HEADER_INVALID:
3761 case SD_BUS_MESSAGE_HEADER_PATH:
3766 if (!streq(signature, "o"))
3769 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
3772 case SD_BUS_MESSAGE_HEADER_INTERFACE:
3777 if (!streq(signature, "s"))
3780 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
3783 case SD_BUS_MESSAGE_HEADER_MEMBER:
3788 if (!streq(signature, "s"))
3791 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
3794 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
3799 if (!streq(signature, "s"))
3802 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
3805 case SD_BUS_MESSAGE_HEADER_DESTINATION:
3810 if (!streq(signature, "s"))
3813 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
3816 case SD_BUS_MESSAGE_HEADER_SENDER:
3821 if (!streq(signature, "s"))
3824 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
3828 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
3832 if (m->root_container.signature)
3835 if (!streq(signature, "g"))
3838 r = message_peek_field_signature(m, &ri, &s);
3846 free(m->root_container.signature);
3847 m->root_container.signature = c;
3851 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
3852 if (m->reply_serial != 0)
3855 if (!streq(signature, "u"))
3858 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
3862 if (m->reply_serial == 0)
3867 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
3871 if (!streq(signature, "u"))
3874 r = message_peek_field_uint32(m, &ri, &unix_fds);
3884 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
3891 if (m->n_fds != unix_fds)
3894 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
3897 switch (m->header->type) {
3899 case SD_BUS_MESSAGE_SIGNAL:
3900 if (!m->path || !m->interface || !m->member)
3904 case SD_BUS_MESSAGE_METHOD_CALL:
3906 if (!m->path || !m->member)
3911 case SD_BUS_MESSAGE_METHOD_RETURN:
3913 if (m->reply_serial == 0)
3917 case SD_BUS_MESSAGE_METHOD_ERROR:
3919 if (m->reply_serial == 0 || !m->error.name)
3924 /* Try to read the error message, but if we can't it's a non-issue */
3925 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
3926 sd_bus_message_read(m, "s", &m->error.message);
3931 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
3932 struct bus_body_part *part;
3942 if (m->n_containers > 0)
3948 /* If there's a non-trivial signature set, then add it in here */
3949 if (!isempty(m->root_container.signature)) {
3950 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
3956 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
3961 /* Add padding at the end of the fields part, since we know
3962 * the body needs to start at an 8 byte alignment. We made
3963 * sure we allocated enough space for this, so all we need to
3964 * do here is to zero it out. */
3965 l = BUS_MESSAGE_FIELDS_SIZE(m);
3968 memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
3970 /* If this is something we can send as memfd, then let's seal
3971 the memfd now. Note that we can send memfds as payload only
3972 for directed messages, and not for broadcasts. */
3973 if (m->destination && m->bus && m->bus->use_memfd) {
3974 MESSAGE_FOREACH_PART(part, i, m)
3975 if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
3976 bus_body_part_unmap(part);
3978 if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
3979 part->sealed = true;
3983 m->header->serial = serial;
3989 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
3999 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
4002 int bus_message_dump(sd_bus_message *m) {
4003 const char *u = NULL, *uu = NULL, *s = NULL;
4004 char **cmdline = NULL;
4007 uid_t owner, audit_loginuid;
4008 uint32_t audit_sessionid;
4012 printf("Message %p\n"
4019 "\tfields_size=%u\n"
4024 "\tdestination=%s\n"
4027 "\treply_serial=%u\n"
4029 "\terror.message=%s\n"
4031 "\tn_body_parts=%u\n",
4038 BUS_MESSAGE_SERIAL(m),
4039 BUS_MESSAGE_FIELDS_SIZE(m),
4040 BUS_MESSAGE_BODY_SIZE(m),
4042 strna(m->interface),
4044 strna(m->destination),
4046 strna(m->root_container.signature),
4048 strna(m->error.name),
4049 strna(m->error.message),
4054 printf("\tpid=%lu\n", (unsigned long) m->pid);
4056 printf("\ttid=%lu\n", (unsigned long) m->tid);
4058 printf("\tuid=%lu\n", (unsigned long) m->uid);
4060 printf("\tgid=%lu\n", (unsigned long) m->gid);
4061 if (m->pid_starttime != 0)
4062 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
4063 if (m->monotonic != 0)
4064 printf("\tmonotonic=%llu\n", (unsigned long long) m->monotonic);
4065 if (m->realtime != 0)
4066 printf("\trealtime=%llu\n", (unsigned long long) m->realtime);
4068 printf("\texe=[%s]\n", m->exe);
4070 printf("\tcomm=[%s]\n", m->comm);
4072 printf("\ttid_comm=[%s]\n", m->tid_comm);
4074 printf("\tlabel=[%s]\n", m->label);
4076 printf("\tcgroup=[%s]\n", m->cgroup);
4078 sd_bus_message_get_unit(m, &u);
4080 printf("\tunit=[%s]\n", u);
4081 sd_bus_message_get_user_unit(m, &uu);
4083 printf("\tuser_unit=[%s]\n", uu);
4084 sd_bus_message_get_session(m, &s);
4086 printf("\tsession=[%s]\n", s);
4087 if (sd_bus_message_get_owner_uid(m, &owner) >= 0)
4088 printf("\towner_uid=%lu\n", (unsigned long) owner);
4089 if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0)
4090 printf("\taudit_loginuid=%lu\n", (unsigned long) audit_loginuid);
4091 if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0)
4092 printf("\taudit_sessionid=%lu\n", (unsigned long) audit_sessionid);
4094 printf("\tCAP_KILL=%i\n", sd_bus_message_has_effective_cap(m, 5));
4096 if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
4099 fputs("\tcmdline=[", stdout);
4100 STRV_FOREACH(c, cmdline) {
4107 fputs("]\n", stdout);
4110 r = sd_bus_message_rewind(m, true);
4112 log_error("Failed to rewind: %s", strerror(-r));
4116 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
4119 _cleanup_free_ char *prefix = NULL;
4120 const char *contents = NULL;
4135 r = sd_bus_message_peek_type(m, &type, &contents);
4137 log_error("Failed to peek type: %s", strerror(-r));
4144 r = sd_bus_message_exit_container(m);
4146 log_error("Failed to exit container: %s", strerror(-r));
4152 prefix = strrep("\t", level);
4156 if (type == SD_BUS_TYPE_ARRAY)
4157 printf("%s} END_ARRAY \n", prefix);
4158 else if (type == SD_BUS_TYPE_VARIANT)
4159 printf("%s} END_VARIANT\n", prefix);
4160 else if (type == SD_BUS_TYPE_STRUCT)
4161 printf("%s} END_STRUCT\n", prefix);
4162 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4163 printf("%s} END_DICT_ENTRY\n", prefix);
4168 prefix = strrep("\t", level);
4172 if (bus_type_is_container(type) > 0) {
4173 r = sd_bus_message_enter_container(m, type, contents);
4175 log_error("Failed to enter container: %s", strerror(-r));
4179 if (type == SD_BUS_TYPE_ARRAY)
4180 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
4181 else if (type == SD_BUS_TYPE_VARIANT)
4182 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
4183 else if (type == SD_BUS_TYPE_STRUCT)
4184 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
4185 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4186 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
4193 r = sd_bus_message_read_basic(m, type, &basic);
4195 log_error("Failed to get basic: %s", strerror(-r));
4201 case SD_BUS_TYPE_BYTE:
4202 printf("%sBYTE: %u\n", prefix, basic.u8);
4205 case SD_BUS_TYPE_BOOLEAN:
4206 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
4209 case SD_BUS_TYPE_INT16:
4210 printf("%sINT16: %i\n", prefix, basic.s16);
4213 case SD_BUS_TYPE_UINT16:
4214 printf("%sUINT16: %u\n", prefix, basic.u16);
4217 case SD_BUS_TYPE_INT32:
4218 printf("%sINT32: %i\n", prefix, basic.s32);
4221 case SD_BUS_TYPE_UINT32:
4222 printf("%sUINT32: %u\n", prefix, basic.u32);
4225 case SD_BUS_TYPE_INT64:
4226 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
4229 case SD_BUS_TYPE_UINT64:
4230 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
4233 case SD_BUS_TYPE_DOUBLE:
4234 printf("%sDOUBLE: %g\n", prefix, basic.d64);
4237 case SD_BUS_TYPE_STRING:
4238 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
4241 case SD_BUS_TYPE_OBJECT_PATH:
4242 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
4245 case SD_BUS_TYPE_SIGNATURE:
4246 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
4249 case SD_BUS_TYPE_UNIX_FD:
4250 printf("%sUNIX_FD: %i\n", prefix, basic.i);
4254 assert_not_reached("Unknown basic type.");
4258 printf("} END_MESSAGE\n");
4262 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
4266 struct bus_body_part *part;
4272 total = BUS_MESSAGE_SIZE(m);
4278 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
4279 MESSAGE_FOREACH_PART(part, i, m)
4280 e = mempcpy(e, part->data, part->size);
4282 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
4290 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
4296 r = sd_bus_message_enter_container(m, 'a', "s");
4303 r = sd_bus_message_read_basic(m, 's', &s);
4309 r = strv_extend(l, s);
4314 r = sd_bus_message_exit_container(m);
4321 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
4323 const char *t = NULL;
4328 r = sd_bus_message_rewind(m, true);
4332 for (j = 0; j <= i; j++) {
4335 r = sd_bus_message_peek_type(m, &type, NULL);
4339 if (type != SD_BUS_TYPE_STRING &&
4340 type != SD_BUS_TYPE_OBJECT_PATH &&
4341 type != SD_BUS_TYPE_SIGNATURE)
4344 r = sd_bus_message_read_basic(m, type, &t);
4352 bool bus_header_is_complete(struct bus_header *h, size_t size) {
4358 if (size < sizeof(struct bus_header))
4361 full = sizeof(struct bus_header) +
4362 (h->endian == SD_BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
4364 return size >= full;
4367 int bus_header_message_size(struct bus_header *h, size_t *sum) {
4373 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
4374 fs = h->fields_size;
4376 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
4377 fs = bswap_32(h->fields_size);
4378 bs = bswap_32(h->body_size);
4382 *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
4386 int sd_bus_message_get_errno(sd_bus_message *m) {
4387 assert_return(m, -EINVAL);
4389 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
4392 return sd_bus_error_get_errno(&m->error);
4395 const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
4396 struct bus_container *c;
4401 c = complete ? &m->root_container : message_get_container(m);
4402 return c->signature ?: "";