}
_public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
- assert_return(m, NULL);
+
+ if (!m)
+ return NULL;
assert(m->n_ref > 0);
m->n_ref--;
}
static size_t determine_word_size(size_t sz, size_t extra) {
- if (sz <= 0 && extra == 0)
- return 0;
- else if (sz + extra <= 0xFF)
+ if (sz + extra <= 0xFF)
return 1;
else if (sz + extra*2 <= 0xFFFF)
return 2;
if (!BUS_MESSAGE_IS_GVARIANT(m))
return 0;
- p = c->signature;
+ p = strempty(c->signature);
while (*p != 0) {
size_t n;
if (!a)
return -ENOMEM;
- p = c->signature;
+ p = strempty(c->signature);
for (i = 0, j = 0; i < c->n_offsets; i++) {
unsigned k;
size_t n;
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
- assert_return(bus_type_is_trivial(type), -EINVAL);
+ assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
assert_return(ptr || size == 0, -EINVAL);
assert_return(!m->poisoned, -ESTALE);
+ /* alignment and size of the trivial types (except bool) is
+ * identical for gvariant and dbus1 marshalling */
align = bus_type_get_alignment(type);
sz = bus_type_get_size(type);
part->size = size;
copy_fd = -1;
- message_extend_containers(m, size);
m->header->body_size += size;
+ message_extend_containers(m, size);
return sd_bus_message_close_container(m);
}
return 0;
}
-int bus_message_seal(sd_bus_message *m, uint64_t serial) {
+int bus_message_seal(sd_bus_message *m, uint64_t serial, usec_t timeout) {
struct bus_body_part *part;
size_t l, a;
unsigned i;
return r;
m->header->serial = serial;
+ m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
/* Add padding at the end of the fields part, since we know
* the body needs to start at an 8 byte alignment. We made
*rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
c->item_size = c->offsets[c->offset_index+1] - *rindex;
} else {
+
+ if (c->offset_index+1 >= (c->end-c->begin)/sz)
+ goto end;
+
/* Fixed-size array */
- *rindex += sz;
+ *rindex = c->begin + (c->offset_index+1) * sz;
c->item_size = sz;
}
}
part = find_part(m, start, nbytes, (void**) &q);
- if (!part || !q)
+ if (!part || (nbytes > 0 && !q))
return -EBADMSG;
*rindex = end;
int r;
assert(m);
- assert(signature);
assert(item_size);
assert(offsets);
assert(n_offsets);
+ if (isempty(signature)) {
+ *item_size = 0;
+ *offsets = NULL;
+ *n_offsets = 0;
+ return 0;
+ }
+
sz = determine_word_size(size, 0);
+ if (sz <= 0)
+ return -EBADMSG;
/* First, loop over signature and count variable elements and
* elements in general. We use this to know how large the
_public_ int sd_bus_message_exit_container(sd_bus_message *m) {
struct bus_container *c;
+ unsigned saved;
int r;
assert_return(m, -EINVAL);
c = message_get_container(m);
+ saved = c->index;
+ c->index = c->saved_index;
r = container_next_item(m, c, &m->rindex);
+ c->index = saved;
if (r < 0)
return r;
m->rindex = c->begin;
}
+ c->offset_index = 0;
+ c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
+
return !isempty(c->signature);
}
uint32_t unix_fds = 0;
void *offsets = NULL;
unsigned n_offsets = 0;
- size_t sz;
+ size_t sz = 0;
unsigned i = 0;
assert(m);
if (m->n_fds != unix_fds)
return -EBADMSG;
- if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
- return -EBADMSG;
-
switch (m->header->type) {
case SD_BUS_MESSAGE_SIGNAL:
assert_return(m, NULL);
c = complete ? &m->root_container : message_get_container(m);
- return c->signature ?: "";
+ return strempty(c->signature);
}
_public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {