mirror of
https://github.com/clearlinux/systemd-stable.git
synced 2026-10-18 22:33:54 +00:00
libudev: udev_device_get_sysattr_list_entry() update
This commit is contained in:
+28
-39
@@ -60,8 +60,8 @@ struct udev_device {
|
||||
size_t monitor_buf_len;
|
||||
struct udev_list_node devlinks_list;
|
||||
struct udev_list_node properties_list;
|
||||
struct udev_list_node sysattr_value_list;
|
||||
struct udev_list_node sysattr_list;
|
||||
struct udev_list_node available_sysattr_list;
|
||||
struct udev_list_node tags_list;
|
||||
unsigned long long int seqnum;
|
||||
unsigned long long int usec_initialized;
|
||||
@@ -84,7 +84,7 @@ struct udev_device {
|
||||
bool db_loaded;
|
||||
bool uevent_loaded;
|
||||
bool is_initialized;
|
||||
bool sysattrs_cached;
|
||||
bool sysattr_list_read;
|
||||
};
|
||||
|
||||
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
|
||||
@@ -362,8 +362,8 @@ struct udev_device *udev_device_new(struct udev *udev)
|
||||
udev_device->udev = udev;
|
||||
udev_list_init(&udev_device->devlinks_list);
|
||||
udev_list_init(&udev_device->properties_list);
|
||||
udev_list_init(&udev_device->sysattr_value_list);
|
||||
udev_list_init(&udev_device->sysattr_list);
|
||||
udev_list_init(&udev_device->available_sysattr_list);
|
||||
udev_list_init(&udev_device->tags_list);
|
||||
udev_device->event_timeout = -1;
|
||||
udev_device->watch_handle = -1;
|
||||
@@ -787,8 +787,8 @@ void udev_device_unref(struct udev_device *udev_device)
|
||||
free(udev_device->devtype);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_value_list);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->available_sysattr_list);
|
||||
udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
|
||||
free(udev_device->action);
|
||||
free(udev_device->driver);
|
||||
@@ -1166,7 +1166,7 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const
|
||||
return NULL;
|
||||
|
||||
/* look for possibly already cached result */
|
||||
udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->sysattr_list)) {
|
||||
udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->sysattr_value_list)) {
|
||||
if (strcmp(udev_list_entry_get_name(list_entry), sysattr) == 0) {
|
||||
dbg(udev_device->udev, "got '%s' (%s) from cache\n",
|
||||
sysattr, udev_list_entry_get_value(list_entry));
|
||||
@@ -1177,7 +1177,7 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const
|
||||
util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
|
||||
if (lstat(path, &statbuf) != 0) {
|
||||
dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path);
|
||||
udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, NULL, 0, 0);
|
||||
udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, NULL, 0, 0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1201,7 +1201,7 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const
|
||||
if (pos != NULL) {
|
||||
pos = &pos[1];
|
||||
dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
|
||||
list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0);
|
||||
list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, pos, 0, 0);
|
||||
val = udev_list_entry_get_value(list_entry);
|
||||
}
|
||||
|
||||
@@ -1233,22 +1233,21 @@ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const
|
||||
value[size] = '\0';
|
||||
util_remove_trailing_chars(value, '\n');
|
||||
dbg(udev_device->udev, "'%s' has attribute value '%s'\n", path, value);
|
||||
list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, value, 0, 0);
|
||||
list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, value, 0, 0);
|
||||
val = udev_list_entry_get_value(list_entry);
|
||||
out:
|
||||
return val;
|
||||
}
|
||||
|
||||
static int udev_device_cache_sysattrs(struct udev_device *udev_device)
|
||||
static int udev_device_sysattr_list_read(struct udev_device *udev_device)
|
||||
{
|
||||
struct dirent *entry;
|
||||
struct dirent *dent;
|
||||
DIR *dir;
|
||||
int num = 0;
|
||||
|
||||
if (udev_device == NULL)
|
||||
return -1;
|
||||
/* caching already done? */
|
||||
if (udev_device->sysattrs_cached)
|
||||
if (udev_device->sysattr_list_read)
|
||||
return 0;
|
||||
|
||||
dir = opendir(udev_device_get_syspath(udev_device));
|
||||
@@ -1258,37 +1257,28 @@ static int udev_device_cache_sysattrs(struct udev_device *udev_device)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (NULL != (entry = readdir(dir))) {
|
||||
for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
|
||||
char path[UTIL_PATH_SIZE];
|
||||
struct stat statbuf;
|
||||
|
||||
/* only handle symlinks and regular files */
|
||||
if (DT_LNK != entry->d_type && DT_REG != entry->d_type)
|
||||
if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device),
|
||||
"/", entry->d_name, NULL);
|
||||
if (0 != lstat(path, &statbuf))
|
||||
util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
|
||||
if (lstat(path, &statbuf) != 0)
|
||||
continue;
|
||||
if ((statbuf.st_mode & S_IRUSR) == 0)
|
||||
continue;
|
||||
|
||||
if (0 == (statbuf.st_mode & S_IRUSR))
|
||||
continue;
|
||||
|
||||
if (DT_LNK == entry->d_type) {
|
||||
if (strcmp(entry->d_name, "driver") != 0 &&
|
||||
strcmp(entry->d_name, "subsystem") != 0 &&
|
||||
strcmp(entry->d_name, "module") != 0)
|
||||
continue;
|
||||
}
|
||||
udev_list_entry_add(udev_device->udev,
|
||||
&udev_device->available_sysattr_list, entry->d_name,
|
||||
DT_LNK == entry->d_type ? "s" : "r", 0, 0);
|
||||
++num;
|
||||
udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list,
|
||||
dent->d_name, NULL, 0, 0);
|
||||
num++;
|
||||
}
|
||||
|
||||
dbg(udev_device->udev, "found %d sysattrs for '%s'\n", num,
|
||||
udev_device_get_syspath(udev_device));
|
||||
udev_device->sysattrs_cached = true;
|
||||
closedir(dir);
|
||||
dbg(udev_device->udev, "found %d sysattrs for '%s'\n", num, udev_device_get_syspath(udev_device));
|
||||
udev_device->sysattr_list_read = true;
|
||||
|
||||
return num;
|
||||
}
|
||||
@@ -1298,22 +1288,21 @@ static int udev_device_cache_sysattrs(struct udev_device *udev_device)
|
||||
* @udev_device: udev device
|
||||
*
|
||||
* Retrieve the list of available sysattrs, with value being empty;
|
||||
* This is to be able to read all available sysfs attributes for a particular
|
||||
* device without the necessity to access sysfs from outside libudev.
|
||||
* This just return all available sysfs attributes for a particular
|
||||
* device without reading their values.
|
||||
*
|
||||
* Returns: the first entry of the property list
|
||||
**/
|
||||
struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
|
||||
{
|
||||
/* perform initial caching of sysattr list */
|
||||
if (!udev_device->sysattrs_cached) {
|
||||
if (!udev_device->sysattr_list_read) {
|
||||
int ret;
|
||||
ret = udev_device_cache_sysattrs(udev_device);
|
||||
ret = udev_device_sysattr_list_read(udev_device);
|
||||
if (0 > ret)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return udev_list_get_entry(&udev_device->available_sysattr_list);
|
||||
return udev_list_get_entry(&udev_device->sysattr_list);
|
||||
}
|
||||
|
||||
int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
|
||||
|
||||
+23
-10
@@ -31,37 +31,50 @@
|
||||
|
||||
#include "udev.h"
|
||||
|
||||
static bool skip_attribute(const char *name)
|
||||
{
|
||||
char *skip[] = {
|
||||
"uevent",
|
||||
"dev",
|
||||
"modalias",
|
||||
"resource",
|
||||
"driver",
|
||||
"subsystem",
|
||||
"module",
|
||||
};
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(skip); i++)
|
||||
if (strcmp(name, skip[i]) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void print_all_attributes(struct udev_device *device, const char *key)
|
||||
{
|
||||
struct udev_list_entry *sysattr;
|
||||
|
||||
udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) {
|
||||
struct udev *udev = udev_device_get_udev(device);
|
||||
const char *name;
|
||||
const char *value;
|
||||
size_t len;
|
||||
|
||||
/* skip symlinks */
|
||||
if (0 == strcmp("s", udev_list_entry_get_value(sysattr)))
|
||||
continue;
|
||||
|
||||
name = udev_list_entry_get_name(sysattr);
|
||||
if (strcmp(name, "uevent") == 0)
|
||||
continue;
|
||||
if (strcmp(name, "dev") == 0)
|
||||
if (skip_attribute(name))
|
||||
continue;
|
||||
|
||||
value = udev_device_get_sysattr_value(device, name);
|
||||
if (value == NULL)
|
||||
continue;
|
||||
dbg(udev_device_get_udev(device), "attr '%s'='%s'\n", name, value);
|
||||
dbg(udev, "attr '%s'='%s'\n", name, value);
|
||||
|
||||
/* skip nonprintable attributes */
|
||||
len = strlen(value);
|
||||
while (len > 0 && isprint(value[len-1]))
|
||||
len--;
|
||||
if (len > 0) {
|
||||
dbg(udev_device_get_udev(device),
|
||||
"attribute value of '%s' non-printable, skip\n", name);
|
||||
dbg(udev, "attribute value of '%s' non-printable, skip\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user