1
0
mirror of git://sigrok.org/libserialport synced 2023-08-10 21:13:24 +03:00

Make sp_list_ports and sp_get_port_by_name return int.

This commit is contained in:
Martin Ling 2013-11-03 22:15:54 +00:00 committed by Uwe Hermann
parent d4babed247
commit 77f262c4f9
2 changed files with 76 additions and 27 deletions

View File

@ -45,28 +45,32 @@
#include "serialport.h" #include "serialport.h"
struct sp_port *sp_get_port_by_name(const char *portname) int sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
{ {
struct sp_port *port; struct sp_port *port;
int len; int len;
*port_ptr = NULL;
if (!portname) if (!portname)
return NULL; return SP_ERR_ARG;
if (!(port = malloc(sizeof(struct sp_port)))) if (!(port = malloc(sizeof(struct sp_port))))
return NULL; return SP_ERR_MEM;
len = strlen(portname) + 1; len = strlen(portname) + 1;
if (!(port->name = malloc(len))) if (!(port->name = malloc(len)))
{ {
free(port); free(port);
return NULL; return SP_ERR_MEM;
} }
memcpy(port->name, portname, len); memcpy(port->name, portname, len);
return port; *port_ptr = port;
return SP_OK;
} }
static struct sp_port **sp_list_append(struct sp_port **list, const char *portname) static struct sp_port **sp_list_append(struct sp_port **list, const char *portname)
@ -77,7 +81,7 @@ static struct sp_port **sp_list_append(struct sp_port **list, const char *portna
if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2)))) if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
goto fail; goto fail;
list = tmp; list = tmp;
if (!(list[count] = sp_get_port_by_name(portname))) if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
goto fail; goto fail;
list[count + 1] = NULL; list[count + 1] = NULL;
return list; return list;
@ -91,12 +95,13 @@ fail:
* *
* @return A null-terminated array of port name strings. * @return A null-terminated array of port name strings.
*/ */
struct sp_port **sp_list_ports(void) int sp_list_ports(struct sp_port ***list_ptr)
{ {
struct sp_port **list; struct sp_port **list;
int ret = SP_OK;
if (!(list = malloc(sizeof(struct sp_port **)))) if (!(list = malloc(sizeof(struct sp_port **))))
return NULL; return SP_ERR_MEM;;
list[0] = NULL; list[0] = NULL;
@ -111,15 +116,27 @@ struct sp_port **sp_list_ports(void)
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS)
return NULL; {
ret = SP_ERR_FAIL;
goto out_done;
}
if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS)
{
ret = SP_ERR_FAIL;
goto out_close; goto out_close;
}
max_data_len = max_data_size / sizeof(TCHAR); max_data_len = max_data_size / sizeof(TCHAR);
if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR))))
{
ret = SP_ERR_MEM;
goto out_close; goto out_close;
}
if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR))))
{
ret = SP_ERR_MEM;
goto out_free_value; goto out_free_value;
}
while ( while (
value_len = max_value_len, value_len = max_value_len,
data_size = max_data_size, data_size = max_data_size,
@ -134,15 +151,20 @@ struct sp_port **sp_list_ports(void)
name_len = data_len + 1; name_len = data_len + 1;
#endif #endif
if (!(name = malloc(name_len))) if (!(name = malloc(name_len)))
{
ret = SP_ERR_MEM;
goto out; goto out;
}
#ifdef UNICODE #ifdef UNICODE
WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
#else #else
strcpy(name, data); strcpy(name, data);
#endif #endif
if (type == REG_SZ) if (type == REG_SZ && !(list = sp_list_append(list, name)))
if (!(list = sp_list_append(list, name))) {
goto out; ret = SP_ERR_MEM;
goto out;
}
index++; index++;
} }
out: out:
@ -151,7 +173,7 @@ out_free_value:
free(value); free(value);
out_close: out_close:
RegCloseKey(key); RegCloseKey(key);
return list; out_done:
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
mach_port_t master; mach_port_t master;
@ -163,19 +185,31 @@ out_close:
Boolean result; Boolean result;
if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS) if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS)
return NULL; {
ret = SP_ERR_FAIL;
goto out_done;
}
if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue)))
return NULL; {
ret = SP_ERR_FAIL;
goto out_done;
}
CFDictionarySetValue(classes, CFDictionarySetValue(classes,
CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes)); CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
if (!(IOServiceGetMatchingServices(master, classes, &iter))) if (!(IOServiceGetMatchingServices(master, classes, &iter)))
return NULL; {
ret = SP_ERR_FAIL;
goto out_done;
}
if (!(path = malloc(PATH_MAX))) if (!(path = malloc(PATH_MAX)))
{
ret = SP_ERR_MEM;
goto out_release; goto out_release;
}
while ((port = IOIteratorNext(iter))) { while ((port = IOIteratorNext(iter))) {
cf_path = IORegistryEntryCreateCFProperty(port, cf_path = IORegistryEntryCreateCFProperty(port,
@ -184,21 +218,20 @@ out_close:
result = CFStringGetCString(cf_path, result = CFStringGetCString(cf_path,
path, PATH_MAX, kCFStringEncodingASCII); path, PATH_MAX, kCFStringEncodingASCII);
CFRelease(cf_path); CFRelease(cf_path);
if (result) if (result && !(list = sp_list_append(list, path)))
if (!(list = sp_list_append(list, path))) {
{ ret = SP_ERR_MEM;
IOObjectRelease(port); IOObjectRelease(port);
goto out; goto out;
} }
} }
IOObjectRelease(port); IOObjectRelease(port);
} }
out: out:
free(path); free(path);
out_release: out_release:
IOObjectRelease(iter); IOObjectRelease(iter);
return list; out_done:
#endif #endif
#ifdef __linux__ #ifdef __linux__
struct udev *ud; struct udev *ud;
@ -248,13 +281,29 @@ out_release:
skip: skip:
udev_device_unref(ud_dev); udev_device_unref(ud_dev);
if (!list) if (!list)
{
ret = SP_ERR_MEM;
goto out; goto out;
}
} }
out: out:
udev_enumerate_unref(ud_enumerate); udev_enumerate_unref(ud_enumerate);
udev_unref(ud); udev_unref(ud);
return list;
#endif #endif
if (ret == SP_OK)
{
*list_ptr = list;
}
else
{
if (list)
sp_free_port_list(list);
*list_ptr = NULL;
}
return ret;
} }
/** /**

View File

@ -79,8 +79,8 @@ enum {
SP_FLOW_SOFTWARE = 2 SP_FLOW_SOFTWARE = 2
}; };
struct sp_port *sp_get_port_by_name(const char *portname); int sp_get_port_by_name(const char *portname, struct sp_port **port_ptr);
struct sp_port **sp_list_ports(void); int sp_list_ports(struct sp_port ***list_ptr);
void sp_free_port_list(struct sp_port **ports); void sp_free_port_list(struct sp_port **ports);
int sp_open(struct sp_port *port, int flags); int sp_open(struct sp_port *port, int flags);
int sp_close(struct sp_port *port); int sp_close(struct sp_port *port);