Hello,
with pain I found out that libusb_exit() must be called in ftdi_deinit(), as
ftdi_free() can't be run on a static struct ftdi_context. So find appended a
corrected patch, or more exact two patches, the first doing the
libusb_exit() and the second libusb_free_device_list() (fixing one more path
than the original).
It's hard to get things right the first time
--
Uwe Bonnes bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
>From 2b6e88b88dee09e43f2e20815be494d31a876353 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 7 Jun 2010 20:41:03 +0200
Subject: libusb_init() needs libusb_exit() to avoid leak
---
src/ftdi.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/ftdi.c b/src/ftdi.c
index 7b4b987..69e5068 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -185,6 +185,7 @@ void ftdi_deinit(struct ftdi_context *ftdi)
free(ftdi->readbuffer);
ftdi->readbuffer = NULL;
}
+ libusb_exit(NULL);
}
/**
--
1.6.4.2
>From 2863d71e145d07db58cfb67e1cdc3579344e8c44 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 7 Jun 2010 20:44:40 +0200
Subject: libbusb_get_device_list() needs libusb_free_device_list() to avoid
leaks
---
src/ftdi.c | 41 +++++++++++++++++++++++++++--------------
1 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/src/ftdi.c b/src/ftdi.c
index 69e5068..cde1c76 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -41,6 +41,12 @@
return code; \
} while(0);
+#define ftdi_error_return_free_device_list(code, str, devs) do { \
+ libusb_free_device_list(devs,1); \
+ ftdi->error_str = str; \
+ return code; \
+ } while(0);
+
/**
Internal function to close usb device pointer.
@@ -251,13 +257,13 @@ int ftdi_usb_find_all(struct ftdi_context *ftdi, struct
ftdi_device_list **devli
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc) < 0)
- ftdi_error_return(-6, "libusb_get_device_descriptor() failed");
+ ftdi_error_return_free_device_list(-6,
"libusb_get_device_descriptor() failed", devs);
if (desc.idVendor == vendor && desc.idProduct == product)
{
*curdev = (struct ftdi_device_list*)malloc(sizeof(struct
ftdi_device_list));
if (!*curdev)
- ftdi_error_return(-3, "out of memory");
+ ftdi_error_return_free_device_list(-3, "out of memory", devs);
(*curdev)->next = NULL;
(*curdev)->dev = dev;
@@ -266,7 +272,7 @@ int ftdi_usb_find_all(struct ftdi_context *ftdi, struct
ftdi_device_list **devli
count++;
}
}
-
+ libusb_free_device_list(devs,1);
return count;
}
@@ -626,30 +632,31 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi,
int vendor, int product,
if (libusb_init(NULL) < 0)
ftdi_error_return(-11, "libusb_init() failed");
- if (libusb_get_device_list(NULL, &devs) < 0)
- ftdi_error_return(-12, "libusb_get_device_list() failed");
-
if (ftdi == NULL)
ftdi_error_return(-11, "ftdi context invalid");
+ if (libusb_get_device_list(NULL, &devs) < 0)
+ ftdi_error_return(-12, "libusb_get_device_list() failed");
+
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
+ int res;
if (libusb_get_device_descriptor(dev, &desc) < 0)
- ftdi_error_return(-13, "libusb_get_device_descriptor() failed");
+ ftdi_error_return_free_device_list(-13,
"libusb_get_device_descriptor() failed", devs);
if (desc.idVendor == vendor && desc.idProduct == product)
{
if (libusb_open(dev, &ftdi->usb_dev) < 0)
- ftdi_error_return(-4, "usb_open() failed");
+ ftdi_error_return_free_device_list(-4, "usb_open() failed",
devs);
if (description != NULL)
{
if (libusb_get_string_descriptor_ascii(ftdi->usb_dev,
desc.iProduct, (unsigned char *)string, sizeof(string)) < 0)
{
libusb_close (ftdi->usb_dev);
- ftdi_error_return(-8, "unable to fetch product
description");
+ ftdi_error_return_free_device_list(-8, "unable to fetch
product description", devs);
}
if (strncmp(string, description, sizeof(string)) != 0)
{
@@ -662,7 +669,7 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int
vendor, int product,
if (libusb_get_string_descriptor_ascii(ftdi->usb_dev,
desc.iSerialNumber, (unsigned char *)string, sizeof(string)) < 0)
{
ftdi_usb_close_internal (ftdi);
- ftdi_error_return(-9, "unable to fetch serial number");
+ ftdi_error_return_free_device_list(-9, "unable to fetch
serial number", devs);
}
if (strncmp(string, serial, sizeof(string)) != 0)
{
@@ -679,12 +686,14 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi,
int vendor, int product,
continue;
}
- return ftdi_usb_open_dev(ftdi, dev);
+ res = ftdi_usb_open_dev(ftdi, dev);
+ libusb_free_device_list(devs, 1);
+ return res;
}
}
// device not found
- ftdi_error_return(-3, "device not found");
+ ftdi_error_return_free_device_list(-3, "device not found", devs);
}
/**
@@ -743,11 +752,15 @@ int ftdi_usb_open_string(struct ftdi_context *ftdi, const
char* description)
{
if (bus_number == libusb_get_bus_number (dev)
&& device_address == libusb_get_device_address (dev))
- return ftdi_usb_open_dev(ftdi, dev);
+ {
+ int res = ftdi_usb_open_dev(ftdi, dev);
+ libusb_free_device_list(devs, 1);
+ return res;
+ }
}
// device not found
- ftdi_error_return(-3, "device not found");
+ ftdi_error_return_free_device_list(-3, "device not found", devs);
}
else if (description[0] == 'i' || description[0] == 's')
{
--
1.6.4.2
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
|