-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
-#include "util.h"
-#include "utf8.h"
-#include "strv.h"
-#include "time-util.h"
-#include "memfd-util.h"
-
#include "sd-bus.h"
-#include "bus-message.h"
+
+#include "alloc-util.h"
+#include "bus-gvariant.h"
#include "bus-internal.h"
-#include "bus-type.h"
+#include "bus-message.h"
#include "bus-signature.h"
-#include "bus-gvariant.h"
+#include "bus-type.h"
#include "bus-util.h"
+#include "fd-util.h"
+#include "io-util.h"
+#include "memfd-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "time-util.h"
+#include "utf8.h"
+#include "util.h"
static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
assert(m);
assert(part);
- if (part->memfd >= 0) {
- /* If we can reuse the memfd, try that. For that it
- * can't be sealed yet. */
-
- if (!part->sealed) {
- assert(part->memfd_offset == 0);
- assert(part->data == part->mmap_begin);
- bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
- } else {
- if (part->mapped > 0)
- assert_se(munmap(part->mmap_begin, part->mapped) == 0);
-
- safe_close(part->memfd);
- }
-
- } else if (part->munmap_this)
+ if (part->memfd >= 0)
+ close_and_munmap(part->memfd, part->mmap_begin, part->mapped);
+ else if (part->munmap_this)
munmap(part->mmap_begin, part->mapped);
else if (part->free_this)
free(part->data);
free(m->containers[i].offsets);
}
- free(m->containers);
- m->containers = NULL;
+ m->containers = mfree(m->containers);
m->n_containers = m->containers_allocated = 0;
m->root_container.index = 0;
}
-static void message_free(sd_bus_message *m) {
+static sd_bus_message* message_free(sd_bus_message *m) {
assert(m);
if (m->free_header)
message_reset_parts(m);
- if (m->release_kdbus)
- bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
-
- if (m->free_kdbus)
- free(m->kdbus);
-
sd_bus_unref(m->bus);
if (m->free_fds) {
if (m->iovec != m->iovec_fixed)
free(m->iovec);
- m->destination_ptr = mfree(m->destination_ptr);
message_reset_containers(m);
free(m->root_container.signature);
free(m->root_container.offsets);
free(m->root_container.peeked_signature);
bus_creds_done(&m->creds);
- free(m);
+ return mfree(m);
}
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free);
+
static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
void *op, *np;
size_t old_size, new_size, start;
if (!np)
goto poison;
} else {
- /* Initially, the header is allocated as part of of
+ /* Initially, the header is allocated as part of
* the sd_bus_message itself, let's replace it by
* dynamic data */
size_t footer_accessible,
size_t message_size,
int *fds,
- unsigned n_fds,
+ size_t n_fds,
const char *label,
size_t extra,
sd_bus_message **ret) {
}
m->bus = sd_bus_ref(bus);
- *ret = m;
- m = NULL;
+ *ret = TAKE_PTR(m);
return 0;
}
void *buffer,
size_t length,
int *fds,
- unsigned n_fds,
+ size_t n_fds,
const char *label,
sd_bus_message **ret) {
- sd_bus_message *m;
+ _cleanup_(message_freep) sd_bus_message *m = NULL;
size_t sz;
int r;
r = bus_message_parse_fields(m);
if (r < 0)
- goto fail;
+ return r;
/* We take possession of the memory and fds now */
m->free_header = true;
m->free_fds = true;
- *ret = m;
+ *ret = TAKE_PTR(m);
return 0;
-
-fail:
- message_free(m);
- return r;
}
-static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
- sd_bus_message *m;
+_public_ int sd_bus_message_new(
+ sd_bus *bus,
+ sd_bus_message **m,
+ uint8_t type) {
- assert(bus);
+ sd_bus_message *t;
- m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
- if (!m)
- return NULL;
+ assert_return(bus, -ENOTCONN);
+ assert_return(bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(m, -EINVAL);
+ assert_return(type < _SD_BUS_MESSAGE_TYPE_MAX, -EINVAL);
- m->n_ref = 1;
- m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
- m->header->endian = BUS_NATIVE_ENDIAN;
- m->header->type = type;
- m->header->version = bus->message_version;
- m->allow_fds = bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
- m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
- m->bus = sd_bus_ref(bus);
+ t = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
+ if (!t)
+ return -ENOMEM;
+
+ t->n_ref = 1;
+ t->header = (struct bus_header*) ((uint8_t*) t + ALIGN(sizeof(struct sd_bus_message)));
+ t->header->endian = BUS_NATIVE_ENDIAN;
+ t->header->type = type;
+ t->header->version = bus->message_version;
+ t->allow_fds = bus->can_fds || !IN_SET(bus->state, BUS_HELLO, BUS_RUNNING);
+ t->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(t);
+ t->bus = sd_bus_ref(bus);
if (bus->allow_interactive_authorization)
- m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+ t->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
- return m;
+ *m = t;
+ return 0;
}
_public_ int sd_bus_message_new_signal(
const char *interface,
const char *member) {
- sd_bus_message *t;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
int r;
assert_return(bus, -ENOTCONN);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(m, -EINVAL);
- t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
- if (!t)
+ r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_SIGNAL);
+ if (r < 0)
return -ENOMEM;
+ assert(t);
+
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
if (r < 0)
- goto fail;
+ return r;
r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
if (r < 0)
- goto fail;
+ return r;
r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
if (r < 0)
- goto fail;
+ return r;
- *m = t;
+ *m = TAKE_PTR(t);
return 0;
-
-fail:
- sd_bus_message_unref(t);
- return r;
}
_public_ int sd_bus_message_new_method_call(
const char *interface,
const char *member) {
- sd_bus_message *t;
+ _cleanup_(message_freep) sd_bus_message *t = NULL;
int r;
assert_return(bus, -ENOTCONN);
assert_return(member_name_is_valid(member), -EINVAL);
assert_return(m, -EINVAL);
- t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
- if (!t)
+ r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_METHOD_CALL);
+ if (r < 0)
return -ENOMEM;
+ assert(t);
+
r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
if (r < 0)
- goto fail;
+ return r;
r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
if (r < 0)
- goto fail;
+ return r;
if (interface) {
r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
if (r < 0)
- goto fail;
+ return r;
}
if (destination) {
r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
if (r < 0)
- goto fail;
+ return r;
}
- *m = t;
+ *m = TAKE_PTR(t);
return 0;
-
-fail:
- message_free(t);
- return r;
}
static int message_new_reply(
uint8_t type,
sd_bus_message **m) {
- sd_bus_message *t;
+ _cleanup_(message_freep) sd_bus_message *t = NULL;
+ uint64_t cookie;
int r;
assert_return(call, -EINVAL);
assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
assert_return(m, -EINVAL);
- t = message_new(call->bus, type);
- if (!t)
+ cookie = BUS_MESSAGE_COOKIE(call);
+ if (cookie == 0)
+ return -EOPNOTSUPP;
+
+ r = sd_bus_message_new(call->bus, &t, type);
+ if (r < 0)
return -ENOMEM;
- t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
- t->reply_cookie = BUS_MESSAGE_COOKIE(call);
- if (t->reply_cookie == 0)
- return -EOPNOTSUPP;
+ assert(t);
+ t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
+ t->reply_cookie = cookie;
r = message_append_reply_cookie(t, t->reply_cookie);
if (r < 0)
- goto fail;
+ return r;
if (call->sender) {
r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
if (r < 0)
- goto fail;
+ return r;
}
t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
t->enforced_reply_signature = call->enforced_reply_signature;
- *m = t;
+ *m = TAKE_PTR(t);
return 0;
-
-fail:
- message_free(t);
- return r;
}
_public_ int sd_bus_message_new_method_return(
sd_bus_message **m,
const sd_bus_error *e) {
- sd_bus_message *t;
+ _cleanup_(message_freep) sd_bus_message *t = NULL;
int r;
assert_return(sd_bus_error_is_set(e), -EINVAL);
r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
if (r < 0)
- goto fail;
+ return r;
if (e->message) {
r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
if (r < 0)
- goto fail;
+ return r;
}
t->error._need_free = -1;
- *m = t;
+ *m = TAKE_PTR(t);
return 0;
-
-fail:
- message_free(t);
- return r;
}
_public_ int sd_bus_message_new_method_errorf(
const char *format,
...) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
va_list ap;
assert_return(name, -EINVAL);
int error,
const sd_bus_error *p) {
- _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
if (sd_bus_error_is_set(p))
return sd_bus_message_new_method_error(call, m, p);
return sd_bus_message_new_method_error(call, m, &berror);
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_new_method_errnof(
sd_bus_message *call,
sd_bus_message **m,
const char *format,
...) {
- _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
va_list ap;
va_start(ap, format);
return sd_bus_message_new_method_error(call, m, &berror);
}
-#endif // 0
void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
assert(bus);
const sd_bus_error *e,
sd_bus_message **m) {
- sd_bus_message *t;
+ _cleanup_(message_freep) sd_bus_message *t = NULL;
int r;
assert(bus);
assert(sd_bus_error_is_set(e));
assert(m);
- t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
- if (!t)
+ r = sd_bus_message_new(bus, &t, SD_BUS_MESSAGE_METHOD_ERROR);
+ if (r < 0)
return -ENOMEM;
+ assert(t);
+
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
t->reply_cookie = cookie;
r = message_append_reply_cookie(t, t->reply_cookie);
if (r < 0)
- goto fail;
+ return r;
if (bus && bus->unique_name) {
r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
if (r < 0)
- goto fail;
+ return r;
}
r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
if (r < 0)
- goto fail;
+ return r;
if (e->message) {
r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
if (r < 0)
- goto fail;
+ return r;
}
t->error._need_free = -1;
bus_message_set_sender_driver(bus, t);
- *m = t;
+ *m = TAKE_PTR(t);
return 0;
-
-fail:
- message_free(t);
- return r;
}
_public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
- assert_return(m, NULL);
+
+ if (!m)
+ return NULL;
assert(m->n_ref > 0);
m->n_ref++;
if (m->n_ref > 0)
return NULL;
- message_free(m);
- return NULL;
+ return message_free(m);
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
assert_return(m, -EINVAL);
assert_return(type, -EINVAL);
return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
}
-#endif // 0
_public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
assert_return(m, -EINVAL);
_public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
assert_return(m, NULL);
- assert_return(sd_bus_error_is_set(&m->error), NULL);
+
+ if (!sd_bus_error_is_set(&m->error))
+ return NULL;
return &m->error;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
assert_return(m, -EINVAL);
assert_return(usec, -EINVAL);
*seqnum = m->seqnum;
return 0;
}
-#endif // 0
_public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
assert_return(m, NULL);
return &m->creds;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_is_signal(
sd_bus_message *m,
const char *interface,
if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
return 0;
- if (interface && (!m->interface || !streq(m->interface, interface)))
+ if (interface && !streq_ptr(m->interface, interface))
return 0;
- if (member && (!m->member || !streq(m->member, member)))
+ if (member && !streq_ptr(m->member, member))
return 0;
return 1;
}
-#endif // 0
_public_ int sd_bus_message_is_method_call(
sd_bus_message *m,
if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
return 0;
- if (interface && (!m->interface || !streq(m->interface, interface)))
+ if (interface && !streq_ptr(m->interface, interface))
return 0;
- if (member && (!m->member || !streq(m->member, member)))
+ if (member && !streq_ptr(m->member, member))
return 0;
return 1;
if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
return 0;
- if (name && (!m->error.name || !streq(m->error.name, name)))
+ if (name && !streq_ptr(m->error.name, name))
return 0;
return 1;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
- if (b)
- m->header->flags &= ~BUS_MESSAGE_NO_REPLY_EXPECTED;
- else
- m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_NO_REPLY_EXPECTED, !b);
return 0;
}
-#endif // 0
_public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- if (b)
- m->header->flags &= ~BUS_MESSAGE_NO_AUTO_START;
- else
- m->header->flags |= BUS_MESSAGE_NO_AUTO_START;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_NO_AUTO_START, !b);
return 0;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- if (b)
- m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
- else
- m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
+ SET_FLAG(m->header->flags, BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION, b);
return 0;
}
-#endif // 0
static struct bus_container *message_get_container(sd_bus_message *m) {
assert(m);
part->memfd = -1;
m->body_end = part;
- m->n_body_parts ++;
+ m->n_body_parts++;
return part;
}
void **q) {
void *n;
- int r;
assert(m);
assert(part);
if (m->poisoned)
return -ENOMEM;
- if (!part->data && part->memfd < 0) {
- part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
- part->mmap_begin = part->data;
- }
-
- if (part->memfd >= 0) {
-
- if (part->allocated == 0 || sz > part->allocated) {
- uint64_t new_allocated;
-
- new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
- r = memfd_set_size(part->memfd, new_allocated);
- if (r < 0) {
- m->poisoned = true;
- return r;
- }
-
- part->allocated = new_allocated;
- }
+ if (part->allocated == 0 || sz > part->allocated) {
+ size_t new_allocated;
- if (!part->data || sz > part->mapped) {
- size_t psz;
-
- psz = PAGE_ALIGN(sz > 0 ? sz : 1);
- if (part->mapped <= 0)
- n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
- else
- n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
-
- if (n == MAP_FAILED) {
- m->poisoned = true;
- return -errno;
- }
-
- part->mmap_begin = part->data = n;
- part->mapped = psz;
- part->memfd_offset = 0;
+ new_allocated = sz > 0 ? 2 * sz : 64;
+ n = realloc(part->data, new_allocated);
+ if (!n) {
+ m->poisoned = true;
+ return -ENOMEM;
}
- part->munmap_this = true;
- } else {
- if (part->allocated == 0 || sz > part->allocated) {
- size_t new_allocated;
-
- new_allocated = sz > 0 ? 2 * sz : 64;
- n = realloc(part->data, new_allocated);
- if (!n) {
- m->poisoned = true;
- return -ENOMEM;
- }
-
- part->data = n;
- part->allocated = new_allocated;
- part->free_this = true;
- }
+ part->data = n;
+ part->allocated = new_allocated;
+ part->free_this = true;
}
if (q)
m->n_body_parts <= 0 ||
m->body_end->sealed ||
(padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
- (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */
+ (force_inline && m->body_end->size > MEMFD_MIN_SIZE);
+ /* If this must be an inlined extension, let's create a new part if
+ * the previous part is large enough to be inlined. */
if (add_new_part) {
if (padding > 0) {
}
} else
/* Return something that is not NULL and is aligned */
- p = (uint8_t *) NULL + align;
+ p = (uint8_t*) align;
m->body_size = end_body;
message_extend_containers(m, added);
if (copy < 0)
return -errno;
- f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
+ f = reallocarray(m->fds, sizeof(int), m->n_fds + 1);
if (!f) {
m->poisoned = true;
safe_close(copy);
case SD_BUS_TYPE_STRING:
p = strempty(p);
- /* Fall through... */
+ _fallthrough_;
case SD_BUS_TYPE_OBJECT_PATH:
if (!p)
return -EINVAL;
* into the empty string */
p = strempty(p);
- /* Fall through... */
+ _fallthrough_;
case SD_BUS_TYPE_OBJECT_PATH:
if (!p)
if (!a)
return -ENOMEM;
- if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
+ if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
*(uint32_t*) a = sz - 5;
memcpy((uint8_t*) a + 4, p, sz - 4);
}
if (type == SD_BUS_TYPE_UNIX_FD)
- m->n_fds ++;
+ m->n_fds++;
if (c->enclosing != SD_BUS_TYPE_ARRAY)
c->index++;
return 0;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_append_string_iovec(
sd_bus_message *m,
const struct iovec *iov,
- unsigned n) {
+ unsigned n /* should be size_t, but is API now… 😞 */) {
size_t size;
unsigned i;
return 0;
}
-#endif // 0
static int bus_message_open_array(
sd_bus_message *m,
struct bus_container *c, *w;
uint32_t *array_size = NULL;
- char *signature;
+ _cleanup_free_ char *signature = NULL;
size_t before, begin = 0;
bool need_offsets = false;
int r;
r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
else
r = -EINVAL;
-
- if (r < 0) {
- free(signature);
+ if (r < 0)
return r;
- }
/* OK, let's fill it in */
w = m->containers + m->n_containers++;
w->enclosing = type;
- w->signature = signature;
+ w->signature = TAKE_PTR(signature);
w->index = 0;
w->array_size = array_size;
w->before = before;
r = bus_message_close_array(m, c);
else if (c->enclosing == SD_BUS_TYPE_VARIANT)
r = bus_message_close_variant(m, c);
- else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
+ else if (IN_SET(c->enclosing, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY))
r = bus_message_close_struct(m, c, true);
else
assert_not_reached("Unknown container type");
return 1;
}
-int bus_message_append_ap(
+_public_ int sd_bus_message_appendv(
sd_bus_message *m,
const char *types,
va_list ap) {
unsigned stack_ptr = 0;
int r;
- assert(m);
-
- if (!types)
- return 0;
+ assert_return(m, -EINVAL);
+ assert_return(types, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->poisoned, -ESTALE);
n_array = (unsigned) -1;
n_struct = strlen(types);
t = types;
if (n_array != (unsigned) -1)
- n_array --;
+ n_array--;
else {
- types ++;
+ types++;
n_struct--;
}
assert_return(!m->poisoned, -ESTALE);
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
return r;
if (r < 0)
return r;
- if (size > 0)
- memcpy(p, ptr, size);
+ memcpy_safe(p, ptr, size);
return 0;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_append_array_iovec(
sd_bus_message *m,
char type,
const struct iovec *iov,
- unsigned n) {
+ unsigned n /* should be size_t, but is API now… 😞 */) {
size_t size;
unsigned i;
if (r < 0)
return r;
- copy_fd = dup(memfd);
+ copy_fd = fcntl(memfd, F_DUPFD_CLOEXEC, 3);
if (copy_fd < 0)
return copy_fd;
if (r < 0)
return r;
- copy_fd = dup(memfd);
+ copy_fd = fcntl(memfd, FD_CLOEXEC, 3);
if (copy_fd < 0)
return copy_fd;
return 0;
}
-#endif // 0
_public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
char **i;
/* The actual user data is finished now, we just complete the
variant and struct now (at least on gvariant). Remember
- this position, so that during parsing we know where to to
+ this position, so that during parsing we know where to
put the outer container end. */
m->user_body_size = m->body_size;
return 0;
}
-int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
+_public_ int sd_bus_message_seal(sd_bus_message *m, uint64_t cookie, uint64_t timeout_usec) {
struct bus_body_part *part;
size_t a;
unsigned i;
int r;
- assert(m);
+ assert_return(m, -EINVAL);
if (m->sealed)
return -EPERM;
else
m->header->dbus1.serial = (uint32_t) cookie;
- m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
+ m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout_usec;
/* Add padding at the end of the fields part, since we know
* the body needs to start at an 8 byte alignment. We made
}
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
assert_return(m, -EINVAL);
assert_return(m->sealed, -EPERM);
return false;
}
-#endif // 0
static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
struct bus_body_part *part;
c->offset_index++;
- } else if (c->enclosing == 0 ||
- c->enclosing == SD_BUS_TYPE_STRUCT ||
- c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
+ } else if (IN_SET(c->enclosing, 0, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY)) {
int alignment;
size_t n, j;
return 0;
}
-
static int message_peek_body(
sd_bus_message *m,
size_t *rindex,
if (r < 0)
return r;
if (r == 0 && p[n] != 0) /* except the last item */
- n_variable ++;
+ n_variable++;
n_total++;
p += n;
const char *contents) {
struct bus_container *c, *w;
uint32_t *array_size = NULL;
- char *signature;
+ _cleanup_free_ char *signature = NULL;
size_t before;
- size_t *offsets = NULL;
+ _cleanup_free_ size_t *offsets = NULL;
size_t n_offsets = 0, item_size = 0;
int r;
r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
else
r = -EINVAL;
-
- if (r <= 0) {
- free(signature);
- free(offsets);
+ if (r <= 0)
return r;
- }
/* OK, let's fill it in */
w = m->containers + m->n_containers++;
w->enclosing = type;
- w->signature = signature;
+ w->signature = TAKE_PTR(signature);
w->peeked_signature = NULL;
w->index = 0;
w->array_size = array_size;
w->item_size = item_size;
- w->offsets = offsets;
+ w->offsets = TAKE_PTR(offsets);
w->n_offsets = n_offsets;
w->offset_index = 0;
return 1;
}
- if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
- c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
+ if (IN_SET(c->signature[c->index], SD_BUS_TYPE_STRUCT_BEGIN, SD_BUS_TYPE_DICT_ENTRY_BEGIN)) {
if (contents) {
size_t l;
t = types;
if (n_array != (unsigned) -1)
- n_array --;
+ n_array--;
else {
- types ++;
+ types++;
n_struct--;
}
if (sz == 0)
/* Zero length array, let's return some aligned
* pointer that is not NULL */
- p = (uint8_t*) NULL + align;
+ p = (uint8_t*) align;
else {
r = message_peek_body(m, &m->rindex, align, sz, &p);
if (r < 0)
(*signature)++;
- } else if (t == SD_BUS_TYPE_STRUCT ||
- t == SD_BUS_TYPE_DICT_ENTRY) {
+ } else if (IN_SET(t, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY)) {
r = signature_element_length(*signature, &l);
if (r < 0)
r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
- if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
+ if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client) {
m->creds.unique_name = (char*) m->sender;
m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
}
break;
-
case BUS_MESSAGE_HEADER_SIGNATURE: {
const char *s;
char *c;
if (!c)
return -ENOMEM;
- free(m->root_container.signature);
- m->root_container.signature = c;
+ free_and_replace(m->root_container.signature, c);
break;
}
return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
}
-/// UNNEEDED by elogind
-#if 0
+_public_ int sd_bus_message_set_sender(sd_bus_message *m, const char *sender) {
+ assert_return(m, -EINVAL);
+ assert_return(sender, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->sender, -EEXIST);
+
+ return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
+}
+
+#if 0 /// UNNEEDED by elogind
int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
size_t total;
void *p, *e;
- unsigned i;
+ size_t i;
struct bus_body_part *part;
assert(m);
}
_public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
- char **strv = NULL;
+ _cleanup_strv_free_ char **strv = NULL;
int r;
assert_return(m, -EINVAL);
assert_return(l, -EINVAL);
r = bus_message_read_strv_extend(m, &strv);
- if (r <= 0) {
- strv_free(strv);
+ if (r <= 0)
return r;
- }
- *l = strv;
+ *l = TAKE_PTR(strv);
return 1;
}
assert(str);
r = bus_message_get_arg_skip(m, i, &type, NULL);
- if (r < 0)
- return r;
+ if (r < 0)
+ return r;
if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE))
return -ENXIO;
assert(strv);
r = bus_message_get_arg_skip(m, i, &type, &contents);
- if (r < 0)
- return r;
+ if (r < 0)
+ return r;
if (type != SD_BUS_TYPE_ARRAY)
return -ENXIO;
return strempty(c->signature);
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_is_empty(sd_bus_message *m) {
assert_return(m, -EINVAL);
return streq(strempty(m->root_container.signature), strempty(signature));
}
-#endif // 0
_public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
bool done_something = false;
assert(r > 0);
- if (type == SD_BUS_TYPE_OBJECT_PATH ||
- type == SD_BUS_TYPE_SIGNATURE ||
- type == SD_BUS_TYPE_STRING)
+ if (IN_SET(type, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE, SD_BUS_TYPE_STRING))
r = sd_bus_message_append_basic(m, type, basic.string);
else
r = sd_bus_message_append_basic(m, type, &basic);
return done_something;
}
-/// UNNEEDED by elogind
-#if 0
_public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
const char *c;
char t;
return 1;
}
-#endif // 0
_public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
assert_return(m, NULL);
}
int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
- _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL;
usec_t timeout;
int r;
case SD_BUS_MESSAGE_METHOD_RETURN:
case SD_BUS_MESSAGE_METHOD_ERROR:
- n = message_new(bus, (*m)->header->type);
- if (!n)
+ r = sd_bus_message_new(bus, &n, (*m)->header->type);
+ if (r < 0)
return -ENOMEM;
+ assert(n);
+
n->reply_cookie = (*m)->reply_cookie;
r = message_append_reply_cookie(n, n->reply_cookie);
if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
timeout = BUS_DEFAULT_TIMEOUT;
- r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
+ r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
if (r < 0)
return r;
sd_bus_message_unref(*m);
- *m = n;
- n = NULL;
+ *m = TAKE_PTR(n);
return 0;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
int bus_message_append_sender(sd_bus_message *m, const char *sender) {
assert(m);
assert(sender);
return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
}
+#endif // 0
_public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
assert_return(m, -EINVAL);
m->priority = priority;
return 0;
}
-#endif // 0