summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-05-27 05:22:30 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-08-02 04:22:24 +0200
commitbab889c51e888c1b288fed253c349e979a6cf31a (patch)
treecb42248899fee5da690ba5280d61d913bd42ebfa
parentsd-device-monitor: make device_monitor_receive_device() always initialize ret... (diff)
downloadsystemd-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.sym2
-rw-r--r--src/libsystemd/sd-device/device-monitor-private.h2
-rw-r--r--src/libsystemd/sd-device/device-monitor.c12
-rw-r--r--src/libsystemd/sd-device/test-sd-device-monitor.c33
-rw-r--r--src/libudev/libudev-monitor.c6
-rw-r--r--src/systemd/sd-device.h2
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);