summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/bus-kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-bus/bus-kernel.c')
-rw-r--r--src/libsystemd-bus/bus-kernel.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/libsystemd-bus/bus-kernel.c b/src/libsystemd-bus/bus-kernel.c
index 650e6b9659..0e47308238 100644
--- a/src/libsystemd-bus/bus-kernel.c
+++ b/src/libsystemd-bus/bus-kernel.c
@@ -1219,18 +1219,37 @@ int bus_kernel_create_namespace(const char *name, char **s) {
return fd;
}
-int bus_kernel_monitor(sd_bus *bus) {
- struct kdbus_cmd_monitor cmd_monitor;
- int r;
+int bus_kernel_create_monitor(const char *bus) {
+ struct kdbus_cmd_hello *hello;
+ char *p;
+ int fd;
assert(bus);
- cmd_monitor.id = 0;
- cmd_monitor.flags = KDBUS_MONITOR_ENABLE;
+ p = alloca(sizeof("/dev/kdbus/") - 1 + DECIMAL_STR_MAX(uid_t) + 1 + strlen(bus) + sizeof("/bus"));
+ sprintf(p, "/dev/kdbus/%lu-%s/bus", (unsigned long) getuid(), bus);
- r = ioctl(bus->input_fd, KDBUS_CMD_MONITOR, &cmd_monitor);
- if (r < 0)
+ fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
return -errno;
- return 1;
+ hello = alloca0(sizeof(struct kdbus_cmd_hello));
+ hello->size = sizeof(struct kdbus_cmd_hello);
+ hello->conn_flags = KDBUS_HELLO_ACTIVATOR;
+ hello->pool_size = KDBUS_POOL_SIZE;
+
+ if (ioctl(fd, KDBUS_CMD_HELLO, hello) < 0) {
+ close_nointr_nofail(fd);
+ return -errno;
+ }
+
+ /* The higher 32bit of both flags fields are considered
+ * 'incompatible flags'. Refuse them all for now. */
+ if (hello->bus_flags > 0xFFFFFFFFULL ||
+ hello->conn_flags > 0xFFFFFFFFULL) {
+ close_nointr_nofail(fd);
+ return -ENOTSUP;
+ }
+
+ return fd;
}