summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2014-01-09 11:31:49 +0100
committerGravatar Nikias Bassen2014-01-09 11:31:49 +0100
commit678149cde792d30beca94ba6fc9ea20996f2febc (patch)
treed4427b08b3a900bb0e2e82921f98dae44f1f3017 /src
parentd04ce1b524f68dda6b75cfff69f70f4b4ad8e1d5 (diff)
downloadusbmuxd-678149cde792d30beca94ba6fc9ea20996f2febc.tar.gz
usbmuxd-678149cde792d30beca94ba6fc9ea20996f2febc.tar.bz2
device/client: make device_get_list() allocate the result buffer itself
Using device_get_count() and device_get_list() separately can return different device counts in case there are devices added to the list inbetween these two function calls. To prevent this, device_get_list() will allocate the buffer by itself.
Diffstat (limited to 'src')
-rw-r--r--src/client.c42
-rw-r--r--src/device.c7
-rw-r--r--src/device.h2
3 files changed, 26 insertions, 25 deletions
diff --git a/src/client.c b/src/client.c
index d4719c3..5a70edb 100644
--- a/src/client.c
+++ b/src/client.c
@@ -267,23 +267,21 @@ static int send_device_list(struct mux_client *client, uint32_t tag)
plist_t dict = plist_new_dict();
plist_t devices = plist_new_array();
- int count = device_get_count(0);
- if (count > 0) {
- struct device_info *devs;
- struct device_info *dev;
- int i;
-
- devs = malloc(sizeof(struct device_info) * count);
- count = device_get_list(0, devs);
- dev = devs;
- for (i = 0; i < count; i++) {
- plist_t device = create_device_attached_plist(dev++);
- if (device) {
- plist_array_append_item(devices, device);
- }
+ struct device_info *devs = NULL;
+ struct device_info *dev;
+ int i;
+
+ int count = device_get_list(0, &devs);
+ dev = devs;
+ for (i = 0; devs && i < count; i++) {
+ plist_t device = create_device_attached_plist(dev++);
+ if (device) {
+ plist_array_append_item(devices, device);
}
- free(devs);
}
+ if (devs)
+ free(devs);
+
plist_dict_insert_item(dict, "DeviceList", devices);
res = send_plist_pkt(client, tag, dict);
plist_free(dict);
@@ -369,25 +367,23 @@ static int notify_device_remove(struct mux_client *client, uint32_t device_id)
static int start_listen(struct mux_client *client)
{
- struct device_info *devs;
+ struct device_info *devs = NULL;
struct device_info *dev;
int count, i;
client->state = CLIENT_LISTEN;
- count = device_get_count(0);
- if(!count)
- return 0;
- devs = malloc(sizeof(struct device_info) * count);
- count = device_get_list(0, devs);
+ count = device_get_list(0, &devs);
dev = devs;
- for(i=0; i<count; i++) {
+ for(i=0; devs && i < count; i++) {
if(notify_device_add(client, dev++) < 0) {
free(devs);
return -1;
}
}
- free(devs);
+ if (devs)
+ free(devs);
+
return count;
}
diff --git a/src/device.c b/src/device.c
index 29be9d1..0844499 100644
--- a/src/device.c
+++ b/src/device.c
@@ -746,10 +746,15 @@ int device_get_count(int include_hidden)
return count;
}
-int device_get_list(int include_hidden, struct device_info *p)
+int device_get_list(int include_hidden, struct device_info **devices)
{
int count = 0;
pthread_mutex_lock(&device_list_mutex);
+
+ int total_count = collection_count(&device_list);
+ *devices = malloc(sizeof(struct device_info) * total_count);
+ struct device_info *p = *devices;
+
FOREACH(struct mux_device *dev, &device_list) {
if((dev->state == MUXDEV_ACTIVE) && (include_hidden || dev->visible)) {
p->id = dev->id;
diff --git a/src/device.h b/src/device.h
index 95d470e..cb5bc24 100644
--- a/src/device.h
+++ b/src/device.h
@@ -44,7 +44,7 @@ void device_set_visible(int device_id);
void device_set_preflight_cb_data(int device_id, void* data);
int device_get_count(int include_hidden);
-int device_get_list(int include_hidden, struct device_info *p);
+int device_get_list(int include_hidden, struct device_info **devices);
int device_get_timeout(void);
void device_check_timeouts(void);