if (m->free_kdbus)
free(m->kdbus);
- if (m->release_kdbus)
- ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus);
+ if (m->release_kdbus) {
+ uint64_t off;
+
+ off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
+ ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
+ }
if (m->bus)
sd_bus_unref(m->bus);
if (bus && bus->state == BUS_UNSET)
return -ENOTCONN;
- t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
+ t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
if (!t)
return -ENOMEM;
sd_bus_message *t;
int r;
- if (!path)
+ if (destination && !service_name_is_valid(destination))
return -EINVAL;
- if (!member)
+ if (!object_path_is_valid(path))
+ return -EINVAL;
+ if (interface && !interface_name_is_valid(interface))
+ return -EINVAL;
+ if (!member_name_is_valid(member))
return -EINVAL;
if (!m)
return -EINVAL;
if (bus && bus->state == BUS_UNSET)
return -ENOTCONN;
- t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
+ t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
if (!t)
return -ENOMEM;
return -EINVAL;
if (!call->sealed)
return -EPERM;
- if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
+ if (call->header->type != SD_BUS_MESSAGE_METHOD_CALL)
return -EINVAL;
if (!m)
return -EINVAL;
sd_bus_message *call,
sd_bus_message **m) {
- return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
+ return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
}
int sd_bus_message_new_method_error(
if (!m)
return -EINVAL;
- r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
+ r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
if (r < 0)
return r;
return r;
}
+int sd_bus_message_new_method_errorf(
+ sd_bus *bus,
+ sd_bus_message *call,
+ sd_bus_message **m,
+ const char *name,
+ const char *format,
+ ...) {
+
+ _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ va_list ap;
+ int r;
+
+ assert_return(name, -EINVAL);
+ assert_return(m, -EINVAL);
+
+ va_start(ap, format);
+ r = bus_error_setfv(&error, name, format, ap);
+ va_end(ap);
+
+ if (r < 0)
+ return r;
+
+ return sd_bus_message_new_method_error(bus, call, &error, m);
+}
+
+int sd_bus_message_new_method_errno(
+ sd_bus *bus,
+ sd_bus_message *call,
+ int error,
+ const sd_bus_error *p,
+ sd_bus_message **m) {
+
+ _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
+
+ if (sd_bus_error_is_set(p))
+ return sd_bus_message_new_method_error(bus, call, p, m);
+
+ sd_bus_error_set_errno(&berror, error);
+
+ return sd_bus_message_new_method_error(bus, call, &berror, m);
+}
+
+int sd_bus_message_new_method_errnof(
+ sd_bus *bus,
+ sd_bus_message *call,
+ sd_bus_message **m,
+ int error,
+ const char *format,
+ ...) {
+
+ _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
+ va_list ap;
+ int r;
+
+ va_start(ap, format);
+ r = bus_error_set_errnofv(&berror, error, format, ap);
+ va_end(ap);
+
+ if (r < 0)
+ return r;
+
+ return sd_bus_message_new_method_error(bus, call, &berror, m);
+}
+
int bus_message_new_synthetic_error(
sd_bus *bus,
uint64_t serial,
assert(sd_bus_error_is_set(e));
assert(m);
- t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR);
+ t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
if (!t)
return -ENOMEM;
goto fail;
}
+ r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
+ if (r < 0)
+ goto fail;
+
+ if (e->message) {
+ r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
+ if (r < 0)
+ goto fail;
+ }
+
*m = t;
return 0;
if (!m)
return -EINVAL;
- return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
+ return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
}
const char *sd_bus_message_get_path(sd_bus_message *m) {
if (!m)
return -EINVAL;
- if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
+ if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
return 0;
if (interface && (!m->interface || !streq(m->interface, interface)))
if (!m)
return -EINVAL;
- if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
+ if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
return 0;
if (interface && (!m->interface || !streq(m->interface, interface)))
if (!m)
return -EINVAL;
- if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
+ if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
return 0;
if (name && (!m->error.name || !streq(m->error.name, name)))
return -EINVAL;
if (m->sealed)
return -EPERM;
- if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
+ if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
return -EPERM;
if (b)
part->mapped = psz;
part->data = n;
- part->munmap_this = true;
}
+
+ part->munmap_this = true;
} else {
- n = realloc(part->data, sz);
+ n = realloc(part->data, MAX(sz, 1u));
if (!n) {
m->poisoned = true;
return -ENOMEM;
assert(contents);
assert(array_size);
- if (!signature_is_single(contents))
+ if (!signature_is_single(contents, true))
return -EINVAL;
alignment = bus_type_get_alignment(contents[0]);
assert(c);
assert(contents);
- if (!signature_is_single(contents))
+ if (!signature_is_single(contents, false))
return -EINVAL;
if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
void *a;
int r;
- if (!m)
- return -EINVAL;
- if (!memfd)
- return -EINVAL;
- if (m->sealed)
- return -EPERM;
- if (m->poisoned)
- return -ESTALE;
+ assert_return(m, -EINVAL);
+ assert_return(memfd, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->poisoned, -ESTALE);
r = sd_memfd_set_sealed(memfd, true);
if (r < 0)
return 0;
}
+int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
+ char **i;
+ int r;
+
+ assert_return(m, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->poisoned, -ESTALE);
+
+ r = sd_bus_message_open_container(m, 'a', "s");
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(i, l) {
+ r = sd_bus_message_append_basic(m, 's', *i);
+ if (r < 0)
+ return r;
+ }
+
+ return sd_bus_message_close_container(m);
+}
+
int bus_body_part_map(struct bus_body_part *part) {
void *p;
size_t psz;
if (!c->signature || c->signature[c->index] == 0)
return 0;
+ if (message_end_of_array(m, m->rindex))
+ return 0;
+
if (c->signature[c->index] != type)
return -ENXIO;
assert(contents);
assert(array_size);
- if (!signature_is_single(contents))
+ if (!signature_is_single(contents, true))
return -EINVAL;
alignment = bus_type_get_alignment(contents[0]);
assert(c);
assert(contents);
- if (!signature_is_single(contents))
+ if (!signature_is_single(contents, false))
return -EINVAL;
if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
if (!c->signature || c->signature[c->index] == 0)
return 0;
+ if (message_end_of_array(m, m->rindex))
+ return 0;
+
signature = strdup(contents);
if (!signature)
return -ENOMEM;
switch (m->header->type) {
- case SD_BUS_MESSAGE_TYPE_SIGNAL:
+ case SD_BUS_MESSAGE_SIGNAL:
if (!m->path || !m->interface || !m->member)
return -EBADMSG;
break;
- case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
+ case SD_BUS_MESSAGE_METHOD_CALL:
if (!m->path || !m->member)
return -EBADMSG;
break;
- case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
+ case SD_BUS_MESSAGE_METHOD_RETURN:
if (m->reply_serial == 0)
return -EBADMSG;
break;
- case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
+ case SD_BUS_MESSAGE_METHOD_ERROR:
if (m->reply_serial == 0 || !m->error.name)
return -EBADMSG;
}
/* Try to read the error message, but if we can't it's a non-issue */
- if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
+ if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
sd_bus_message_read(m, "s", &m->error.message);
return 0;
return 0;
}
-int bus_message_to_errno(sd_bus_message *m) {
- assert(m);
+int sd_bus_message_get_errno(sd_bus_message *m) {
+ assert_return(m, -EINVAL);
- if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
+ if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
return 0;
- return bus_error_to_errno(&m->error);
+ return sd_bus_error_get_errno(&m->error);
+}
+
+const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
+ struct bus_container *c;
+
+ if (!m)
+ return NULL;
+
+ c = complete ? &m->root_container : message_get_container(m);
+ return c->signature ?: "";
}