diff options
author | Lennart Poettering <lennart@poettering.net> | 2024-10-15 13:40:24 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2024-10-15 14:15:21 +0200 |
commit | 12641ecd67875b7bf18db06c0afa40c37d804750 (patch) | |
tree | 1fbaf4210daf90a6f98a35a6cff7d2c6cf78310f | |
parent | network: add AF_TO_ADDRESS_FAMILY() helper (diff) | |
download | systemd-12641ecd67875b7bf18db06c0afa40c37d804750.tar.xz systemd-12641ecd67875b7bf18db06c0afa40c37d804750.zip |
sd-varlink: add new sd_varlink_error_is_invalid_parameter() helper
Diffstat (limited to '')
-rw-r--r-- | src/libsystemd/libsystemd.sym | 1 | ||||
-rw-r--r-- | src/libsystemd/sd-varlink/sd-varlink.c | 20 | ||||
-rw-r--r-- | src/systemd/sd-varlink.h | 2 | ||||
-rw-r--r-- | src/test/test-varlink.c | 57 |
4 files changed, 77 insertions, 3 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index b3f46f90f1..e1836da08f 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -975,6 +975,7 @@ global: sd_varlink_error_errno; sd_varlink_error_invalid_parameter; sd_varlink_error_invalid_parameter_name; + sd_varlink_error_is_invalid_parameter; sd_varlink_error_to_errno; sd_varlink_errorb; sd_varlink_flush; diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c index 70615bb3e3..fb42e3205d 100644 --- a/src/libsystemd/sd-varlink/sd-varlink.c +++ b/src/libsystemd/sd-varlink/sd-varlink.c @@ -4112,3 +4112,23 @@ _public_ int sd_varlink_error_to_errno(const char *error, sd_json_variant *param return -EBADR; /* Catch-all */ } + +_public_ int sd_varlink_error_is_invalid_parameter(const char *error, sd_json_variant *parameter, const char *name) { + + /* Returns true if the specified error result is an invalid parameter error for the parameter 'name' */ + + if (!streq_ptr(error, SD_VARLINK_ERROR_INVALID_PARAMETER)) + return false; + + if (!name) + return true; + + if (!sd_json_variant_is_object(parameter)) + return false; + + sd_json_variant *e = sd_json_variant_by_key(parameter, "parameter"); + if (!e || !sd_json_variant_is_string(e)) + return false; + + return streq(sd_json_variant_string(e), name); +} diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h index 4c943d5389..4596561ed3 100644 --- a/src/systemd/sd-varlink.h +++ b/src/systemd/sd-varlink.h @@ -266,6 +266,8 @@ int sd_varlink_invocation(sd_varlink_invocation_flags_t flags); int sd_varlink_error_to_errno(const char *error, sd_json_variant *parameters); +int sd_varlink_error_is_invalid_parameter(const char *error, sd_json_variant *parameter, const char *name); + /* Define helpers so that __attribute__((cleanup(sd_varlink_unrefp))) and similar may be used. */ _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_varlink, sd_varlink_unref); _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_varlink, sd_varlink_close_unref); diff --git a/src/test/test-varlink.c b/src/test/test-varlink.c index 17a78633cc..cafe98871b 100644 --- a/src/test/test-varlink.c +++ b/src/test/test-varlink.c @@ -326,7 +326,7 @@ static int block_fd_handler(sd_event_source *s, int fd, uint32_t revents, void * return 0; } -int main(int argc, char *argv[]) { +TEST(chat) { _cleanup_(sd_event_source_unrefp) sd_event_source *block_event = NULL; _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL; _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *c = NULL; @@ -337,8 +337,6 @@ int main(int argc, char *argv[]) { pthread_t t; const char *sp; - test_setup_logging(LOG_DEBUG); - assert_se(mkdtemp_malloc("/tmp/varlink-test-XXXXXX", &tmpdir) >= 0); sp = strjoina(tmpdir, "/socket"); @@ -377,6 +375,59 @@ int main(int argc, char *argv[]) { assert_se(sd_event_loop(e) >= 0); assert_se(pthread_join(t, NULL) == 0); +} + +static int method_invalid(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { + int r; + + sd_json_dispatch_field table[] = { + { "iexist", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY }, + {} + }; + + const char *p = NULL; + r = sd_varlink_dispatch(link, parameters, table, &p); + if (r != 0) + return r; + + assert_not_reached(); +} + +static int reply_invalid(sd_varlink *link, sd_json_variant *parameters, const char *error_id, sd_varlink_reply_flags_t flags, void *userdata) { + assert(sd_varlink_error_is_invalid_parameter(error_id, parameters, "idontexist")); + assert(sd_event_exit(sd_varlink_get_event(link), EXIT_SUCCESS) >= 0); return 0; } + +TEST(invalid_parameter) { + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + assert_se(sd_event_default(&e) >= 0); + + _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL; + assert_se(sd_varlink_server_new(&s, 0) >= 0); + + assert_se(sd_varlink_server_attach_event(s, e, 0) >= 0); + + assert_se(sd_varlink_server_bind_method(s, "foo.mytest.Invalid", method_invalid) >= 0); + + int connfd[2]; + assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, connfd) >= 0); + assert_se(sd_varlink_server_add_connection(s, connfd[0], /* ret= */ NULL) >= 0); + + _cleanup_(sd_varlink_unrefp) sd_varlink *c = NULL; + assert_se(sd_varlink_connect_fd(&c, connfd[1]) >= 0); + + assert_se(sd_varlink_attach_event(c, e, 0) >= 0); + + assert_se(sd_varlink_bind_reply(c, reply_invalid) >= 0); + + assert_se(sd_varlink_invokebo(c, "foo.mytest.Invalid", + SD_JSON_BUILD_PAIR_STRING("iexist", "foo"), + SD_JSON_BUILD_PAIR_STRING("idontexist", "bar")) >= 0); + + + assert_se(sd_event_loop(e) >= 0); +} + +DEFINE_TEST_MAIN(LOG_DEBUG); |