bus: if a a Set() vtable callback of a writable is left NULL, try to do the right thing automatically
This commit is contained in:
parent
43a43f5016
commit
9db7635521
2
TODO
2
TODO
|
@ -52,6 +52,8 @@ CGroup Rework Completion:
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
|
* Add a new Distribute=$NUMBER key to socket units that makes use of SO_REUSEPORT to distribute network traffic on $NUMBER instances
|
||||||
|
|
||||||
* tmpfiles: when applying ownership to /run/log/journal also do this for the journal fails contained in it
|
* tmpfiles: when applying ownership to /run/log/journal also do this for the journal fails contained in it
|
||||||
|
|
||||||
* rework list.h to use typeof() and thus simplify most linked list macros by not requring the type to be specified
|
* rework list.h to use typeof() and thus simplify most linked list macros by not requring the type to be specified
|
||||||
|
|
|
@ -2089,11 +2089,11 @@ static int method_callbacks_run(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (!streq(c->vtable->method.signature, signature)) {
|
if (!streq(strempty(c->vtable->method.signature), signature)) {
|
||||||
r = sd_bus_reply_method_errorf(bus, m,
|
r = sd_bus_reply_method_errorf(bus, m,
|
||||||
"org.freedesktop.DBus.Error.InvalidArgs",
|
"org.freedesktop.DBus.Error.InvalidArgs",
|
||||||
"Invalid arguments '%s' to call %s:%s, expecting '%s'.",
|
"Invalid arguments '%s' to call %s:%s, expecting '%s'.",
|
||||||
signature, c->interface, c->member, c->vtable->method.signature);
|
signature, c->interface, c->member, strempty(c->vtable->method.signature));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -2132,6 +2132,8 @@ static int invoke_property_get(
|
||||||
|
|
||||||
/* Automatic handling if no callback is defined. */
|
/* Automatic handling if no callback is defined. */
|
||||||
|
|
||||||
|
assert(bus_type_is_basic(v->property.signature[0]));
|
||||||
|
|
||||||
switch (v->property.signature[0]) {
|
switch (v->property.signature[0]) {
|
||||||
|
|
||||||
case SD_BUS_TYPE_STRING:
|
case SD_BUS_TYPE_STRING:
|
||||||
|
@ -2142,6 +2144,7 @@ static int invoke_property_get(
|
||||||
|
|
||||||
default:
|
default:
|
||||||
p = userdata;
|
p = userdata;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_bus_message_append_basic(m, v->property.signature[0], p);
|
r = sd_bus_message_append_basic(m, v->property.signature[0], p);
|
||||||
|
@ -2151,6 +2154,62 @@ static int invoke_property_get(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int invoke_property_set(
|
||||||
|
sd_bus *bus,
|
||||||
|
const sd_bus_vtable *v,
|
||||||
|
const char *path,
|
||||||
|
const char *interface,
|
||||||
|
const char *property,
|
||||||
|
sd_bus_message *value,
|
||||||
|
sd_bus_error *error,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(bus);
|
||||||
|
assert(v);
|
||||||
|
|
||||||
|
if (v->property.set)
|
||||||
|
return v->property.set(bus, path, interface, property, value, error, userdata);
|
||||||
|
|
||||||
|
/* Automatic handling if no callback is defined. */
|
||||||
|
|
||||||
|
assert(signature_is_single(v->property.signature, false));
|
||||||
|
assert(bus_type_is_basic(v->property.signature[0]));
|
||||||
|
|
||||||
|
switch (v->property.signature[0]) {
|
||||||
|
|
||||||
|
case SD_BUS_TYPE_STRING:
|
||||||
|
case SD_BUS_TYPE_OBJECT_PATH:
|
||||||
|
case SD_BUS_TYPE_SIGNATURE: {
|
||||||
|
const char *p;
|
||||||
|
char *n;
|
||||||
|
|
||||||
|
r = sd_bus_message_read_basic(value, v->property.signature[0], &p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
n = strdup(p);
|
||||||
|
if (!n)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
free(*(char**) userdata);
|
||||||
|
*(char**) userdata = n;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
r = sd_bus_message_read_basic(value, v->property.signature[0], userdata);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int property_get_set_callbacks_run(
|
static int property_get_set_callbacks_run(
|
||||||
sd_bus *bus,
|
sd_bus *bus,
|
||||||
sd_bus_message *m,
|
sd_bus_message *m,
|
||||||
|
@ -2212,12 +2271,9 @@ static int property_get_set_callbacks_run(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (c->vtable->property.set) {
|
r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, &error, u);
|
||||||
r = c->vtable->property.set(bus, m->path, c->interface, c->member, m, &error, u);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else
|
|
||||||
assert_not_reached("automatic properties not supported yet");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd_bus_error_is_set(&error)) {
|
if (sd_bus_error_is_set(&error)) {
|
||||||
|
@ -3767,8 +3823,8 @@ static int add_object_vtable_internal(
|
||||||
struct vtable_member *m;
|
struct vtable_member *m;
|
||||||
|
|
||||||
if (!member_name_is_valid(v->method.member) ||
|
if (!member_name_is_valid(v->method.member) ||
|
||||||
!signature_is_valid(v->method.signature, false) ||
|
!signature_is_valid(strempty(v->method.signature), false) ||
|
||||||
!signature_is_valid(v->method.result, false) ||
|
!signature_is_valid(strempty(v->method.result), false) ||
|
||||||
!(v->method.handler || (isempty(v->method.signature) && isempty(v->method.result))) ||
|
!(v->method.handler || (isempty(v->method.signature) && isempty(v->method.result))) ||
|
||||||
v->flags & (SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)) {
|
v->flags & (SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)) {
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
|
@ -3796,8 +3852,16 @@ static int add_object_vtable_internal(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case _SD_BUS_VTABLE_PROPERTY:
|
case _SD_BUS_VTABLE_WRITABLE_PROPERTY:
|
||||||
case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
|
|
||||||
|
if (!(v->property.set || bus_type_is_basic(v->property.signature[0]))) {
|
||||||
|
r = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall through */
|
||||||
|
|
||||||
|
case _SD_BUS_VTABLE_PROPERTY: {
|
||||||
struct vtable_member *m;
|
struct vtable_member *m;
|
||||||
|
|
||||||
if (!member_name_is_valid(v->property.member) ||
|
if (!member_name_is_valid(v->property.member) ||
|
||||||
|
@ -3834,7 +3898,7 @@ static int add_object_vtable_internal(
|
||||||
case _SD_BUS_VTABLE_SIGNAL:
|
case _SD_BUS_VTABLE_SIGNAL:
|
||||||
|
|
||||||
if (!member_name_is_valid(v->signal.member) ||
|
if (!member_name_is_valid(v->signal.member) ||
|
||||||
!signature_is_single(v->signal.signature, false)) {
|
!signature_is_single(strempty(v->signal.signature), false)) {
|
||||||
r = -EINVAL;
|
r = -EINVAL;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
*
|
*
|
||||||
* Add in:
|
* Add in:
|
||||||
*
|
*
|
||||||
* automatic properties for Set()
|
|
||||||
* node hierarchy updates during dispatching
|
* node hierarchy updates during dispatching
|
||||||
* emit_interfaces_added/emit_interfaces_removed
|
* emit_interfaces_added/emit_interfaces_removed
|
||||||
*
|
*
|
||||||
|
@ -48,7 +47,7 @@ struct context {
|
||||||
int fds[2];
|
int fds[2];
|
||||||
bool quit;
|
bool quit;
|
||||||
char *something;
|
char *something;
|
||||||
const char *automatic_string_property;
|
char *automatic_string_property;
|
||||||
uint32_t automatic_integer_property;
|
uint32_t automatic_integer_property;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,8 +152,8 @@ static const sd_bus_vtable vtable[] = {
|
||||||
SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0),
|
SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0),
|
||||||
SD_BUS_METHOD("Exit", "", "", exit_handler, 0),
|
SD_BUS_METHOD("Exit", "", "", exit_handler, 0),
|
||||||
SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
|
SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
|
||||||
SD_BUS_PROPERTY("AutomaticStringProperty", "s", NULL, offsetof(struct context, automatic_string_property), 0),
|
SD_BUS_WRITABLE_PROPERTY("AutomaticStringProperty", "s", NULL, NULL, offsetof(struct context, automatic_string_property), 0),
|
||||||
SD_BUS_PROPERTY("AutomaticIntegerProperty", "u", NULL, offsetof(struct context, automatic_integer_property), 0),
|
SD_BUS_WRITABLE_PROPERTY("AutomaticIntegerProperty", "u", NULL, NULL, offsetof(struct context, automatic_integer_property), 0),
|
||||||
SD_BUS_METHOD("NoOperation", "", "", NULL, 0),
|
SD_BUS_METHOD("NoOperation", "", "", NULL, 0),
|
||||||
SD_BUS_VTABLE_END
|
SD_BUS_VTABLE_END
|
||||||
};
|
};
|
||||||
|
@ -288,6 +287,16 @@ static int client(struct context *c) {
|
||||||
sd_bus_message_unref(reply);
|
sd_bus_message_unref(reply);
|
||||||
reply = NULL;
|
reply = NULL;
|
||||||
|
|
||||||
|
r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticIntegerProperty", &error, "u", 815);
|
||||||
|
assert_se(r >= 0);
|
||||||
|
|
||||||
|
assert_se(c->automatic_integer_property == 815);
|
||||||
|
|
||||||
|
r = sd_bus_set_property(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "AutomaticStringProperty", &error, "s", "Du Dödel, Du!");
|
||||||
|
assert_se(r >= 0);
|
||||||
|
|
||||||
|
assert_se(streq(c->automatic_string_property, "Du Dödel, Du!"));
|
||||||
|
|
||||||
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
|
r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
|
|
||||||
|
@ -393,7 +402,7 @@ int main(int argc, char *argv[]) {
|
||||||
zero(c);
|
zero(c);
|
||||||
|
|
||||||
c.automatic_integer_property = 4711;
|
c.automatic_integer_property = 4711;
|
||||||
c.automatic_string_property = "dudeldu";
|
assert_se(c.automatic_string_property = strdup("dudeldu"));
|
||||||
|
|
||||||
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
|
assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
|
||||||
|
|
||||||
|
@ -414,6 +423,7 @@ int main(int argc, char *argv[]) {
|
||||||
return PTR_TO_INT(p);
|
return PTR_TO_INT(p);
|
||||||
|
|
||||||
free(c.something);
|
free(c.something);
|
||||||
|
free(c.automatic_string_property);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,12 +57,9 @@ typedef struct {
|
||||||
/* Callbacks */
|
/* Callbacks */
|
||||||
|
|
||||||
typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata);
|
typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata);
|
||||||
|
|
||||||
typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
|
typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
|
||||||
typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, sd_bus_error *error, void *userdata);
|
typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, sd_bus_error *error, void *userdata);
|
||||||
|
|
||||||
typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void **found, void *userdata);
|
typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void **found, void *userdata);
|
||||||
|
|
||||||
typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, char ***nodes, void *userdata);
|
typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *path, char ***nodes, void *userdata);
|
||||||
|
|
||||||
#include "sd-bus-protocol.h"
|
#include "sd-bus-protocol.h"
|
||||||
|
|
Loading…
Reference in a new issue