Hello, libusb_init() requires libusb_exit() to free all memory. I placed this call in ftdi_free(). libusb_get_device_list() also requires a libusb_free_device_list(). This free must happen after an libusb_open() and in all the error pathes, so I added a define for the error case and the return of the libusb_open() call must be remembered.
Bye -- Uwe Bonnes [email protected] Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt --------- Tel. 06151 162516 -------- Fax. 06151 164321 ---------- >From 01c5ddd2ebf902257e815154ce5bd464899d8969 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes <[email protected]> Date: Mon, 7 Jun 2010 19:00:42 +0200 Subject: Call libusb_exit() and libusb_free_device_list() to avoid leaks --- src/ftdi.c | 36 +++++++++++++++++++++++++----------- 1 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/ftdi.c b/src/ftdi.c index 7b4b987..1e34f47 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. @@ -195,6 +201,7 @@ void ftdi_deinit(struct ftdi_context *ftdi) void ftdi_free(struct ftdi_context *ftdi) { ftdi_deinit(ftdi); + libusb_exit(NULL); free(ftdi); } @@ -250,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; @@ -265,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; } @@ -621,6 +628,7 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, libusb_device **devs; char string[256]; int i = 0; + int res; if (libusb_init(NULL) < 0) ftdi_error_return(-11, "libusb_init() failed"); @@ -636,19 +644,19 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, struct libusb_device_descriptor desc; 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) { @@ -661,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) { @@ -678,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); } /** @@ -742,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 [email protected]
