libudev: monitor - set nl_pid when reusing fd in udev_monitor_new_from_netlink_fd

This allows a fd to be created and configured as part of one monitor, to be passed in
to create a second monitor without having to redo any of the configuration.

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
This commit is contained in:
Tom Gundersen 2015-06-02 20:57:52 +02:00 committed by Anthony G. Basile
parent 3df635050b
commit f4e9270310

View File

@ -147,6 +147,22 @@ static bool udev_has_devtmpfs(struct udev *udev) {
return false;
}
static void monitor_set_nl_address(struct udev_monitor *udev_monitor) {
union sockaddr_union snl;
socklen_t addrlen;
int r;
assert(udev_monitor);
/* get the address the kernel has assigned us
* it is usually, but not necessarily the pid
*/
addrlen = sizeof(struct sockaddr_nl);
r = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
if (r >= 0)
udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
}
struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const char *name, int fd)
{
struct udev_monitor *udev_monitor;
@ -186,7 +202,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
if (fd < 0) {
udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
if (udev_monitor->sock == -1) {
if (udev_monitor->sock < 0) {
log_debug_errno(errno, "error getting socket: %m");
free(udev_monitor);
return NULL;
@ -194,6 +210,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
} else {
udev_monitor->bound = true;
udev_monitor->sock = fd;
monitor_set_nl_address(udev_monitor);
}
udev_monitor->snl.nl.nl_family = AF_NETLINK;
@ -369,6 +386,7 @@ int udev_monitor_allow_unicast_sender(struct udev_monitor *udev_monitor, struct
udev_monitor->snl_trusted_sender.nl.nl_pid = sender->snl.nl.nl_pid;
return 0;
}
/**
* udev_monitor_enable_receiving:
* @udev_monitor: the monitor which should receive events
@ -391,19 +409,9 @@ _public_ int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor)
udev_monitor->bound = true;
}
if (err >= 0) {
union sockaddr_union snl;
socklen_t addrlen;
/*
* get the address the kernel has assigned us
* it is usually, but not necessarily the pid
*/
addrlen = sizeof(struct sockaddr_nl);
err = getsockname(udev_monitor->sock, &snl.sa, &addrlen);
if (err == 0)
udev_monitor->snl.nl.nl_pid = snl.nl.nl_pid;
} else {
if (err >= 0)
monitor_set_nl_address(udev_monitor);
else {
log_debug_errno(errno, "bind failed: %m");
return -errno;
}