diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-05-27 05:22:30 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-08-02 04:22:24 +0200 |
commit | bab889c51e888c1b288fed253c349e979a6cf31a (patch) | |
tree | cb42248899fee5da690ba5280d61d913bd42ebfa | |
parent | sd-device-monitor: make device_monitor_receive_device() always initialize ret... (diff) | |
download | systemd-bab889c51e888c1b288fed253c349e979a6cf31a.tar.xz systemd-bab889c51e888c1b288fed253c349e979a6cf31a.zip |
sd-device-monitor: expose low-level functions
To make it work without sd-event.
Prompted by recent chat:
> Hey all!
> reading man libudev, it says to use sd-device instead now. I've read that
> APIs header file and it seems it no longer has an equivalent to libudev's
> udev_monitor_get_fd, which AFAICT means I have to use sd-event to watch
> for events I'm interested in. I know I can "embed" sd-event in other event
> loops I might already have, but that seems overkill when I'm only interested
> in this one type of event and don't need sd-event for anything else.
-rw-r--r-- | src/libsystemd/libsystemd.sym | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-monitor-private.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-device/device-monitor.c | 12 | ||||
-rw-r--r-- | src/libsystemd/sd-device/test-sd-device-monitor.c | 33 | ||||
-rw-r--r-- | src/libudev/libudev-monitor.c | 6 | ||||
-rw-r--r-- | src/systemd/sd-device.h | 2 |
6 files changed, 46 insertions, 11 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index fa3c0e9933..65b81db464 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -1045,4 +1045,6 @@ global: sd_varlink_unref; sd_varlink_wait; sd_device_monitor_is_running; + sd_device_monitor_get_fd; + sd_device_monitor_receive; } LIBSYSTEMD_256; diff --git a/src/libsystemd/sd-device/device-monitor-private.h b/src/libsystemd/sd-device/device-monitor-private.h index 6cd2fef3ca..af7dd2ec35 100644 --- a/src/libsystemd/sd-device/device-monitor-private.h +++ b/src/libsystemd/sd-device/device-monitor-private.h @@ -18,6 +18,4 @@ typedef enum MonitorNetlinkGroup { int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group, int fd); int device_monitor_get_address(sd_device_monitor *m, union sockaddr_union *ret); int device_monitor_allow_unicast_sender(sd_device_monitor *m, sd_device_monitor *sender); -int device_monitor_get_fd(sd_device_monitor *m); int device_monitor_send_device(sd_device_monitor *m, const union sockaddr_union *destination, sd_device *device); -int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret); diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c index 50d4d57773..002edd4f96 100644 --- a/src/libsystemd/sd-device/device-monitor.c +++ b/src/libsystemd/sd-device/device-monitor.c @@ -125,8 +125,8 @@ _public_ int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, siz return fd_set_rcvbuf(m->sock, size, false); } -int device_monitor_get_fd(sd_device_monitor *m) { - assert(m); +_public_ int sd_device_monitor_get_fd(sd_device_monitor *m) { + assert_return(m, -EINVAL); return m->sock; } @@ -308,7 +308,7 @@ static int device_monitor_event_handler(sd_event_source *s, int fd, uint32_t rev _unused_ _cleanup_(log_context_unrefp) LogContext *c = NULL; sd_device_monitor *m = ASSERT_PTR(userdata); - if (device_monitor_receive_device(m, &device) <= 0) + if (sd_device_monitor_receive(m, &device) <= 0) return 0; if (log_context_enabled()) @@ -537,7 +537,7 @@ static bool check_sender_uid(sd_device_monitor *m, uid_t uid) { return false; } -int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) { +_public_ int sd_device_monitor_receive(sd_device_monitor *m, sd_device **ret) { _cleanup_(sd_device_unrefp) sd_device *device = NULL; _cleanup_free_ uint8_t *buf_alloc = NULL; union { @@ -562,8 +562,8 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) { bool is_initialized = false; int r; - assert(m); - assert(ret); + assert_return(m, -EINVAL); + assert_return(ret, -EINVAL); n = next_datagram_size_fd(m->sock); if (n < 0) { diff --git a/src/libsystemd/sd-device/test-sd-device-monitor.c b/src/libsystemd/sd-device/test-sd-device-monitor.c index 651490ad1c..a64f2b4b84 100644 --- a/src/libsystemd/sd-device/test-sd-device-monitor.c +++ b/src/libsystemd/sd-device/test-sd-device-monitor.c @@ -9,6 +9,7 @@ #include "device-monitor-private.h" #include "device-private.h" #include "device-util.h" +#include "io-util.h" #include "macro.h" #include "mountpoint-util.h" #include "path-util.h" @@ -323,6 +324,38 @@ TEST(sd_device_monitor_filter_remove) { ASSERT_EQ(sd_event_loop(sd_device_monitor_get_event(monitor_client)), 100); } +TEST(sd_device_monitor_receive) { + _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; + union sockaddr_union sa; + const char *syspath; + int fd, r; + + prepare_loopback(&device); + + ASSERT_OK(sd_device_get_syspath(device, &syspath)); + + prepare_monitor(&monitor_server, &monitor_client, &sa); + + ASSERT_OK(device_monitor_send_device(monitor_server, &sa, device)); + + ASSERT_OK(fd = sd_device_monitor_get_fd(monitor_client)); + for (;;) { + r = fd_wait_for_event(fd, POLLIN, 10 * USEC_PER_SEC); + if (r == -EINTR) + continue; + ASSERT_GT(r, 0); + break; + } + + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + ASSERT_GT(sd_device_monitor_receive(monitor_client, &dev), 0); + + const char *s; + ASSERT_OK(sd_device_get_syspath(dev, &s)); + ASSERT_TRUE(streq(s, syspath)); +} + static int intro(void) { if (getuid() != 0) return log_tests_skipped("not root"); diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index b283154c40..55b6eb00f6 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -186,7 +186,7 @@ _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) { _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) { assert_return(udev_monitor, -EINVAL); - return device_monitor_get_fd(udev_monitor->monitor); + return sd_device_monitor_get_fd(udev_monitor->monitor); } static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) { @@ -197,13 +197,13 @@ static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_ for (;;) { /* r == 0 means a device is received but it does not pass the current filter. */ - r = device_monitor_receive_device(udev_monitor->monitor, ret); + r = sd_device_monitor_receive(udev_monitor->monitor, ret); if (r != 0) return r; for (;;) { /* Wait for next message */ - r = fd_wait_for_event(device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0); + r = fd_wait_for_event(sd_device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0); if (r == -EINTR) continue; if (r < 0) diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h index 40786fc1cd..c84cc55202 100644 --- a/src/systemd/sd-device.h +++ b/src/systemd/sd-device.h @@ -142,6 +142,7 @@ int sd_device_monitor_new(sd_device_monitor **ret); sd_device_monitor *sd_device_monitor_ref(sd_device_monitor *m); sd_device_monitor *sd_device_monitor_unref(sd_device_monitor *m); +int sd_device_monitor_get_fd(sd_device_monitor *m); int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, size_t size); int sd_device_monitor_attach_event(sd_device_monitor *m, sd_event *event); int sd_device_monitor_detach_event(sd_device_monitor *m); @@ -152,6 +153,7 @@ int sd_device_monitor_get_description(sd_device_monitor *m, const char **ret); int sd_device_monitor_is_running(sd_device_monitor *m); int sd_device_monitor_start(sd_device_monitor *m, sd_device_monitor_handler_t callback, void *userdata); int sd_device_monitor_stop(sd_device_monitor *m); +int sd_device_monitor_receive(sd_device_monitor *m, sd_device **ret); int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype); int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag); |