mirror of
https://github.com/systemd/systemd
synced 2024-10-15 12:34:37 +00:00
udev: move util_resolve_subsys_kernel() to udev-util.c
This commit is contained in:
parent
393fcaf733
commit
1223227f95
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue