summaryrefslogtreecommitdiffstats
path: root/src/modules/module-udev-detect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/module-udev-detect.c')
-rw-r--r--src/modules/module-udev-detect.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index 1ad6fa2d..c8ec2bf9 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -65,6 +65,8 @@ static const char* const valid_modargs[] = {
NULL
};
+static int setup_inotify(struct userdata *u);
+
static void device_free(struct device *d) {
pa_assert(d);
@@ -117,6 +119,9 @@ static void card_changed(struct userdata *u, struct udev_device *dev) {
pa_assert(u);
pa_assert(dev);
+ /* Maybe /dev/snd is now available? */
+ setup_inotify(u);
+
path = udev_device_get_devpath(dev);
if ((d = pa_hashmap_get(u->devices, path))) {
@@ -262,7 +267,7 @@ static void inotify_cb(
} buf;
struct userdata *u = userdata;
static int type = 0;
- pa_bool_t verify = FALSE;
+ pa_bool_t verify = FALSE, deleted = FALSE;
for (;;) {
ssize_t r;
@@ -279,6 +284,9 @@ static void inotify_cb(
if ((buf.e.mask & IN_CLOSE_WRITE) && pa_startswith(buf.e.name, "pcmC"))
verify = TRUE;
+
+ if ((buf.e.mask & (IN_DELETE_SELF|IN_MOVE_SELF)))
+ deleted = TRUE;
}
if (verify) {
@@ -291,11 +299,14 @@ static void inotify_cb(
verify_access(u, d);
}
- return;
+ if (!deleted)
+ return;
fail:
- a->io_free(u->inotify_io);
- u->inotify_io = NULL;
+ if (u->inotify_io) {
+ a->io_free(u->inotify_io);
+ u->inotify_io = NULL;
+ }
if (u->inotify_fd >= 0) {
pa_close(u->inotify_fd);
@@ -307,17 +318,28 @@ static int setup_inotify(struct userdata *u) {
char *dev_snd;
int r;
+ if (u->inotify_fd >= 0)
+ return 0;
+
if ((u->inotify_fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
pa_log("inotify_init1() failed: %s", pa_cstrerror(errno));
return -1;
}
dev_snd = pa_sprintf_malloc("%s/snd", udev_get_dev_path(u->udev));
- r = inotify_add_watch(u->inotify_fd, dev_snd, IN_CLOSE_WRITE);
+ r = inotify_add_watch(u->inotify_fd, dev_snd, IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF);
pa_xfree(dev_snd);
if (r < 0) {
- pa_log("inotify_add_watch() failed: %s", pa_cstrerror(errno));
+ int saved_errno = errno;
+
+ pa_close(u->inotify_fd);
+ u->inotify_fd = -1;
+
+ if (saved_errno == ENOENT)
+ return 0;
+
+ pa_log("inotify_add_watch() failed: %s", pa_cstrerror(saved_errno));
return -1;
}