diff options
-rwxr-xr-x | test/udev-test.pl | 12 | ||||
-rw-r--r-- | udev_rules.c | 35 | ||||
-rw-r--r-- | udev_rules.h | 5 | ||||
-rw-r--r-- | udev_rules_parse.c | 8 |
4 files changed, 45 insertions, 15 deletions
diff --git a/test/udev-test.pl b/test/udev-test.pl index c7a99e517d..bf6b62f10a 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -259,7 +259,7 @@ BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}" EOF }, { - desc => "import of shellvalue file", + desc => "import of shell-value file", subsys => "block", devpath => "/block/sda", exp_name => "subdir/sys/node" , @@ -269,6 +269,16 @@ KERNEL=="ttyUSB0", NAME="visor" EOF }, { + desc => "import of shell-value returned from program", + subsys => "block", + devpath => "/block/sda", + exp_name => "node12345678", + rules => <<EOF +BUS=="scsi", IMPORT{exec}="/bin/echo -e \' TEST_KEY=12345678 \\n TEST_key2=98765 \'", NAME="node\$env{TEST_KEY}" +KERNEL=="ttyUSB0", NAME="visor" +EOF + }, + { desc => "sustitution of sysfs value (%s{file})", subsys => "block", devpath => "/block/sda", diff --git a/udev_rules.c b/udev_rules.c index aa66c7ad30..b81943a17c 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -241,8 +241,8 @@ static int import_keys_into_env(const char *buf, size_t bufsize) linepos = line; if (get_key(&linepos, &variable, &value) == 0) { - dbg("import %s=%s", variable, value); - setenv(variable, value, 0); + dbg("import '%s=%s'", variable, value); + setenv(variable, value, 1); } } @@ -264,11 +264,18 @@ static int import_file_into_env(const char *filename) return 0; } -/** Finds the lowest positive N such that <name>N isn't present in - * $(udevroot) either as a file or a symlink. - * - * @param name Name to check for - * @return 0 if <name> didn't exist and N otherwise. +static int import_program_into_env(struct udevice *udev, const char *program) +{ + char result[1024]; + size_t reslen; + + if (execute_program(program, udev->subsystem, result, sizeof(result), &reslen) != 0) + return -1; + return import_keys_into_env(result, reslen); +} + +/* finds the lowest positive N such that <name>N isn't present in the udevdb + * if <name> doesn't exist, 0 is returned, N otherwise */ static int find_free_number(struct udevice *udev, const char *name) { @@ -811,16 +818,24 @@ try_parent: /* import variables from file into environment */ if (rule->import_operation != KEY_OP_UNSET) { char import[PATH_SIZE]; + int rc = -1; strlcpy(import, rule->import, sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); - dbg("check for " KEY_IMPORT " import='%s", import); - if (import_file_into_env(import) != 0) { + dbg("check for " KEY_IMPORT " import='%s'", import); + if (rule->import_exec) { + dbg("run executable file import='%s'", import); + rc = import_program_into_env(udev, import); + } else { + dbg("import file import='%s'", import); + rc = import_file_into_env(import); + } + if (rc) { dbg(KEY_IMPORT " failed"); if (rule->import_operation != KEY_OP_NOMATCH) goto exit; } else - dbg(KEY_IMPORT " file '%s' imported", rule->import); + dbg(KEY_IMPORT " '%s' imported", rule->import); dbg(KEY_IMPORT " key is true"); } diff --git a/udev_rules.h b/udev_rules.h index f4b0a6f12f..bad8406cf4 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -99,10 +99,11 @@ struct udev_rule { int sysfs_pair_count; struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; int env_pair_count; + char modalias[NAME_SIZE]; enum key_operation modalias_operation; - char modalias[PATH_SIZE]; - enum key_operation import_operation; char import[PATH_SIZE]; + enum key_operation import_operation; + int import_exec; char name[PATH_SIZE]; enum key_operation name_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 121236820b..4979feddc1 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -375,7 +375,12 @@ static int rules_parse(const char *filename) continue; } - if (strcasecmp(key, KEY_IMPORT) == 0) { + if (strncasecmp(key, KEY_IMPORT, sizeof(KEY_IMPORT)-1) == 0) { + attr = get_key_attribute(key + sizeof(KEY_IMPORT)-1); + if (attr && strstr(attr, "exec")) { + dbg(KEY_IMPORT" will be executed"); + rule.import_exec = 1; + } strlcpy(rule.import, value, sizeof(rule.import)); rule.import_operation = operation; valid = 1; @@ -411,7 +416,6 @@ static int rules_parse(const char *filename) dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } - /* FIXME: remove old style option and make OPTIONS= mandatory */ if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; |