summaryrefslogtreecommitdiff
path: root/src/libsystemd/sd-bus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd/sd-bus')
-rw-r--r--src/libsystemd/sd-bus/bus-control.c16
-rw-r--r--src/libsystemd/sd-bus/bus-convenience.c1
-rw-r--r--src/libsystemd/sd-bus/bus-creds.c2
-rw-r--r--src/libsystemd/sd-bus/bus-internal.c42
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h26
-rw-r--r--src/libsystemd/sd-bus/bus-introspect.c3
-rw-r--r--src/libsystemd/sd-bus/bus-kernel.c24
-rw-r--r--src/libsystemd/sd-bus/bus-match.c72
-rw-r--r--src/libsystemd/sd-bus/bus-match.h2
-rw-r--r--src/libsystemd/sd-bus/bus-message.c70
-rw-r--r--src/libsystemd/sd-bus/bus-message.h3
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c7
-rw-r--r--src/libsystemd/sd-bus/bus-track.c1
-rw-r--r--src/libsystemd/sd-bus/busctl.c1
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c39
-rw-r--r--src/libsystemd/sd-bus/test-bus-benchmark.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-chat.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-cleanup.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-error.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-gvariant.c1
-rw-r--r--src/libsystemd/sd-bus/test-bus-introspect.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel-bloom.c4
-rw-r--r--src/libsystemd/sd-bus/test-bus-kernel.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-match.c9
-rw-r--r--src/libsystemd/sd-bus/test-bus-objects.c2
-rw-r--r--src/libsystemd/sd-bus/test-bus-server.c1
26 files changed, 195 insertions, 139 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 95c7d4ebe4..aeb48bedd1 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -32,6 +32,7 @@
#include "bus-message.h"
#include "bus-control.h"
#include "bus-bloom.h"
+#include "bus-util.h"
#include "capability.h"
_public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
@@ -1308,7 +1309,16 @@ int bus_add_match_internal_kernel(
break;
}
- case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
+ case BUS_MATCH_ARG_HAS...BUS_MATCH_ARG_HAS_LAST: {
+ char buf[sizeof("arg")-1 + 2 + sizeof("-has")];
+
+ xsprintf(buf, "arg%i-has", c->type - BUS_MATCH_ARG_HAS);
+ bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
+ using_bloom = true;
+ break;
+ }
+
+ case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST:
/*
* XXX: DBus spec defines arg[0..63]path= matching to be
* a two-way glob. That is, if either string is a prefix
@@ -1322,7 +1332,6 @@ int bus_add_match_internal_kernel(
* to properly support multiple-matches here.
*/
break;
- }
case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
@@ -1333,7 +1342,7 @@ int bus_add_match_internal_kernel(
break;
}
- case BUS_MATCH_DESTINATION: {
+ case BUS_MATCH_DESTINATION:
/*
* Kernel only supports matching on destination IDs, but
* not on destination names. So just skip the
@@ -1351,7 +1360,6 @@ int bus_add_match_internal_kernel(
matches_name_change = false;
break;
- }
case BUS_MATCH_ROOT:
case BUS_MATCH_VALUE:
diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index 79747e058b..af5f7da11c 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -22,6 +22,7 @@
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-signature.h"
+#include "bus-util.h"
#include "bus-type.h"
_public_ int sd_bus_emit_signal(
diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c
index 130fbf7a23..1c365b7fcd 100644
--- a/src/libsystemd/sd-bus/bus-creds.c
+++ b/src/libsystemd/sd-bus/bus-creds.c
@@ -31,10 +31,10 @@
#include "fileio.h"
#include "audit.h"
#include "bus-message.h"
+#include "bus-util.h"
#include "strv.h"
#include "bus-creds.h"
#include "bus-label.h"
-#include "bus-internal.h"
enum {
CAP_OFFSET_INHERITABLE = 0,
diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c
index f4ab57f5bc..fea796cd30 100644
--- a/src/libsystemd/sd-bus/bus-internal.c
+++ b/src/libsystemd/sd-bus/bus-internal.c
@@ -371,45 +371,3 @@ int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
return 1;
}
-
-bool is_kdbus_wanted(void) {
- _cleanup_free_ char *value = NULL;
-#ifdef ENABLE_KDBUS
- const bool configured = true;
-#else
- const bool configured = false;
-#endif
- int r;
-
- if (get_proc_cmdline_key("kdbus", NULL) > 0)
- return true;
-
- r = get_proc_cmdline_key("kdbus=", &value);
- if (r <= 0)
- return configured;
-
- return parse_boolean(value) == 1;
-}
-
-bool is_kdbus_available(void) {
- static int cached = -1;
- _cleanup_close_ int fd = -1;
- struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
-
- if (cached >= 0)
- return (bool) cached;
-
- if (!is_kdbus_wanted()) {
- cached = false;
- return false;
- }
-
- fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
- if (fd < 0) {
- cached = false;
- return false;
- }
-
- cached = ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
- return cached;
-}
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 9b68fdd642..7af61a9433 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -37,29 +37,6 @@
#include "bus-kernel.h"
#include "kdbus.h"
-typedef enum BusTransport {
- BUS_TRANSPORT_LOCAL,
- BUS_TRANSPORT_REMOTE,
- BUS_TRANSPORT_MACHINE,
- _BUS_TRANSPORT_MAX,
- _BUS_TRANSPORT_INVALID = -1
-} BusTransport;
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_flush_close_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
-DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref);
-
-#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp)
-#define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp)
-#define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp)
-#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp)
-#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp)
-#define _cleanup_bus_track_unref_ _cleanup_(sd_bus_slot_unrefp)
-#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free)
-
struct reply_callback {
sd_bus_message_handler_t callback;
usec_t timeout;
@@ -417,9 +394,6 @@ int bus_get_root_path(sd_bus *bus);
int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);
-bool is_kdbus_wanted(void);
-bool is_kdbus_available(void);
-
#define bus_assert_return(expr, r, error) \
do { \
if (!assert_log(expr)) \
diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c
index c2233d0cf3..3107d00092 100644
--- a/src/libsystemd/sd-bus/bus-introspect.c
+++ b/src/libsystemd/sd-bus/bus-introspect.c
@@ -81,6 +81,9 @@ static void introspect_write_flags(struct introspect *i, int type, int flags) {
fputs(" <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n", i->f);
if (type == _SD_BUS_VTABLE_PROPERTY || type == _SD_BUS_VTABLE_WRITABLE_PROPERTY) {
+ if (flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)
+ fputs(" <annotation name=\"org.freedesktop.systemd1.Explicit\" value=\"true\"/>\n", i->f);
+
if (flags & SD_BUS_VTABLE_PROPERTY_CONST)
fputs(" <annotation name=\"org.freedesktop.DBus.Property.EmitsChangedSignal\" value=\"const\"/>\n", i->f);
else if (flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index 21f3700128..577a8b44c3 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -45,6 +45,7 @@
#include "bus-message.h"
#include "bus-kernel.h"
#include "bus-bloom.h"
+#include "bus-util.h"
#include "bus-label.h"
#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
@@ -167,6 +168,27 @@ static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i,
bloom_add_prefixes(data, size, n_hash, buf, t, '/');
}
+static void add_bloom_arg_has(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) {
+ char buf[sizeof("arg")-1 + 2 + sizeof("-has")];
+ char *e;
+
+ assert(data);
+ assert(size > 0);
+ assert(i < 64);
+ assert(t);
+
+ e = stpcpy(buf, "arg");
+ if (i < 10)
+ *(e++) = '0' + (char) i;
+ else {
+ *(e++) = '0' + (char) (i / 10);
+ *(e++) = '0' + (char) (i % 10);
+ }
+
+ strcpy(e, "-has");
+ bloom_add_pair(data, size, n_hash, buf, t);
+}
+
static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) {
void *data;
unsigned i;
@@ -221,7 +243,7 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter
return r;
while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0)
- add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
+ add_bloom_arg_has(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t);
if (r < 0)
return r;
diff --git a/src/libsystemd/sd-bus/bus-match.c b/src/libsystemd/sd-bus/bus-match.c
index f3b49c0c90..2b83f439a7 100644
--- a/src/libsystemd/sd-bus/bus-match.c
+++ b/src/libsystemd/sd-bus/bus-match.c
@@ -22,6 +22,7 @@
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-match.h"
+#include "bus-util.h"
#include "strv.h"
/* Example:
@@ -61,12 +62,13 @@
*/
static inline bool BUS_MATCH_IS_COMPARE(enum bus_match_node_type t) {
- return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_NAMESPACE_LAST;
+ return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_HAS_LAST;
}
static inline bool BUS_MATCH_CAN_HASH(enum bus_match_node_type t) {
return (t >= BUS_MATCH_MESSAGE_TYPE && t <= BUS_MATCH_PATH) ||
- (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST);
+ (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST) ||
+ (t >= BUS_MATCH_ARG_HAS && t <= BUS_MATCH_ARG_HAS_LAST);
}
static void bus_match_node_free(struct bus_match_node *node) {
@@ -178,12 +180,16 @@ static bool value_node_test(
case BUS_MATCH_INTERFACE:
case BUS_MATCH_MEMBER:
case BUS_MATCH_PATH:
- case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST: {
- char **i;
+ case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
if (value_str)
return streq_ptr(node->value.str, value_str);
+ return false;
+
+ case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: {
+ char **i;
+
STRV_FOREACH(i, value_strv)
if (streq_ptr(node->value.str, *i))
return true;
@@ -191,33 +197,20 @@ static bool value_node_test(
return false;
}
- case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST: {
- char **i;
-
+ case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
if (value_str)
return namespace_simple_pattern(node->value.str, value_str);
- STRV_FOREACH(i, value_strv)
- if (namespace_simple_pattern(node->value.str, *i))
- return true;
return false;
- }
case BUS_MATCH_PATH_NAMESPACE:
return path_simple_pattern(node->value.str, value_str);
- case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST: {
- char **i;
-
+ case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
if (value_str)
return path_complex_pattern(node->value.str, value_str);
- STRV_FOREACH(i, value_strv)
- if (path_complex_pattern(node->value.str, *i))
- return true;
-
return false;
- }
default:
assert_not_reached("Invalid node type");
@@ -248,6 +241,7 @@ static bool value_node_same(
case BUS_MATCH_MEMBER:
case BUS_MATCH_PATH:
case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
+ case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
case BUS_MATCH_PATH_NAMESPACE:
case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
@@ -371,15 +365,19 @@ int bus_match_run(
break;
case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
- (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str, &test_strv);
+ (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str);
break;
case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
- (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str, &test_strv);
+ (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str);
break;
case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
- (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str, &test_strv);
+ (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str);
+ break;
+
+ case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
+ (void) bus_message_get_arg_strv(m, node->type - BUS_MATCH_ARG_HAS, &test_strv);
break;
default:
@@ -742,6 +740,32 @@ enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n
return t;
}
+ if (n == 7 && startswith(k, "arg") && startswith(k + 4, "has")) {
+ int j;
+
+ j = undecchar(k[3]);
+ if (j < 0)
+ return -EINVAL;
+
+ return BUS_MATCH_ARG_HAS + j;
+ }
+
+ if (n == 8 && startswith(k, "arg") && startswith(k + 5, "has")) {
+ enum bus_match_node_type t;
+ int a, b;
+
+ a = undecchar(k[3]);
+ b = undecchar(k[4]);
+ if (a <= 0 || b < 0)
+ return -EINVAL;
+
+ t = BUS_MATCH_ARG_HAS + a * 10 + b;
+ if (t > BUS_MATCH_ARG_HAS_LAST)
+ return -EINVAL;
+
+ return t;
+ }
+
return -EINVAL;
}
@@ -1110,6 +1134,10 @@ const char* bus_match_node_type_to_string(enum bus_match_node_type t, char buf[]
snprintf(buf, l, "arg%inamespace", t - BUS_MATCH_ARG_NAMESPACE);
return buf;
+ case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
+ snprintf(buf, l, "arg%ihas", t - BUS_MATCH_ARG_HAS);
+ return buf;
+
default:
return NULL;
}
diff --git a/src/libsystemd/sd-bus/bus-match.h b/src/libsystemd/sd-bus/bus-match.h
index 56516be9fa..53ee0463ca 100644
--- a/src/libsystemd/sd-bus/bus-match.h
+++ b/src/libsystemd/sd-bus/bus-match.h
@@ -44,6 +44,8 @@ enum bus_match_node_type {
BUS_MATCH_ARG_PATH_LAST = BUS_MATCH_ARG_PATH + 63,
BUS_MATCH_ARG_NAMESPACE,
BUS_MATCH_ARG_NAMESPACE_LAST = BUS_MATCH_ARG_NAMESPACE + 63,
+ BUS_MATCH_ARG_HAS,
+ BUS_MATCH_ARG_HAS_LAST = BUS_MATCH_ARG_HAS + 63,
_BUS_MATCH_NODE_TYPE_MAX,
_BUS_MATCH_NODE_TYPE_INVALID = -1
};
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index bc531c2e3a..366a026426 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -35,6 +35,7 @@
#include "bus-type.h"
#include "bus-signature.h"
#include "bus-gvariant.h"
+#include "bus-util.h"
static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
@@ -5613,21 +5614,23 @@ _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
return 1;
}
-int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv) {
- const char *contents;
+static int bus_message_get_arg_skip(
+ sd_bus_message *m,
+ unsigned i,
+ char *_type,
+ const char **_contents) {
+
unsigned j;
- char type;
int r;
- assert(m);
- assert(str);
- assert(strv);
-
r = sd_bus_message_rewind(m, true);
if (r < 0)
return r;
for (j = 0;; j++) {
+ const char *contents;
+ char type;
+
r = sd_bus_message_peek_type(m, &type, &contents);
if (r < 0)
return r;
@@ -5639,31 +5642,56 @@ int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char **
!(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
return -ENXIO;
- if (j >= i)
- break;
+ if (j >= i) {
+ if (_contents)
+ *_contents = contents;
+ if (_type)
+ *_type = type;
+ return 0;
+ }
r = sd_bus_message_skip(m, NULL);
if (r < 0)
return r;
}
- if (type == SD_BUS_TYPE_ARRAY) {
+}
- r = sd_bus_message_read_strv(m, strv);
- if (r < 0)
- return r;
+int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str) {
+ char type;
+ int r;
- *str = NULL;
+ assert(m);
+ assert(str);
- } else {
- r = sd_bus_message_read_basic(m, type, str);
- if (r < 0)
- return r;
+ r = bus_message_get_arg_skip(m, i, &type, NULL);
+ if (r < 0)
+ return r;
- *strv = NULL;
- }
+ if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE))
+ return -ENXIO;
- return 0;
+ return sd_bus_message_read_basic(m, type, str);
+}
+
+int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv) {
+ const char *contents;
+ char type;
+ int r;
+
+ assert(m);
+ assert(strv);
+
+ r = bus_message_get_arg_skip(m, i, &type, &contents);
+ if (r < 0)
+ return r;
+
+ if (type != SD_BUS_TYPE_ARRAY)
+ return -ENXIO;
+ if (!STR_IN_SET(contents, "s", "o", "g"))
+ return -ENXIO;
+
+ return sd_bus_message_read_strv(m, strv);
}
_public_ int sd_bus_message_get_errno(sd_bus_message *m) {
diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h
index 088d5b1109..ff25003461 100644
--- a/src/libsystemd/sd-bus/bus-message.h
+++ b/src/libsystemd/sd-bus/bus-message.h
@@ -218,7 +218,8 @@ int bus_message_from_malloc(
const char *label,
sd_bus_message **ret);
-int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str, char ***strv);
+int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str);
+int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv);
int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index b2e617ada4..0593aa658a 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -26,6 +26,7 @@
#include "bus-type.h"
#include "bus-signature.h"
#include "bus-introspect.h"
+#include "bus-util.h"
#include "bus-slot.h"
#include "bus-objects.h"
@@ -749,6 +750,9 @@ static int vtable_append_all_properties(
if (v->flags & SD_BUS_VTABLE_HIDDEN)
continue;
+ if (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)
+ continue;
+
r = vtable_append_one_property(bus, reply, path, c, v, userdata, error);
if (r < 0)
return r;
@@ -1740,8 +1744,9 @@ static int add_object_vtable_internal(
if (!member_name_is_valid(v->x.property.member) ||
!signature_is_single(v->x.property.signature, false) ||
!(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) ||
- v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
+ (v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ||
(!!(v->flags & SD_BUS_VTABLE_PROPERTY_CONST) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) > 1 ||
+ ((v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) && (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)) ||
(v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) {
r = -EINVAL;
goto fail;
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
index 7803e39c3d..e43891be25 100644
--- a/src/libsystemd/sd-bus/bus-track.c
+++ b/src/libsystemd/sd-bus/bus-track.c
@@ -20,6 +20,7 @@
***/
#include "sd-bus.h"
+#include "bus-util.h"
#include "bus-internal.h"
#include "bus-track.h"
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 181621ffc7..a1f0f30d6c 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -30,6 +30,7 @@
#include "set.h"
#include "sd-bus.h"
+#include "bus-internal.h"
#include "bus-util.h"
#include "bus-dump.h"
#include "bus-signature.h"
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 31cdcb4e5b..5285278d92 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -44,6 +44,7 @@
#include "bus-kernel.h"
#include "bus-control.h"
#include "bus-objects.h"
+#include "bus-util.h"
#include "bus-container.h"
#include "bus-protocol.h"
#include "bus-track.h"
@@ -1001,6 +1002,8 @@ static int bus_parse_next_address(sd_bus *b) {
}
static int bus_start_address(sd_bus *b) {
+ bool container_kdbus_available = false;
+ bool kdbus_available = false;
int r;
assert(b);
@@ -1010,15 +1013,29 @@ static int bus_start_address(sd_bus *b) {
bus_close_fds(b);
+ /*
+ * Usually, if you provide multiple different bus-addresses, we
+ * try all of them in order. We use the first one that
+ * succeeds. However, if you mix kernel and unix addresses, we
+ * never try unix-addresses if a previous kernel address was
+ * tried and kdbus was available. This is required to prevent
+ * clients to fallback to the bus-proxy if kdbus is available
+ * but failed (eg., too many connections).
+ */
+
if (b->exec_path)
r = bus_socket_exec(b);
- else if ((b->nspid > 0 || b->machine) && b->kernel)
+ else if ((b->nspid > 0 || b->machine) && b->kernel) {
r = bus_container_connect_kernel(b);
- else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
+ if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT))
+ container_kdbus_available = true;
+ } else if (!container_kdbus_available && (b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
r = bus_container_connect_socket(b);
- else if (b->kernel)
+ else if (b->kernel) {
r = bus_kernel_connect(b);
- else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
+ if (r < 0 && !IN_SET(r, -ENOENT, -ESOCKTNOSUPPORT))
+ kdbus_available = true;
+ } else if (!kdbus_available && b->sockaddr.sa.sa_family != AF_UNSPEC)
r = bus_socket_connect(b);
else
skipped = true;
@@ -1173,10 +1190,7 @@ int bus_set_address_system(sd_bus *b) {
if (e)
return sd_bus_set_address(b, e);
- if (is_kdbus_available())
- return sd_bus_set_address(b, KERNEL_SYSTEM_BUS_ADDRESS);
-
- return sd_bus_set_address(b, UNIX_SYSTEM_BUS_ADDRESS);
+ return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
}
_public_ int sd_bus_open_system(sd_bus **ret) {
@@ -1224,17 +1238,16 @@ int bus_set_address_user(sd_bus *b) {
return sd_bus_set_address(b, e);
e = secure_getenv("XDG_RUNTIME_DIR");
- if (is_kdbus_available())
- (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid());
- else if (e) {
+ if (e) {
_cleanup_free_ char *ee = NULL;
ee = bus_address_escape(e);
if (!ee)
return -ENOMEM;
- (void) asprintf(&b->address, UNIX_USER_BUS_ADDRESS_FMT, ee);
- }
+ (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, getuid(), ee);
+ } else
+ (void) asprintf(&b->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid());
if (!b->address)
return -ENOMEM;
diff --git a/src/libsystemd/sd-bus/test-bus-benchmark.c b/src/libsystemd/sd-bus/test-bus-benchmark.c
index d3bf6da850..d14110aa04 100644
--- a/src/libsystemd/sd-bus/test-bus-benchmark.c
+++ b/src/libsystemd/sd-bus/test-bus-benchmark.c
@@ -28,6 +28,7 @@
#include "sd-bus.h"
#include "bus-kernel.h"
#include "bus-internal.h"
+#include "bus-util.h"
#define MAX_SIZE (2*1024*1024)
diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c
index a0aecc1f55..20f1b532b7 100644
--- a/src/libsystemd/sd-bus/test-bus-chat.c
+++ b/src/libsystemd/sd-bus/test-bus-chat.c
@@ -33,6 +33,7 @@
#include "bus-error.h"
#include "bus-match.h"
#include "bus-internal.h"
+#include "bus-util.h"
static int match_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
diff --git a/src/libsystemd/sd-bus/test-bus-cleanup.c b/src/libsystemd/sd-bus/test-bus-cleanup.c
index b483d47468..f586880593 100644
--- a/src/libsystemd/sd-bus/test-bus-cleanup.c
+++ b/src/libsystemd/sd-bus/test-bus-cleanup.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include "sd-bus.h"
+#include "bus-util.h"
#include "bus-internal.h"
#include "bus-message.h"
#include "refcnt.h"
diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c
index f2cfbc706f..5753c04b0e 100644
--- a/src/libsystemd/sd-bus/test-bus-error.c
+++ b/src/libsystemd/sd-bus/test-bus-error.c
@@ -20,6 +20,7 @@
***/
#include "sd-bus.h"
+#include "bus-error.h"
#include "bus-util.h"
#include "errno-list.h"
#include "bus-common-errors.h"
diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c
index 414d4e9a58..b078bdc5f6 100644
--- a/src/libsystemd/sd-bus/test-bus-gvariant.c
+++ b/src/libsystemd/sd-bus/test-bus-gvariant.c
@@ -27,6 +27,7 @@
#include "macro.h"
#include "sd-bus.h"
#include "bus-gvariant.h"
+#include "bus-util.h"
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-dump.h"
diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c
index b2caa02870..f39dedeb24 100644
--- a/src/libsystemd/sd-bus/test-bus-introspect.c
+++ b/src/libsystemd/sd-bus/test-bus-introspect.c
@@ -41,7 +41,7 @@ static const sd_bus_vtable vtable[] = {
SD_BUS_PROPERTY("AReadOnlyDeprecatedProperty", "(ut)", prop_get, 0, SD_BUS_VTABLE_DEPRECATED),
SD_BUS_PROPERTY("ChangingProperty", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Invalidating", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
- SD_BUS_PROPERTY("Constant", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Constant", "t", prop_get, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EXPLICIT),
SD_BUS_VTABLE_END
};
diff --git a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
index 90eb1f2a33..f3d1099dd2 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel-bloom.c
@@ -108,8 +108,10 @@ int main(int argc, char *argv[]) {
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "member='Pi_ep'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "arg0='foo_bar'", false);
- test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foobar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0='foo_bar'", false);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0has='foobar'", true);
+ test_one("/foo/bar/waldo", "waldo.com", "Piep", true, "foobar", "arg0has='foo_bar'", false);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar'", true);
test_one("/foo/bar/waldo", "waldo.com", "Piep", false, "foobar", "path='/foo/bar/waldo',interface='waldo.com',member='Piep',arg0='foobar2'", false);
diff --git a/src/libsystemd/sd-bus/test-bus-kernel.c b/src/libsystemd/sd-bus/test-bus-kernel.c
index 6284153a58..6506eaab2e 100644
--- a/src/libsystemd/sd-bus/test-bus-kernel.c
+++ b/src/libsystemd/sd-bus/test-bus-kernel.c
@@ -25,8 +25,8 @@
#include "log.h"
#include "sd-bus.h"
-#include "bus-util.h"
#include "bus-kernel.h"
+#include "bus-util.h"
#include "bus-dump.h"
int main(int argc, char *argv[]) {
diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c
index f659ba3124..75ea28371b 100644
--- a/src/libsystemd/sd-bus/test-bus-match.c
+++ b/src/libsystemd/sd-bus/test-bus-match.c
@@ -24,6 +24,7 @@
#include "bus-match.h"
#include "bus-message.h"
+#include "bus-util.h"
#include "bus-slot.h"
static bool mask[32];
@@ -114,10 +115,10 @@ int main(int argc, char *argv[]) {
assert_se(match_add(slots, &root, "arg1='two'", 12) >= 0);
assert_se(match_add(slots, &root, "member='waldo',arg2path='/prefix/'", 13) >= 0);
assert_se(match_add(slots, &root, "member=waldo,path='/foo/bar',arg3namespace='prefix'", 14) >= 0);
- assert_se(match_add(slots, &root, "arg4='pi'", 15) >= 0);
- assert_se(match_add(slots, &root, "arg4='pa'", 16) >= 0);
- assert_se(match_add(slots, &root, "arg4='po'", 17) >= 0);
- assert_se(match_add(slots, &root, "arg4='pu'", 18) >= 0);
+ assert_se(match_add(slots, &root, "arg4has='pi'", 15) >= 0);
+ assert_se(match_add(slots, &root, "arg4has='pa'", 16) >= 0);
+ assert_se(match_add(slots, &root, "arg4has='po'", 17) >= 0);
+ assert_se(match_add(slots, &root, "arg4='pi'", 18) >= 0);
bus_match_dump(&root, 0);
diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c
index 6b3bfad5b6..0a35b750b3 100644
--- a/src/libsystemd/sd-bus/test-bus-objects.c
+++ b/src/libsystemd/sd-bus/test-bus-objects.c
@@ -30,6 +30,7 @@
#include "sd-bus.h"
#include "bus-internal.h"
#include "bus-message.h"
+#include "bus-util.h"
#include "bus-dump.h"
struct context {
@@ -217,6 +218,7 @@ static const sd_bus_vtable vtable2[] = {
SD_BUS_PROPERTY("Value2", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
SD_BUS_PROPERTY("Value3", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Value4", "s", value_handler, 10, 0),
+ SD_BUS_PROPERTY("AnExplicitProperty", "s", NULL, offsetof(struct context, something), SD_BUS_VTABLE_PROPERTY_EXPLICIT|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
SD_BUS_VTABLE_END
};
diff --git a/src/libsystemd/sd-bus/test-bus-server.c b/src/libsystemd/sd-bus/test-bus-server.c
index 604df098cc..080d8eddb7 100644
--- a/src/libsystemd/sd-bus/test-bus-server.c
+++ b/src/libsystemd/sd-bus/test-bus-server.c
@@ -28,6 +28,7 @@
#include "sd-bus.h"
#include "bus-internal.h"
+#include "bus-util.h"
struct context {
int fds[2];