More informative libusb_open() return code

Hopefully one of the last API tweaks...
diff --git a/TODO b/TODO
index c548443..7a6bd3e 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 for 1.0
 =======
-review functionality missing over 0.1
 serialization of handle_events
 
 for 1.1 or future
@@ -9,3 +8,4 @@
 notifications of hotplugged/unplugged devices
 offer API to create/destroy handle_events thread
 isochronous sync I/O?
+exposing of parent-child device relationships
diff --git a/libusb/core.c b/libusb/core.c
index 74ad527..45229be 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -599,38 +599,45 @@
  * This is a non-blocking function; no requests are sent over the bus.
  *
  * \param dev the device to open
- * \returns a handle for the device, or NULL on error
+ * \param output location for the returned device handle pointer. Only
+ * populated when the return code is 0.
+ * \returns 0 on success
+ * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure
+ * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions
+ * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
+ * \returns another LIBUSB_ERROR code on other failure
  */
-API_EXPORTED libusb_device_handle *libusb_open(libusb_device *dev)
+API_EXPORTED int libusb_open(libusb_device *dev, libusb_device_handle **handle)
 {
-	struct libusb_device_handle *handle;
+	struct libusb_device_handle *_handle;
 	size_t priv_size = usbi_backend->device_handle_priv_size;
 	int r;
 	usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
 
-	handle = malloc(sizeof(*handle) + priv_size);
-	if (!handle)
-		return NULL;
+	_handle = malloc(sizeof(*_handle) + priv_size);
+	if (!_handle)
+		return LIBUSB_ERROR_NO_MEM;
 
-	r = pthread_mutex_init(&handle->lock, NULL);
+	r = pthread_mutex_init(&_handle->lock, NULL);
 	if (r)
-		return NULL;
+		return LIBUSB_ERROR_OTHER;
 
-	handle->dev = libusb_ref_device(dev);
-	handle->claimed_interfaces = 0;
-	memset(&handle->os_priv, 0, priv_size);
+	_handle->dev = libusb_ref_device(dev);
+	_handle->claimed_interfaces = 0;
+	memset(&_handle->os_priv, 0, priv_size);
 
-	r = usbi_backend->open(handle);
+	r = usbi_backend->open(_handle);
 	if (r < 0) {
 		libusb_unref_device(dev);
-		free(handle);
-		return NULL;
+		free(_handle);
+		return r;
 	}
 
 	pthread_mutex_lock(&usbi_open_devs_lock);
-	list_add(&handle->list, &usbi_open_devs);
+	list_add(&_handle->list, &usbi_open_devs);
 	pthread_mutex_unlock(&usbi_open_devs_lock);
-	return handle;
+	*handle = _handle;
+	return 0;
 }
 
 /** \ingroup dev
@@ -656,13 +663,14 @@
 	struct libusb_device *dev;
 	struct libusb_device_handle *handle = NULL;
 	size_t i = 0;
+	int r;
 
 	if (libusb_get_device_list(&devs) < 0)
 		return NULL;
 
 	while ((dev = devs[i++]) != NULL) {
 		struct libusb_device_descriptor desc;
-		int r = libusb_get_device_descriptor(dev, &desc);
+		r = libusb_get_device_descriptor(dev, &desc);
 		if (r < 0)
 			goto out;
 		if (desc.idVendor == vendor_id && desc.idProduct == product_id) {
@@ -671,8 +679,11 @@
 		}
 	}
 
-	if (found)
-		handle = libusb_open(found);
+	if (found) {
+		r = libusb_open(found, &handle);
+		if (r < 0)
+			handle = NULL;
+	}
 
 out:
 	libusb_free_device_list(devs, 1);
diff --git a/libusb/libusb.h b/libusb/libusb.h
index 2cd6633..3e77beb 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -742,7 +742,7 @@
 uint8_t libusb_get_device_address(libusb_device *dev);
 int libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint);
 
-libusb_device_handle *libusb_open(libusb_device *dev);
+int libusb_open(libusb_device *dev, libusb_device_handle **handle);
 void libusb_close(libusb_device_handle *dev_handle);
 libusb_device *libusb_get_device(libusb_device_handle *dev_handle);