aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Hampson <ahampson@google.com>2013-02-01 09:24:46 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-02-04 23:32:27 +0000
commit60ccd6b0b264605d84fd85c343ae465e7fa4deb0 (patch)
treed94f2f799624393f591f347f6a89eed5c4466919
parenta361c7f29c5b6ec9aa2b2e3e552b335a13c42cae (diff)
downloadlibusb_aah-60ccd6b0b264605d84fd85c343ae465e7fa4deb0.tar.gz
temp: Reuse file descriptor if availabletools_r22jb-mr1.1-dev-plus-aosp
This will need to be reviewed at a later date and removed or modified if possible. Modify the open behavior to reuse an existing file descriptor if available. This allows libusb to reuse the file descriptor used by the Android USB host. Also change the search order proc/bus/usb before /dev/bus/usb. Change-Id: I1d9f29fb7eebe783bbcfac5def59dd59928d975f Signed-off-by: Hendrik Dahlkamp <hendrik@google.com> Signed-off-by: Adam Hampson <ahampson@google.com>
-rw-r--r--libusb/os/linux_usbfs.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 02d182d..2bdd510 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -212,13 +212,13 @@ static int check_usb_vfs(const char *dirname)
static const char *find_usbfs_path(void)
{
- const char *path = "/dev/bus/usb";
+ const char *path = "/proc/bus/usb";
const char *ret = NULL;
if (check_usb_vfs(path)) {
ret = path;
} else {
- path = "/proc/bus/usb";
+ path = "/dev/bus/usb";
if (check_usb_vfs(path))
ret = path;
}
@@ -1211,6 +1211,38 @@ static int op_get_device_list(struct libusb_context *ctx,
return usbfs_get_device_list(ctx, _discdevs);
}
+/* Returns the file descriptor of 'file_name', if it has been opened by the process, or -1 otherwise. */
+static int find_fd_by_name(char *file_name)
+{
+ struct dirent *fd_dirent;
+ DIR *proc_fd = opendir("/proc/self/fd");
+ int ret = -1;
+
+ while (fd_dirent = readdir(proc_fd))
+ {
+ char link_file_name[1024];
+ char fd_file_name[1024];
+
+ if (fd_dirent->d_type != DT_LNK)
+ {
+ continue;
+ }
+
+ snprintf(link_file_name, 1024, "/proc/self/fd/%s", fd_dirent->d_name);
+
+ memset(fd_file_name, 0, sizeof(fd_file_name));
+ readlink(link_file_name, fd_file_name, sizeof(fd_file_name) - 1);
+
+ if (!strcmp(fd_file_name, file_name))
+ {
+ ret = atoi(fd_dirent->d_name);
+ }
+ }
+
+ closedir(proc_fd);
+
+ return ret;
+}
static int op_open(struct libusb_device_handle *handle)
{
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
@@ -1218,7 +1250,15 @@ static int op_open(struct libusb_device_handle *handle)
_get_usbfs_path(handle->dev, filename);
usbi_dbg("opening %s", filename);
- hpriv->fd = open(filename, O_RDWR);
+
+ hpriv->fd = find_fd_by_name(filename);
+
+ /* Fallback to normal behavior */
+ if (hpriv->fd == -1)
+ {
+ hpriv->fd = open(filename, O_RDWR);
+ }
+
if (hpriv->fd < 0) {
if (errno == EACCES) {
usbi_err(HANDLE_CTX(handle), "libusb couldn't open USB device %s: "