diff --git a/test/udev-test.pl b/test/udev-test.pl index fee62a64060..72b4aef6bc6 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1617,6 +1617,27 @@ EOF KERNEL=="sda", MODE="0000" EOF }, + { + desc => "TEST PROGRAM feeds MODE", + subsys => "block", + devpath => "/block/sda", + exp_name => "sda", + exp_perms => "0:0:0400", + rules => < "TEST PROGRAM feeds MODE with overflow", + subsys => "block", + devpath => "/block/sda", + exp_name => "sda", + exp_perms => "0:0:0400", + rules => <{option}) && $rules->{option} eq "clean") { - system("rm -rf $udev_root"); - mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + make_udev_root (); } } @@ -1818,8 +1847,7 @@ if (!($<==0)) { } # prepare -system("rm -rf $udev_root"); -mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; +make_udev_root (); # create config file open CONF, ">$udev_conf" || die "unable to create config file: $udev_conf"; diff --git a/udev.7 b/udev.7 index 096bf385548..79e61ea9f45 100644 --- a/udev.7 +++ b/udev.7 @@ -307,7 +307,8 @@ The \fBSYMLINK\fR, \fBPROGRAM\fR, \fBOWNER\fR, -\fBGROUP\fR +\fBGROUP\fR, +\fBMODE\fR and \fBRUN\fR fields support simple printf\-like string substitutions\. The diff --git a/udev.xml b/udev.xml index ac3676e4663..184457aa6c9 100644 --- a/udev.xml +++ b/udev.xml @@ -462,7 +462,7 @@ The , , , - , and + , , and fields support simple printf-like string substitutions. The format chars gets applied after all rules have been processed, right before the program is executed. It allows the use of the complete environment set by earlier matching diff --git a/udev_rules.c b/udev_rules.c index 55a079be874..f4ee11a56c8 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -1412,7 +1412,10 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) if (!udev->mode_final && rule->mode.operation != KEY_OP_UNSET) { if (rule->mode.operation == KEY_OP_ASSIGN_FINAL) udev->mode_final = 1; - udev->mode = strtol(key_val(rule, &rule->mode), NULL, 8); + char buf[20]; + strlcpy(buf, key_val(rule, &rule->mode), sizeof(buf)); + udev_rules_apply_format(udev, buf, sizeof(buf)); + udev->mode = strtol(buf, NULL, 8); dbg("applied mode=%#o to '%s'\n", udev->mode, udev->dev->kernel); } if (!udev->owner_final && rule->owner.operation != KEY_OP_UNSET) {