diff options
author | Benoit Goby <benoit@android.com> | 2012-07-31 19:22:06 -0700 |
---|---|---|
committer | Benoit Goby <benoit@android.com> | 2012-08-02 12:19:30 -0700 |
commit | 6cc883ca098f34bd126478a6aa19d5cce48d71a9 (patch) | |
tree | 6a952d419bb7f456ce9bd1cb088aa93714fe81ad /libusbhost | |
parent | 35fc46d8e338181ee3caedc30f3627bad2ffe35e (diff) | |
download | system_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.zip system_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.tar.gz system_core-6cc883ca098f34bd126478a6aa19d5cce48d71a9.tar.bz2 |
libusbhost: Fix possible missed "device added" notification
When a new bus is added, check for existing devices in the bus
directory, since devices may have been added before calling
inotify_add_watch.
Also add missing inotify_rm_watch calls.
Change-Id: Ie69fc995a3e8b18431099b252be86f0054fe5531
Diffstat (limited to 'libusbhost')
-rw-r--r-- | libusbhost/usbhost.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c index 5d261cd..6be99dc 100644 --- a/libusbhost/usbhost.c +++ b/libusbhost/usbhost.c @@ -77,13 +77,35 @@ static inline int badname(const char *name) return 0; } +static int find_existing_devices_bus(char *busname, + usb_device_added_cb added_cb, + void *client_data) +{ + char devname[32]; + DIR *devdir; + struct dirent *de; + int done = 0; + + devdir = opendir(busname); + if(devdir == 0) return 0; + + while ((de = readdir(devdir)) && !done) { + if(badname(de->d_name)) continue; + + snprintf(devname, sizeof(devname), "%s/%s", busname, de->d_name); + done = added_cb(devname, client_data); + } // end of devdir while + closedir(devdir); + + return done; +} + /* returns true if one of the callbacks indicates we are done */ static int find_existing_devices(usb_device_added_cb added_cb, - usb_device_removed_cb removed_cb, void *client_data) { - char busname[32], devname[32]; - DIR *busdir , *devdir ; + char busname[32]; + DIR *busdir; struct dirent *de; int done = 0; @@ -93,18 +115,10 @@ static int find_existing_devices(usb_device_added_cb added_cb, while ((de = readdir(busdir)) != 0 && !done) { if(badname(de->d_name)) continue; - snprintf(busname, sizeof busname, "%s/%s", USB_FS_DIR, de->d_name); - devdir = opendir(busname); - if(devdir == 0) continue; - - while ((de = readdir(devdir)) && !done) { - if(badname(de->d_name)) continue; - - snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name); - done = added_cb(devname, client_data); - } // end of devdir while - closedir(devdir); - } //end of busdir while + snprintf(busname, sizeof(busname), "%s/%s", USB_FS_DIR, de->d_name); + done = find_existing_devices_bus(busname, added_cb, + client_data); + } closedir(busdir); return done; @@ -167,7 +181,7 @@ void usb_host_run(struct usb_host_context *context, } /* check for existing devices first, after we have inotify set up */ - done = find_existing_devices(added_cb, removed_cb, client_data); + done = find_existing_devices(added_cb, client_data); if (discovery_done_cb) done |= discovery_done_cb(client_data); @@ -179,11 +193,20 @@ void usb_host_run(struct usb_host_context *context, if (wd == wds[0]) { i = atoi(event->name); snprintf(path, sizeof(path), "%s/%s", USB_FS_DIR, event->name); - D("new subdirectory %s: index: %d\n", path, i); + D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ? + "new" : "gone", path, i); if (i > 0 && i < wd_count) { - ret = inotify_add_watch(context->fd, path, IN_CREATE | IN_DELETE); - if (ret > 0) - wds[i] = ret; + if (event->mask & IN_CREATE) { + ret = inotify_add_watch(context->fd, path, + IN_CREATE | IN_DELETE); + if (ret > 0) + wds[i] = ret; + done = find_existing_devices_bus(path, added_cb, + client_data); + } else if (event->mask & IN_DELETE) { + inotify_rm_watch(context->fd, wds[i]); + wds[i] = -1; + } } } else { for (i = 1; i < wd_count && !done; i++) { |