led: Fix and cleanup initialization
The structure returned by readdir is may be statically allocated. Keeping a pointer to it is broken. The LED path is generally not a directory, it's a link to a directory. And even if it were a directory, that would tell nothing about the caller's access permissions. And then there is a lot of duplication between mraa_led_init and mraa_led_init_raw. This addresses that all. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
@@ -273,8 +273,7 @@ struct _iio {
|
|||||||
struct _led {
|
struct _led {
|
||||||
/*@{*/
|
/*@{*/
|
||||||
int count; /**< total LED count in a platform */
|
int count; /**< total LED count in a platform */
|
||||||
char *led_name; /**< LED name */
|
const char *led_path; /**< sysfs path of the LED */
|
||||||
char led_path[64]; /**< sysfs path of the LED */
|
|
||||||
int trig_fd; /**< trigger file descriptor */
|
int trig_fd; /**< trigger file descriptor */
|
||||||
int bright_fd; /**< brightness file descriptor */
|
int bright_fd; /**< brightness file descriptor */
|
||||||
int max_bright_fd; /**< maximum brightness file descriptor */
|
int max_bright_fd; /**< maximum brightness file descriptor */
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ mraa_led_get_maxbrightfd(mraa_led_context dev)
|
|||||||
static mraa_led_context
|
static mraa_led_context
|
||||||
mraa_led_init_internal(const char* led)
|
mraa_led_init_internal(const char* led)
|
||||||
{
|
{
|
||||||
|
char brightness_path[MAX_SIZE];
|
||||||
|
const char *led_name = NULL;
|
||||||
|
char *led_path;
|
||||||
|
size_t led_path_len;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
@@ -79,7 +83,6 @@ mraa_led_init_internal(const char* led)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->led_name = NULL;
|
|
||||||
dev->trig_fd = -1;
|
dev->trig_fd = -1;
|
||||||
dev->bright_fd = -1;
|
dev->bright_fd = -1;
|
||||||
dev->max_bright_fd = -1;
|
dev->max_bright_fd = -1;
|
||||||
@@ -88,13 +91,14 @@ mraa_led_init_internal(const char* led)
|
|||||||
/* get the led name from sysfs path */
|
/* get the led name from sysfs path */
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
if (strstr((const char*) entry->d_name, led)) {
|
if (strstr((const char*) entry->d_name, led)) {
|
||||||
dev->led_name = (char*) entry->d_name;
|
led_name = entry->d_name;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dev->count = cnt;
|
dev->count = cnt;
|
||||||
if (dev->led_name == NULL) {
|
if (led_name == NULL) {
|
||||||
syslog(LOG_CRIT, "led: init: unknown device specified");
|
syslog(LOG_CRIT, "led: init: unknown device specified");
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
@@ -103,19 +107,28 @@ mraa_led_init_internal(const char* led)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir != NULL) {
|
led_path_len = strlen(SYSFS_CLASS_LED) + strlen(led_name) + 3;
|
||||||
|
led_path = calloc(led_path_len, sizeof(char));
|
||||||
|
if (led_path == NULL) {
|
||||||
|
syslog(LOG_CRIT, "led: init: Failed to allocate memory for LED path");
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
snprintf(led_path, led_path_len, "%s/%s", SYSFS_CLASS_LED, led_name);
|
||||||
|
dev->led_path = led_path;
|
||||||
|
|
||||||
|
snprintf(brightness_path, sizeof(brightness_path), "%s/%s", led_path, "brightness");
|
||||||
|
if (access(brightness_path, R_OK | W_OK) != 0) {
|
||||||
|
syslog(LOG_NOTICE, "led: init: current user doesn't have access rights for using LED %s", led_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
mraa_led_context
|
mraa_led_context
|
||||||
mraa_led_init(int index)
|
mraa_led_init(int index)
|
||||||
{
|
{
|
||||||
mraa_led_context dev = NULL;
|
|
||||||
char directory[MAX_SIZE];
|
|
||||||
struct stat dir;
|
|
||||||
|
|
||||||
if (plat == NULL) {
|
if (plat == NULL) {
|
||||||
syslog(LOG_ERR, "led: init: platform not initialised");
|
syslog(LOG_ERR, "led: init: platform not initialised");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -136,27 +149,12 @@ mraa_led_init(int index)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = mraa_led_init_internal((char*) plat->led_dev[index].name);
|
return mraa_led_init_internal((char*) plat->led_dev[index].name);
|
||||||
if (dev == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(directory, MAX_SIZE, "%s/%s", SYSFS_CLASS_LED, dev->led_name);
|
|
||||||
if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) {
|
|
||||||
syslog(LOG_NOTICE, "led: init: current user doesn't have access rights for using LED %s", dev->led_name);
|
|
||||||
}
|
|
||||||
strncpy(dev->led_path, (const char*) directory, sizeof(directory));
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mraa_led_context
|
mraa_led_context
|
||||||
mraa_led_init_raw(const char* led)
|
mraa_led_init_raw(const char* led)
|
||||||
{
|
{
|
||||||
mraa_led_context dev = NULL;
|
|
||||||
char directory[MAX_SIZE];
|
|
||||||
struct stat dir;
|
|
||||||
|
|
||||||
if (plat == NULL) {
|
if (plat == NULL) {
|
||||||
syslog(LOG_ERR, "led: init: platform not initialised");
|
syslog(LOG_ERR, "led: init: platform not initialised");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -167,18 +165,7 @@ mraa_led_init_raw(const char* led)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = mraa_led_init_internal(led);
|
return mraa_led_init_internal(led);
|
||||||
if (dev == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(directory, MAX_SIZE, "%s/%s", SYSFS_CLASS_LED, dev->led_name);
|
|
||||||
if (stat(directory, &dir) == 0 && S_ISDIR(dir.st_mode)) {
|
|
||||||
syslog(LOG_NOTICE, "led: init: current user don't have access rights for using LED %s", dev->led_name);
|
|
||||||
}
|
|
||||||
strncpy(dev->led_path, (const char*) directory, sizeof(directory));
|
|
||||||
|
|
||||||
return dev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mraa_result_t
|
mraa_result_t
|
||||||
@@ -402,6 +389,7 @@ mraa_led_close(mraa_led_context dev)
|
|||||||
close(dev->max_bright_fd);
|
close(dev->max_bright_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free((void *)dev->led_path);
|
||||||
free(dev);
|
free(dev);
|
||||||
|
|
||||||
return MRAA_SUCCESS;
|
return MRAA_SUCCESS;
|
||||||
|
|||||||
Reference in New Issue
Block a user