From: Thomas Egerer <thomas.egerer@secunet.com>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH 1/2] libudev: Get available sysfs attrs for a device
Date: Fri, 04 Mar 2011 16:06:41 +0000 [thread overview]
Message-ID: <4D710E11.8030508@secunet.com> (raw)
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
---
libudev/exported_symbols | 1 +
libudev/libudev-device.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++
libudev/libudev.h | 1 +
3 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/libudev/exported_symbols b/libudev/exported_symbols
index 2e6a9b7..500e981 100644
--- a/libudev/exported_symbols
+++ b/libudev/exported_symbols
@@ -32,6 +32,7 @@ udev_device_get_is_initialized
udev_device_get_devlinks_list_entry
udev_device_get_properties_list_entry
udev_device_get_tags_list_entry
+udev_device_get_sysattr_list_entry
udev_device_get_property_value
udev_device_get_action
udev_device_get_driver
diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c
index 16bee19..af0bc2e 100644
--- a/libudev/libudev-device.c
+++ b/libudev/libudev-device.c
@@ -61,6 +61,7 @@ struct udev_device {
struct udev_list_node devlinks_list;
struct udev_list_node properties_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;
@@ -83,6 +84,7 @@ struct udev_device {
bool db_loaded;
bool uevent_loaded;
bool is_initialized;
+ bool sysattrs_cached;
};
struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
@@ -361,6 +363,7 @@ struct udev_device *udev_device_new(struct udev *udev)
udev_list_init(&udev_device->devlinks_list);
udev_list_init(&udev_device->properties_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;
@@ -785,6 +788,7 @@ void udev_device_unref(struct udev_device *udev_device)
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_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);
@@ -1235,6 +1239,83 @@ out:
return val;
}
+static int udev_device_cache_sysattrs(struct udev_device *udev_device)
+{
+ struct dirent *entry;
+ DIR *dir;
+ int num = 0;
+
+ if (udev_device = NULL)
+ return -1;
+ /* caching already done? */
+ if (udev_device->sysattrs_cached)
+ return 0;
+
+ dir = opendir(udev_device_get_syspath(udev_device));
+ if (!dir) {
+ dbg(udev_device->udev, "sysfs dir '%s' can not be opened\n",
+ udev_device_get_syspath(udev_device));
+ return -1;
+ }
+
+ while (NULL != (entry = 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)
+ continue;
+
+ util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device),
+ "/", entry->d_name, NULL);
+ if (0 != lstat(path, &statbuf))
+ 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;
+ }
+
+ dbg(udev_device->udev, "found %d sysattrs for '%s'\n", num,
+ udev_device_get_syspath(udev_device));
+ udev_device->sysattrs_cached = true;
+
+ return num;
+}
+
+/**
+ * udev_device_get_sysattr_list_entry:
+ * @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.
+ *
+ * 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) {
+ int ret;
+ ret = udev_device_cache_sysattrs(udev_device);
+ if (0 > ret)
+ return NULL;
+ }
+
+ return udev_list_get_entry(&udev_device->available_sysattr_list);
+}
+
int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
{
const char *pos;
diff --git a/libudev/libudev.h b/libudev/libudev.h
index 0abd7c8..892530b 100644
--- a/libudev/libudev.h
+++ b/libudev/libudev.h
@@ -92,6 +92,7 @@ int udev_device_get_is_initialized(struct udev_device *udev_device);
struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device);
+struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device);
const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key);
const char *udev_device_get_driver(struct udev_device *udev_device);
dev_t udev_device_get_devnum(struct udev_device *udev_device);
reply other threads:[~2011-03-04 16:06 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D710E11.8030508@secunet.com \
--to=thomas.egerer@secunet.com \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.