summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-11-07 19:37:03 +0100
committerTom Gundersen <teg@jklm.no>2014-12-11 13:54:18 +0100
commit8f91f69ebf2d8149242b0dd535e420a75778dbe3 (patch)
treee19a07dc96a51df607558c401885b8fc52c937aa
parentb5284aed71f86f845127fffad65bc7cab5a68247 (diff)
sd-device: add sd_device_get_subsystem
-rw-r--r--src/libsystemd/sd-device/sd-device.c63
-rw-r--r--src/systemd/sd-device.h1
2 files changed, 64 insertions, 0 deletions
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index acb699479..695ca835a 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -48,8 +48,11 @@ struct sd_device {
char *devnode;
dev_t devnum;
+ char *subsystem;
+
bool uevent_loaded;
bool parent_set;
+ bool subsystem_set;
};
static int device_new(sd_device **ret) {
@@ -83,6 +86,7 @@ _public_ sd_device *sd_device_unref(sd_device *device) {
free(device->sysname);
free(device->devtype);
free(device->devnode);
+ free(device->subsystem);
free(device);
}
@@ -623,3 +627,62 @@ _public_ int sd_device_get_parent(sd_device *child, sd_device **ret) {
return 0;
}
+
+static int device_set_subsystem(sd_device *device, const char *_subsystem) {
+ _cleanup_free_ char *subsystem = NULL;
+ int r;
+
+ assert(device);
+ assert(_subsystem);
+
+ subsystem = strdup(_subsystem);
+ if (!subsystem)
+ return -ENOMEM;
+
+ free(device->subsystem);
+ device->subsystem = subsystem;
+ subsystem = NULL;
+
+ device->subsystem_set = true;
+
+ return 0;
+}
+
+_public_ int sd_device_get_subsystem(sd_device *device, const char **ret) {
+ assert_return(ret, -EINVAL);
+ assert_return(device, -EINVAL);
+
+ if (!device->subsystem_set) {
+ _cleanup_free_ char *subsystem = NULL;
+ const char *syspath;
+ char *path;
+ int r;
+
+ /* read 'subsystem' link */
+ r = sd_device_get_syspath(device, &syspath);
+ if (r < 0)
+ return r;
+
+ path = strappenda(syspath, "/subsystem");
+ r = readlink_value(path, &subsystem);
+ if (r >= 0)
+ r = device_set_subsystem(device, subsystem);
+ /* use implicit names */
+ else if (path_startswith(device->devpath, "/module/"))
+ r = device_set_subsystem(device, "module");
+ else if (strstr(device->devpath, "/drivers/"))
+ r = device_set_subsystem(device, "drivers");
+ else if (path_startswith(device->devpath, "/subsystem/") ||
+ path_startswith(device->devpath, "/class/") ||
+ path_startswith(device->devpath, "/buss/"))
+ r = device_set_subsystem(device, "subsystem");
+ if (r < 0)
+ return r;
+
+ device->subsystem_set = true;
+ }
+
+ *ret = device->subsystem;
+
+ return 0;
+}
diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h
index 820660145..13e95b7aa 100644
--- a/src/systemd/sd-device.h
+++ b/src/systemd/sd-device.h
@@ -42,6 +42,7 @@ int sd_device_new_from_device_id(sd_device **ret, const char *id);
int sd_device_get_syspath(sd_device *device, const char **ret);
int sd_device_get_parent(sd_device *child, sd_device **ret);
+int sd_device_get_subsystem(sd_device *device, const char **ret);
_SD_END_DECLARATIONS;