#include "strv.h"
#include "time-util.h"
#include "cgroup-util.h"
+#include "memfd-util.h"
#include "sd-bus.h"
#include "bus-message.h"
if (part->mapped > 0)
assert_se(munmap(part->data, part->mapped) == 0);
- close_nointr_nofail(part->memfd);
+ safe_close(part->memfd);
}
} else if (part->munmap_this)
message_reset_parts(m);
- if (m->free_kdbus)
- free(m->kdbus);
-
if (m->release_kdbus) {
- uint64_t off;
+ struct kdbus_cmd_free cmd_free;
- off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
- ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);
+ cmd_free.flags = 0;
+ cmd_free.offset = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
+ (void) ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &cmd_free);
}
- if (m->bus)
- sd_bus_unref(m->bus);
+ if (m->free_kdbus)
+ free(m->kdbus);
+
+ sd_bus_unref(m->bus);
if (m->free_fds) {
close_many(m->fds, m->n_fds);
/* Zero out padding */
if (start > old_size)
- memset((uint8_t*) np + old_size, 0, start - old_size);
+ memzero((uint8_t*) np + old_size, start - old_size);
op = m->header;
m->header = np;
return -ENOMEM;
p[0] = h;
- memset(p+1, 0, 7);
+ memzero(p+1, 7);
memcpy(p+8, s, l);
p[8+l] = 0;
p[8+l+1] = 0;
return -ENOMEM;
p[0] = h;
- memset(p+1, 0, 7);
+ memzero(p+1, 7);
*((uint32_t*) (p + 8)) = x;
p[12] = 0;
p[13] = 'u';
struct bus_header *h;
size_t a, label_sz;
+ assert(bus);
assert(buffer || length <= 0);
assert(fds || n_fds <= 0);
assert(ret);
m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
}
- if (bus)
- m->bus = sd_bus_ref(bus);
-
+ m->bus = sd_bus_ref(bus);
*ret = m;
+
return 0;
}
static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
sd_bus_message *m;
+ assert(bus);
+
m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
if (!m)
return NULL;
m->header->version = bus ? bus->message_version : 1;
m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
-
- if (bus)
- m->bus = sd_bus_ref(bus);
+ m->bus = sd_bus_ref(bus);
return m;
}
_public_ int sd_bus_message_new_signal(
sd_bus *bus,
+ sd_bus_message **m,
const char *path,
const char *interface,
- const char *member,
- sd_bus_message **m) {
+ const char *member) {
sd_bus_message *t;
int r;
- assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(bus, -ENOTCONN);
+ assert_return(bus->state != BUS_UNSET, -ENOTCONN);
assert_return(object_path_is_valid(path), -EINVAL);
assert_return(interface_name_is_valid(interface), -EINVAL);
assert_return(member_name_is_valid(member), -EINVAL);
_public_ int sd_bus_message_new_method_call(
sd_bus *bus,
+ sd_bus_message **m,
const char *destination,
const char *path,
const char *interface,
- const char *member,
- sd_bus_message **m) {
+ const char *member) {
sd_bus_message *t;
int r;
- assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(bus, -ENOTCONN);
+ assert_return(bus->state != BUS_UNSET, -ENOTCONN);
assert_return(!destination || service_name_is_valid(destination), -EINVAL);
assert_return(object_path_is_valid(path), -EINVAL);
assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
assert_return(call, -EINVAL);
assert_return(call->sealed, -EPERM);
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
- assert_return(!call->bus || call->bus->state != BUS_UNSET, -ENOTCONN);
+ assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
assert_return(m, -EINVAL);
t = message_new(call->bus, type);
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
t->reply_cookie = BUS_MESSAGE_COOKIE(call);
- r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
+ r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
if (r < 0)
goto fail;
_public_ int sd_bus_message_new_method_error(
sd_bus_message *call,
- const sd_bus_error *e,
- sd_bus_message **m) {
+ sd_bus_message **m,
+ const sd_bus_error *e) {
sd_bus_message *t;
int r;
bus_error_setfv(&error, name, format, ap);
va_end(ap);
- return sd_bus_message_new_method_error(call, &error, m);
+ return sd_bus_message_new_method_error(call, m, &error);
}
_public_ int sd_bus_message_new_method_errno(
sd_bus_message *call,
+ sd_bus_message **m,
int error,
- const sd_bus_error *p,
- sd_bus_message **m) {
+ const sd_bus_error *p) {
_cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
if (sd_bus_error_is_set(p))
- return sd_bus_message_new_method_error(call, p, m);
+ return sd_bus_message_new_method_error(call, m, p);
sd_bus_error_set_errno(&berror, error);
- return sd_bus_message_new_method_error(call, &berror, m);
+ return sd_bus_message_new_method_error(call, m, &berror);
}
_public_ int sd_bus_message_new_method_errnof(
bus_error_set_errnofv(&berror, error, format, ap);
va_end(ap);
- return sd_bus_message_new_method_error(call, &berror, m);
+ return sd_bus_message_new_method_error(call, m, &berror);
}
int bus_message_new_synthetic_error(
sd_bus_message *t;
int r;
+ assert(bus);
assert(sd_bus_error_is_set(e));
assert(m);
t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
t->reply_cookie = cookie;
- r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_cookie);
+ r = message_append_field_uint32(t, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) t->reply_cookie);
if (r < 0)
goto fail;
assert(m->n_ref > 0);
m->n_ref--;
- if (m->n_ref <= 0)
- message_free(m);
+ if (m->n_ref > 0)
+ return NULL;
+ message_free(m);
return NULL;
}
return 0;
}
-_public_ int sd_bus_message_get_no_reply(sd_bus_message *m) {
+_public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
assert_return(m, -EINVAL);
- return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
+ return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
+ !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
}
-_public_ int sd_bus_message_get_no_auto_start(sd_bus_message *m) {
+_public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
assert_return(m, -EINVAL);
- return !!(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
+ return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
+}
+
+_public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
+ assert_return(m, -EINVAL);
+
+ return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
+ (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
}
_public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
return 1;
}
-_public_ int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
+_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;
+ else
+ m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
return 0;
}
-_public_ int sd_bus_message_set_no_auto_start(sd_bus_message *m, int b) {
+_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;
+
+ return 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_NO_AUTO_START;
+ m->header->flags &= ~BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
return 0;
}
uint64_t new_allocated;
new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
- r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &new_allocated);
+ r = memfd_set_size(part->memfd, new_allocated);
if (r < 0) {
m->poisoned = true;
- return -errno;
+ return r;
}
part->allocated = new_allocated;
return NULL;
if (padding > 0) {
- memset(p, 0, padding);
+ memzero(p, padding);
p = (uint8_t*) p + padding;
}
f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
if (!f) {
m->poisoned = true;
- close_nointr_nofail(copy);
+ safe_close(copy);
return -ENOMEM;
}
struct bus_container *c, *w;
uint32_t *array_size = NULL;
char *signature;
- size_t before, begin;
+ size_t before, begin = 0;
bool need_offsets = false;
int r;
if (iov[i].iov_base)
memcpy(p, iov[i].iov_base, iov[i].iov_len);
else
- memset(p, 0, iov[i].iov_len);
+ memzero(p, iov[i].iov_len);
p = (uint8_t*) p + iov[i].iov_len;
}
_public_ int sd_bus_message_append_array_memfd(sd_bus_message *m,
char type,
- sd_memfd *memfd) {
+ int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
ssize_t align, sz;
if (!m)
return -EINVAL;
- if (!memfd)
+ if (memfd < 0)
return -EINVAL;
if (m->sealed)
return -EPERM;
if (m->poisoned)
return -ESTALE;
- r = sd_memfd_set_sealed(memfd, true);
+ r = memfd_set_sealed(memfd);
if (r < 0)
return r;
- copy_fd = sd_memfd_dup_fd(memfd);
+ copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
- r = sd_memfd_get_size(memfd, &size);
+ r = memfd_get_size(memfd, &size);
if (r < 0)
return r;
return sd_bus_message_close_container(m);
}
-_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
+_public_ int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd) {
_cleanup_close_ int copy_fd = -1;
struct bus_body_part *part;
struct bus_container *c;
int r;
assert_return(m, -EINVAL);
- assert_return(memfd, -EINVAL);
+ assert_return(memfd >= 0, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(!m->poisoned, -ESTALE);
- r = sd_memfd_set_sealed(memfd, true);
+ r = memfd_set_sealed(memfd);
if (r < 0)
return r;
- copy_fd = sd_memfd_dup_fd(memfd);
+ copy_fd = dup(memfd);
if (copy_fd < 0)
return copy_fd;
- r = sd_memfd_get_size(memfd, &size);
+ r = memfd_get_size(memfd, &size);
if (r < 0)
return r;
l = BUS_MESSAGE_FIELDS_SIZE(m);
a = ALIGN8(l) - l;
if (a > 0)
- memset((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, 0, a);
+ memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + l, a);
/* If this is something we can send as memfd, then let's seal
the memfd now. Note that we can send memfds as payload only
for directed messages, and not for broadcasts. */
- if (m->destination && m->bus && m->bus->use_memfd) {
+ if (m->destination && m->bus->use_memfd) {
MESSAGE_FOREACH_PART(part, i, m)
if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) {
uint64_t sz;
/* Then, sync up real memfd size */
sz = part->size;
- if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &sz) < 0)
- return -errno;
+ r = memfd_set_size(part->memfd, sz);
+ if (r < 0)
+ return r;
/* Finally, try to seal */
- if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0)
+ if (memfd_set_sealed(part->memfd) >= 0)
part->sealed = true;
}
}
psz = PAGE_ALIGN(part->size);
if (part->memfd >= 0)
- p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
+ p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, 0);
else if (part->is_zero)
p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
else
* in a single stackframe. We hence implement our own
* home-grown stack in an array. */
- n_array = (unsigned) -1; /* lenght of current array entries */
+ n_array = (unsigned) -1; /* length of current array entries */
n_struct = strlen(types); /* length of current struct contents signature */
for (;;) {
size_t ri;
int r;
uint32_t unix_fds = 0;
+ bool unix_fds_set = false;
void *offsets = NULL;
unsigned n_offsets = 0;
size_t sz = 0;
r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
- if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
+ if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
m->creds.unique_name = (char*) m->sender;
m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
}
break;
}
- case BUS_MESSAGE_HEADER_REPLY_SERIAL:
+ case BUS_MESSAGE_HEADER_REPLY_SERIAL: {
+ uint32_t serial;
+
if (m->reply_cookie != 0)
return -EBADMSG;
if (!streq(signature, "u"))
return -EBADMSG;
- r = message_peek_field_uint32(m, &ri, item_size, &m->reply_cookie);
+ r = message_peek_field_uint32(m, &ri, item_size, &serial);
if (r < 0)
return r;
+ m->reply_cookie = serial;
+
if (m->reply_cookie == 0)
return -EBADMSG;
break;
+ }
case BUS_MESSAGE_HEADER_UNIX_FDS:
- if (unix_fds != 0)
+ if (unix_fds_set)
return -EBADMSG;
if (!streq(signature, "u"))
if (r < 0)
return -EBADMSG;
- if (unix_fds == 0)
- return -EBADMSG;
-
+ unix_fds_set = true;
break;
default:
}
_public_ int sd_bus_message_get_errno(sd_bus_message *m) {
- assert_return(m, -EINVAL);
+ assert_return(m, EINVAL);
if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
return 0;
switch ((*m)->header->type) {
case SD_BUS_MESSAGE_SIGNAL:
- r = sd_bus_message_new_signal(bus, (*m)->path, (*m)->interface, (*m)->member, &n);
+ r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
if (r < 0)
return r;
break;
case SD_BUS_MESSAGE_METHOD_CALL:
- r = sd_bus_message_new_method_call(bus, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member, &n);
+ r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
if (r < 0)
return r;
return -ENOMEM;
n->reply_cookie = (*m)->reply_cookie;
- r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_cookie);
+ r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) n->reply_cookie);
if (r < 0)
return r;
return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
}
+
+_public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
+ assert_return(m, -EINVAL);
+ assert_return(priority, -EINVAL);
+
+ *priority = m->priority;
+ return 0;
+}
+
+_public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
+ assert_return(m, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+
+ m->priority = priority;
+ return 0;
+}