chiark / gitweb /
add substitution in MODE= field
authorErik van Konijnenburg <ekonijn@xs4all.nl>
Mon, 19 May 2008 07:05:20 +0000 (09:05 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Mon, 19 May 2008 07:05:20 +0000 (09:05 +0200)
Do substitition processing in MODE field, similar to substitution in
OWNER, GROUP etc fields.  Add test case for normal and overflow behaviour.
Document in manpage.

test/udev-test.pl
udev.7
udev.xml
udev_rules.c

index fee62a6..72b4aef 100755 (executable)
@@ -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           => <<EOF
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+       },
+       {
+               desc            => "TEST PROGRAM feeds MODE with overflow",
+               subsys          => "block",
+               devpath         => "/block/sda",
+               exp_name        => "sda",
+               exp_perms       => "0:0:0400",
+               rules           => <<EOF
+KERNEL=="sda", PROGRAM=="/bin/echo 0 0 0400letsdoabuffferoverflow0123456789012345789012345678901234567890", OWNER="%c{1}", GROUP="%c{2}", MODE="%c{3}"
+EOF
+       },
+
 );
 
 # set env
@@ -1732,6 +1753,15 @@ sub symlink_test {
        }
 }
 
+sub make_udev_root {
+       system("rm -rf $udev_root");
+       mkdir($udev_root) || die "unable to create udev_root: $udev_root\n";
+       # setting group and mode of udev_root ensures the tests work
+       # even if the parent directory has setgid bit enabled.
+       chown (0, 0, $udev_root) || die "unable to chown $udev_root\n";
+       chmod (0755, $udev_root) || die "unable to chmod $udev_root\n";
+}
+
 sub run_test {
        my ($rules, $number) = @_;
 
@@ -1804,8 +1834,7 @@ sub run_test {
        print "\n";
 
        if (defined($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 096bf38..79e61ea 100644 (file)
--- 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
index ac3676e..184457a 100644 (file)
--- a/udev.xml
+++ b/udev.xml
           </variablelist>
 
           <para>The <option>NAME</option>, <option>SYMLINK</option>, <option>PROGRAM</option>,
-          <option>OWNER</option>, <option>GROUP</option>  and  <option>RUN</option>
+          <option>OWNER</option>, <option>GROUP</option>, <option>MODE</option>  and  <option>RUN</option>
           fields support simple printf-like string substitutions. The <option>RUN</option>
           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
index 55a079b..f4ee11a 100644 (file)
@@ -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) {