summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-12-14 16:40:10 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2020-12-16 02:14:47 +0900
commit1223227f952a1939a592760ae437e417ba24bb01 (patch)
tree6bb57d0eea3d5a0dfd1f6564be84fe4c40630b3e
parent393fcaf733d8e50f18a70be7de1e088fb61f1ff4 (diff)
downloadsystemd-1223227f952a1939a592760ae437e417ba24bb01.tar.gz
udev: move util_resolve_subsys_kernel() to udev-util.c
-rw-r--r--src/libudev/libudev-util.c57
-rw-r--r--src/libudev/libudev-util.h1
-rw-r--r--src/shared/udev-util.c65
-rw-r--r--src/shared/udev-util.h1
-rw-r--r--src/test/test-libudev.c34
-rw-r--r--src/test/test-udev-util.c33
-rw-r--r--src/udev/udev-event.c2
-rw-r--r--src/udev/udev-rules.c8
8 files changed, 104 insertions, 97 deletions
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c
index 8a6b56be5c..a4835d4f40 100644
--- a/src/libudev/libudev-util.c
+++ b/src/libudev/libudev-util.c
@@ -18,63 +18,6 @@
* Utilities useful when dealing with devices and device node names.
*/
-/* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
-int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) {
- char temp[UTIL_PATH_SIZE], *subsys, *sysname, *attr;
- _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
- const char *val;
- int r;
-
- if (string[0] != '[')
- return -EINVAL;
-
- strscpy(temp, sizeof(temp), string);
-
- subsys = &temp[1];
-
- sysname = strchr(subsys, '/');
- if (!sysname)
- return -EINVAL;
- sysname[0] = '\0';
- sysname = &sysname[1];
-
- attr = strchr(sysname, ']');
- if (!attr)
- return -EINVAL;
- attr[0] = '\0';
- attr = &attr[1];
- if (attr[0] == '/')
- attr = &attr[1];
- if (attr[0] == '\0')
- attr = NULL;
-
- if (read_value && !attr)
- return -EINVAL;
-
- r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname);
- if (r < 0)
- return r;
-
- if (read_value) {
- r = sd_device_get_sysattr_value(dev, attr, &val);
- if (r < 0 && r != -ENOENT)
- return r;
- if (r == -ENOENT)
- result[0] = '\0';
- else
- strscpy(result, maxsize, val);
- log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result);
- } else {
- r = sd_device_get_syspath(dev, &val);
- if (r < 0)
- return r;
-
- strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL);
- log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result);
- }
- return 0;
-}
-
/**
* udev_util_encode_string:
* @str: input string to be encoded
diff --git a/src/libudev/libudev-util.h b/src/libudev/libudev-util.h
index 547981311e..f03e9eb221 100644
--- a/src/libudev/libudev-util.h
+++ b/src/libudev/libudev-util.h
@@ -9,7 +9,6 @@
#define UTIL_PATH_SIZE 1024
#define UTIL_NAME_SIZE 512
#define UTIL_LINE_SIZE 16384
-int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value);
/* Cleanup functions */
DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref);
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index d03e4bbe6f..5a506887e7 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -16,6 +16,7 @@
#include "signal-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strxcpyx.h"
#include "udev-util.h"
#include "utf8.h"
@@ -471,3 +472,67 @@ size_t udev_replace_chars(char *str, const char *allow) {
}
return replaced;
}
+
+int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value) {
+ _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+ _cleanup_free_ char *temp = NULL;
+ char *subsys, *sysname, *attr;
+ const char *val;
+ int r;
+
+ assert(string);
+ assert(result);
+
+ /* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
+
+ if (string[0] != '[')
+ return -EINVAL;
+
+ temp = strdup(string);
+ if (!temp)
+ return -ENOMEM;
+
+ subsys = &temp[1];
+
+ sysname = strchr(subsys, '/');
+ if (!sysname)
+ return -EINVAL;
+ sysname[0] = '\0';
+ sysname = &sysname[1];
+
+ attr = strchr(sysname, ']');
+ if (!attr)
+ return -EINVAL;
+ attr[0] = '\0';
+ attr = &attr[1];
+ if (attr[0] == '/')
+ attr = &attr[1];
+ if (attr[0] == '\0')
+ attr = NULL;
+
+ if (read_value && !attr)
+ return -EINVAL;
+
+ r = sd_device_new_from_subsystem_sysname(&dev, subsys, sysname);
+ if (r < 0)
+ return r;
+
+ if (read_value) {
+ r = sd_device_get_sysattr_value(dev, attr, &val);
+ if (r < 0 && r != -ENOENT)
+ return r;
+ if (r == -ENOENT)
+ result[0] = '\0';
+ else
+ strscpy(result, maxsize, val);
+ log_debug("value '[%s/%s]%s' is '%s'", subsys, sysname, attr, result);
+ } else {
+ r = sd_device_get_syspath(dev, &val);
+ if (r < 0)
+ return r;
+
+ strscpyl(result, maxsize, val, attr ? "/" : NULL, attr ?: NULL, NULL);
+ log_debug("path '[%s/%s]%s' is '%s'", subsys, sysname, strempty(attr), result);
+ }
+ return 0;
+}
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index f20e32b4d2..94ec970c50 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -38,3 +38,4 @@ void log_device_uevent(sd_device *device, const char *str);
int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos);
size_t udev_replace_whitespace(const char *str, char *to, size_t len);
size_t udev_replace_chars(char *str, const char *allow);
+int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value);
diff --git a/src/test/test-libudev.c b/src/test/test-libudev.c
index 6f72abc007..12bd0d6299 100644
--- a/src/test/test-libudev.c
+++ b/src/test/test-libudev.c
@@ -345,38 +345,6 @@ static void test_hwdb(struct udev *udev, const char *modalias) {
assert_se(hwdb == NULL);
}
-static void test_util_resolve_subsys_kernel_one(const char *str, bool read_value, int retval, const char *expected) {
- char result[UTIL_PATH_SIZE] = "";
- int r;
-
- r = util_resolve_subsys_kernel(str, result, sizeof(result), read_value);
- log_info("\"%s\" → expect: \"%s\", %d, actual: \"%s\", %d", str, strnull(expected), retval, result, r);
- assert_se(r == retval);
- if (r >= 0)
- assert_se(streq(result, expected));
-}
-
-static void test_util_resolve_subsys_kernel(void) {
- log_info("/* %s */", __func__);
-
- test_util_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL);
- test_util_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL);
- test_util_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL);
- test_util_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL);
-
- test_util_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo");
- test_util_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo");
- test_util_resolve_subsys_kernel_one("[net/lo]hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
- test_util_resolve_subsys_kernel_one("[net/lo]/hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
-
- test_util_resolve_subsys_kernel_one("[net/lo]", true, -EINVAL, NULL);
- test_util_resolve_subsys_kernel_one("[net/lo]/", true, -EINVAL, NULL);
- test_util_resolve_subsys_kernel_one("[net/lo]hoge", true, 0, "");
- test_util_resolve_subsys_kernel_one("[net/lo]/hoge", true, 0, "");
- test_util_resolve_subsys_kernel_one("[net/lo]address", true, 0, "00:00:00:00:00:00");
- test_util_resolve_subsys_kernel_one("[net/lo]/address", true, 0, "00:00:00:00:00:00");
-}
-
static void test_list(void) {
_cleanup_(udev_list_freep) struct udev_list *list = NULL;
struct udev_list_entry *e;
@@ -519,8 +487,6 @@ static int run(int argc, char *argv[]) {
if (arg_monitor)
test_monitor(udev);
- test_util_resolve_subsys_kernel();
-
test_list();
return 0;
diff --git a/src/test/test-udev-util.c b/src/test/test-udev-util.c
index 50d31f44e0..f34c5c27d3 100644
--- a/src/test/test-udev-util.c
+++ b/src/test/test-udev-util.c
@@ -235,6 +235,38 @@ static void test_udev_replace_whitespace(void) {
test_udev_replace_whitespace_one_len(" hoge hoge ", 0, "");
}
+static void test_udev_resolve_subsys_kernel_one(const char *str, bool read_value, int retval, const char *expected) {
+ char result[PATH_MAX] = "";
+ int r;
+
+ r = udev_resolve_subsys_kernel(str, result, sizeof(result), read_value);
+ log_info("\"%s\" → expect: \"%s\", %d, actual: \"%s\", %d", str, strnull(expected), retval, result, r);
+ assert_se(r == retval);
+ if (r >= 0)
+ assert_se(streq(result, expected));
+}
+
+static void test_udev_resolve_subsys_kernel(void) {
+ log_info("/* %s */", __func__);
+
+ test_udev_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL);
+ test_udev_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL);
+ test_udev_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL);
+ test_udev_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL);
+
+ test_udev_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo");
+ test_udev_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo");
+ test_udev_resolve_subsys_kernel_one("[net/lo]hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
+ test_udev_resolve_subsys_kernel_one("[net/lo]/hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
+
+ test_udev_resolve_subsys_kernel_one("[net/lo]", true, -EINVAL, NULL);
+ test_udev_resolve_subsys_kernel_one("[net/lo]/", true, -EINVAL, NULL);
+ test_udev_resolve_subsys_kernel_one("[net/lo]hoge", true, 0, "");
+ test_udev_resolve_subsys_kernel_one("[net/lo]/hoge", true, 0, "");
+ test_udev_resolve_subsys_kernel_one("[net/lo]address", true, 0, "00:00:00:00:00:00");
+ test_udev_resolve_subsys_kernel_one("[net/lo]/address", true, 0, "00:00:00:00:00:00");
+}
+
int main(int argc, char **argv) {
test_parse_value();
test_parse_value_with_backslashes();
@@ -253,6 +285,7 @@ int main(int argc, char **argv) {
test_parse_value_unicode();
test_udev_replace_whitespace();
+ test_udev_resolve_subsys_kernel();
return EXIT_SUCCESS;
}
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index f5831ed28d..c36f0bb732 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -346,7 +346,7 @@ static ssize_t udev_event_subst_format(
return -EINVAL;
/* try to read the value specified by "[dmi/id]product_name" */
- if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), true) == 0)
+ if (udev_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), true) == 0)
val = vbuf;
/* try to read the attribute the device */
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 7bfc25fdb5..c050eea56f 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -76,7 +76,7 @@ typedef enum {
TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */
TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */
TK_M_DRIVER, /* string, sd_device_get_driver() */
- TK_M_ATTR, /* string, takes filename through attribute, sd_device_get_sysattr_value(), util_resolve_subsys_kernel(), etc. */
+ TK_M_ATTR, /* string, takes filename through attribute, sd_device_get_sysattr_value(), udev_resolve_subsys_kernel(), etc. */
TK_M_SYSCTL, /* string, takes kernel parameter through attribute */
/* matches parent parameters */
@@ -1396,7 +1396,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev
return false;
break;
case SUBST_TYPE_SUBSYS:
- if (util_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0)
+ if (udev_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0)
return false;
value = vbuf;
break;
@@ -1641,7 +1641,7 @@ static int udev_rule_apply_token_to_event(
(void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false);
if (!path_is_absolute(buf) &&
- util_resolve_subsys_kernel(buf, buf, sizeof(buf), false) < 0) {
+ udev_resolve_subsys_kernel(buf, buf, sizeof(buf), false) < 0) {
char tmp[UTIL_PATH_SIZE];
r = sd_device_get_syspath(dev, &val);
@@ -2114,7 +2114,7 @@ static int udev_rule_apply_token_to_event(
const char *key_name = token->data;
char value[UTIL_NAME_SIZE];
- if (util_resolve_subsys_kernel(key_name, buf, sizeof(buf), false) < 0 &&
+ if (udev_resolve_subsys_kernel(key_name, buf, sizeof(buf), false) < 0 &&
sd_device_get_syspath(dev, &val) >= 0)
strscpyl(buf, sizeof(buf), val, "/", key_name, NULL);