summaryrefslogtreecommitdiffstats
path: root/libusbhost
diff options
context:
space:
mode:
authorZiv Hendel <ziv@primesense.com>2013-03-24 18:10:52 +0200
committerAdam Hampson <ahampson@google.com>2013-03-25 14:12:18 -0700
commitf75ea8d082ff39e316bd4d73979b610cc4b5e4bc (patch)
tree4bb2e90c8749dcdf04bbff66020ab5fc11cf1170 /libusbhost
parentfb39c0d19860fe48bc598d5d180a8cce9f59e33b (diff)
downloadsystem_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.zip
system_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.tar.gz
system_core-f75ea8d082ff39e316bd4d73979b610cc4b5e4bc.tar.bz2
Properly handle cases of multiple inotify events
Bug: 8469799 Change-Id: Ie10242dd05becd142cc84651d5e5795e4c02270d Signed-off-by: Igor Murashkin <iam@google.com> Signed-off-by: Adam Hampson <ahampson@google.com>
Diffstat (limited to 'libusbhost')
-rw-r--r--libusbhost/usbhost.c83
1 files changed, 44 insertions, 39 deletions
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 167fa60..b967342 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -223,56 +223,61 @@ int usb_host_read_event(struct usb_host_context *context)
char event_buf[512];
char path[100];
int i, ret, done = 0;
- int j, event_size;
+ int offset = 0;
int wd;
ret = read(context->fd, event_buf, sizeof(event_buf));
if (ret >= (int)sizeof(struct inotify_event)) {
- event = (struct inotify_event *)event_buf;
- wd = event->wd;
- if (wd == context->wdd) {
- if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
- watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
- done = find_existing_devices(context->cb_added, context->data);
- } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
- for (i = 0; i < MAX_USBFS_WD_COUNT; i++) {
- if (context->wds[i] >= 0) {
+ while (offset < ret) {
+ event = (struct inotify_event*)&event_buf[offset];
+ done = 0;
+ wd = event->wd;
+ if (wd == context->wdd) {
+ if ((event->mask & IN_CREATE) && !strcmp(event->name, "bus")) {
+ watch_existing_subdirs(context, context->wds, MAX_USBFS_WD_COUNT);
+ done = find_existing_devices(context->cb_added, context->data);
+ } else if ((event->mask & IN_DELETE) && !strcmp(event->name, "bus")) {
+ for (i = 0; i < MAX_USBFS_WD_COUNT; i++) {
+ if (context->wds[i] >= 0) {
+ inotify_rm_watch(context->fd, context->wds[i]);
+ context->wds[i] = -1;
+ }
+ }
+ }
+ } else if (wd == context->wds[0]) {
+ i = atoi(event->name);
+ snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name);
+ D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
+ "new" : "gone", path, i);
+ if (i > 0 && i < MAX_USBFS_WD_COUNT) {
+ if (event->mask & IN_CREATE) {
+ ret = inotify_add_watch(context->fd, path,
+ IN_CREATE | IN_DELETE);
+ if (ret >= 0)
+ context->wds[i] = ret;
+ done = find_existing_devices_bus(path, context->cb_added,
+ context->data);
+ } else if (event->mask & IN_DELETE) {
inotify_rm_watch(context->fd, context->wds[i]);
context->wds[i] = -1;
}
}
- }
- } else if (wd == context->wds[0]) {
- i = atoi(event->name);
- snprintf(path, sizeof(path), USB_FS_DIR "/%s", event->name);
- D("%s subdirectory %s: index: %d\n", (event->mask & IN_CREATE) ?
- "new" : "gone", path, i);
- if (i > 0 && i < MAX_USBFS_WD_COUNT) {
- if (event->mask & IN_CREATE) {
- ret = inotify_add_watch(context->fd, path,
- IN_CREATE | IN_DELETE);
- if (ret >= 0)
- context->wds[i] = ret;
- done = find_existing_devices_bus(path, context->cb_added,
- context->data);
- } else if (event->mask & IN_DELETE) {
- inotify_rm_watch(context->fd, context->wds[i]);
- context->wds[i] = -1;
- }
- }
- } else {
- for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) {
- if (wd == context->wds[i]) {
- snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name);
- if (event->mask == IN_CREATE) {
- D("new device %s\n", path);
- done = context->cb_added(path, context->data);
- } else if (event->mask == IN_DELETE) {
- D("gone device %s\n", path);
- done = context->cb_removed(path, context->data);
+ } else {
+ for (i = 1; (i < MAX_USBFS_WD_COUNT) && !done; i++) {
+ if (wd == context->wds[i]) {
+ snprintf(path, sizeof(path), USB_FS_DIR "/%03d/%s", i, event->name);
+ if (event->mask == IN_CREATE) {
+ D("new device %s\n", path);
+ done = context->cb_added(path, context->data);
+ } else if (event->mask == IN_DELETE) {
+ D("gone device %s\n", path);
+ done = context->cb_removed(path, context->data);
+ }
}
}
}
+
+ offset += sizeof(struct inotify_event) + event->len;
}
}