summaryrefslogtreecommitdiff
path: root/udev/lib/libudev-monitor.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2009-03-29 04:24:39 +0200
committerKay Sievers <kay.sievers@vrfy.org>2009-03-29 04:24:39 +0200
commit116254097ad3c07d9f7ed06042dbec7ba4f0f4fd (patch)
treee2d79a92d01937d3d292badc93ffdb4130d51d7c /udev/lib/libudev-monitor.c
parent241e5a21f9ad7bc986e1bb74093adf9fdb98b170 (diff)
send monitor events back to netlink socket
Instead of of our own private monitor socket, we send the processed event back to our netlink socket, to the multicast group 2 -- so any number of users can listen to udev events, just like they can listen to kernel emitted events on group 1.
Diffstat (limited to 'udev/lib/libudev-monitor.c')
-rw-r--r--udev/lib/libudev-monitor.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/udev/lib/libudev-monitor.c b/udev/lib/libudev-monitor.c
index c0aa99c65a..b2f76c3129 100644
--- a/udev/lib/libudev-monitor.c
+++ b/udev/lib/libudev-monitor.c
@@ -29,6 +29,7 @@ struct udev_monitor {
int refcount;
int sock;
struct sockaddr_nl snl;
+ struct sockaddr_nl snl_peer;
struct sockaddr_un sun;
socklen_t addrlen;
};
@@ -90,7 +91,7 @@ struct udev_monitor *udev_monitor_new_from_socket(struct udev *udev, const char
return udev_monitor;
}
-struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev)
+struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, unsigned int group)
{
struct udev_monitor *udev_monitor;
@@ -110,10 +111,11 @@ struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev)
}
udev_monitor->snl.nl_family = AF_NETLINK;
- udev_monitor->snl.nl_pid = getpid();
- udev_monitor->snl.nl_groups = 1;
+ udev_monitor->snl.nl_groups = group;
+ udev_monitor->snl_peer.nl_family = AF_NETLINK;
+ udev_monitor->snl_peer.nl_groups = UDEV_MONITOR_UDEV;
- dbg(udev, "monitor %p created with NETLINK_KOBJECT_UEVENT\n", udev_monitor);
+ dbg(udev, "monitor %p created with NETLINK_KOBJECT_UEVENT (%u)\n", udev_monitor, group);
return udev_monitor;
}
@@ -123,14 +125,16 @@ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
const int on = 1;
if (udev_monitor->snl.nl_family != 0) {
- err = bind(udev_monitor->sock, (struct sockaddr *)&udev_monitor->snl, sizeof(struct sockaddr_nl));
+ err = bind(udev_monitor->sock,
+ (struct sockaddr *)&udev_monitor->snl, sizeof(struct sockaddr_nl));
if (err < 0) {
err(udev_monitor->udev, "bind failed: %m\n");
return err;
}
dbg(udev_monitor->udev, "monitor %p listening on netlink\n", udev_monitor);
} else if (udev_monitor->sun.sun_family != 0) {
- err = bind(udev_monitor->sock, (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
+ err = bind(udev_monitor->sock,
+ (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
if (err < 0) {
err(udev_monitor->udev, "bind failed: %m\n");
return err;
@@ -381,9 +385,18 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor, struct udev_devi
len = udev_device_get_properties_monitor_buf(udev_device, &buf);
if (len < 32)
return -1;
- count = sendto(udev_monitor->sock,
- buf, len, 0,
- (struct sockaddr *)&udev_monitor->sun, udev_monitor->addrlen);
+ if (udev_monitor->sun.sun_family != 0) {
+ count = sendto(udev_monitor->sock,
+ buf, len, 0,
+ (struct sockaddr *)&udev_monitor->sun,
+ udev_monitor->addrlen);
+ } else {
+ /* no destination besides the muticast group, we will always get -1 ECONNREFUSED */
+ count = sendto(udev_monitor->sock,
+ buf, len, 0,
+ (struct sockaddr *)&udev_monitor->snl_peer,
+ sizeof(struct sockaddr_nl));
+ }
info(udev_monitor->udev, "passed %zi bytes to monitor %p, \n", count, udev_monitor);
return count;
}