#include "bus-message.h"
#include "bus-type.h"
#include "bus-socket.h"
+#include "bus-kernel.h"
#include "bus-control.h"
static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
free(b->unique_name);
free(b->auth_buffer);
free(b->address);
+ free(b->kernel);
free(b->exec_path);
strv_free(b->exec_argv);
assert(bus);
- if (!bus->bus_client)
+ if (!bus->bus_client || bus->is_kernel)
return 0;
r = sd_bus_message_new_method_call(
int bus_start_running(sd_bus *bus) {
assert(bus);
- if (bus->bus_client) {
+ if (bus->bus_client && !bus->is_kernel) {
bus->state = BUS_HELLO;
return 1;
}
return r;
}
+static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
+ _cleanup_free_ char *path = NULL;
+ int r;
+
+ assert(b);
+ assert(p);
+ assert(*p);
+ assert(guid);
+
+ while (**p != 0 && **p != ';') {
+ r = parse_address_key(p, "guid", guid);
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ continue;
+
+ r = parse_address_key(p, "path", &path);
+ if (r < 0)
+ return r;
+ else if (r > 0)
+ continue;
+
+ skip_address_key(p);
+ }
+
+ if (!path)
+ return -EINVAL;
+
+ free(b->kernel);
+ b->kernel = path;
+ path = NULL;
+
+ return 0;
+}
+
static void bus_reset_parsed_address(sd_bus *b) {
assert(b);
b->exec_path = NULL;
b->exec_argv = NULL;
b->server_id = SD_ID128_NULL;
+ free(b->kernel);
+ b->kernel = NULL;
}
static int bus_parse_next_address(sd_bus *b) {
break;
+ } else if (startswith(a, "kernel:")) {
+
+ a += 7;
+ r = parse_kernel_address(b, &a, &guid);
+ if (r < 0)
+ return r;
+
+ break;
}
a = strchr(a, ';');
if (r >= 0)
return r;
+ b->last_connect_error = -r;
+ } else if (b->kernel) {
+
+ r = bus_kernel_connect(b);
+ if (r >= 0)
+ return r;
+
b->last_connect_error = -r;
}
}
static int bus_start_fd(sd_bus *b) {
+ struct stat st;
int r;
assert(b);
return r;
}
- return bus_socket_take_fd(b);
+ if (fstat(b->input_fd, &st) < 0)
+ return -errno;
+
+ if (S_ISCHR(b->input_fd))
+ return bus_kernel_take_fd(b);
+ else
+ return bus_socket_take_fd(b);
}
int sd_bus_start(sd_bus *bus) {
if (bus->input_fd >= 0)
r = bus_start_fd(bus);
- else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path)
+ else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel)
r = bus_start_address(bus);
else
return -EINVAL;
while (bus->wqueue_size > 0) {
- r = bus_socket_write_message(bus, bus->wqueue[0], &bus->windex);
+ if (bus->is_kernel)
+ r = bus_kernel_write_message(bus, bus->wqueue[0]);
+ else
+ r = bus_socket_write_message(bus, bus->wqueue[0], &bus->windex);
+
if (r < 0) {
sd_bus_close(bus);
return r;
} else if (r == 0)
/* Didn't do anything this time */
return ret;
- else if (bus->windex >= bus_message_size(bus->wqueue[0])) {
+ else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
/* Fully written. Let's drop the entry from
* the queue.
*
/* Try to read a new message */
do {
- r = bus_socket_read_message(bus, &z);
+ if (bus->is_kernel)
+ r = bus_kernel_read_message(bus, &z);
+ else
+ r = bus_socket_read_message(bus, &z);
+
if (r < 0) {
sd_bus_close(bus);
return r;
if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
size_t idx = 0;
- r = bus_socket_write_message(bus, m, &idx);
+ if (bus->is_kernel)
+ r = bus_kernel_write_message(bus, m);
+ else
+ r = bus_socket_write_message(bus, m, &idx);
+
if (r < 0) {
sd_bus_close(bus);
return r;
- } else if (idx < bus_message_size(m)) {
+ } else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
/* Wasn't fully written. So let's remember how
* much was written. Note that the first entry
* of the wqueue array is always allocated so
room = true;
}
- r = bus_socket_read_message(bus, &incoming);
+ if (bus->is_kernel)
+ r = bus_kernel_read_message(bus, &incoming);
+ else
+ r = bus_socket_read_message(bus, &incoming);
if (r < 0)
return r;
if (incoming) {