diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 1b0b72085e..beff530b92 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -17,6 +17,7 @@ #include "capsule-util.h" #include "escape.h" #include "fd-util.h" +#include "fdset.h" #include "fileio.h" #include "format-table.h" #include "glyph-util.h" @@ -1477,12 +1478,13 @@ static int status(int argc, char **argv, void *userdata) { return 0; } -static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) { +static int message_append_cmdline(sd_bus_message *m, const char *signature, FDSet **passed_fdset, char ***x) { char **p; int r; assert(m); assert(signature); + assert(passed_fdset); assert(x); p = *x; @@ -1631,7 +1633,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char return bus_log_create_error(r); for (unsigned i = 0; i < n; i++) { - r = message_append_cmdline(m, s, &p); + r = message_append_cmdline(m, s, passed_fdset, &p); if (r < 0) return r; } @@ -1648,7 +1650,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char if (r < 0) return bus_log_create_error(r); - r = message_append_cmdline(m, v, &p); + r = message_append_cmdline(m, v, passed_fdset, &p); if (r < 0) return r; @@ -1680,7 +1682,7 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char if (r < 0) return bus_log_create_error(r); - r = message_append_cmdline(m, s, &p); + r = message_append_cmdline(m, s, passed_fdset, &p); if (r < 0) return r; } @@ -1691,9 +1693,25 @@ static int message_append_cmdline(sd_bus_message *m, const char *signature, char break; } - case SD_BUS_TYPE_UNIX_FD: - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "UNIX file descriptor not supported as type."); + case SD_BUS_TYPE_UNIX_FD: { + int fd; + + fd = parse_fd(v); + if (fd < 0) + return log_error_errno(fd, "Failed to parse '%s' as a file descriptor: %m", v); + + if (!*passed_fdset) { + r = fdset_new_fill(/* filter_cloexec= */ 0, passed_fdset); + if (r < 0) + return log_error_errno(r, "Failed to create fd set: %m"); + } + + if (!fdset_contains(*passed_fdset, fd)) + return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Failed to find file descriptor '%s' among passed file descriptors.", v); + + r = sd_bus_message_append_basic(m, t, &fd); + break; + } default: return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -2049,6 +2067,7 @@ static int call(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; int r; r = acquire_bus(false, &bus); @@ -2085,7 +2104,7 @@ static int call(int argc, char **argv, void *userdata) { p = argv+6; - r = message_append_cmdline(m, argv[5], &p); + r = message_append_cmdline(m, argv[5], &passed_fdset, &p); if (r < 0) return r; @@ -2151,6 +2170,7 @@ static int call(int argc, char **argv, void *userdata) { static int emit_signal(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; int r; r = acquire_bus(false, &bus); @@ -2176,7 +2196,7 @@ static int emit_signal(int argc, char **argv, void *userdata) { p = argv+5; - r = message_append_cmdline(m, argv[4], &p); + r = message_append_cmdline(m, argv[4], &passed_fdset, &p); if (r < 0) return r; @@ -2265,6 +2285,7 @@ static int set_property(int argc, char **argv, void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_fdset_free_ FDSet *passed_fdset = NULL; char **p; int r; @@ -2286,7 +2307,7 @@ static int set_property(int argc, char **argv, void *userdata) { return bus_log_create_error(r); p = argv + 6; - r = message_append_cmdline(m, argv[5], &p); + r = message_append_cmdline(m, argv[5], &passed_fdset, &p); if (r < 0) return r;