chiark / gitweb /
add TEST=="<file>" key
authorKay Sievers <kay.sievers@vrfy.org>
Sat, 2 Jun 2007 22:01:46 +0000 (00:01 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Sat, 2 Jun 2007 22:01:46 +0000 (00:01 +0200)
udev.7
udev.h
udev.xml
udev_node.c
udev_rules.c
udev_rules.h
udev_rules_parse.c

diff --git a/udev.7 b/udev.7
index 4fbaf924320b64f874bf975cdc9f618409c3c48b..a25358158143c3ef63da0178bb738c8c4479cc44 100644 (file)
--- a/udev.7
+++ b/udev.7
@@ -151,6 +151,11 @@ Match against the value of an environment variable. Up to five
 keys can be specified per rule. Depending on the type of operator, this key is also used to export a variable to the environment.
 .RE
 .PP
+\fBTEST{\fR\fB\fIoctal mode mask\fR\fR\fB}\fR
+.RS 4
+Test the existence of a file. An octal mode mask can be specified if needed.
+.RE
+.PP
 \fBPROGRAM\fR
 .RS 4
 Execute external program. The key is true, if the program returns with exit code zero. The whole event environment is available to the executed program. The program's output printed to stdout, is available in the RESULT key.
diff --git a/udev.h b/udev.h
index 94d054f76069940ac35b6d5de6ca219e9e3d8531..64510ed35f8dd40d09363dd4488d31db1389421a 100644 (file)
--- a/udev.h
+++ b/udev.h
@@ -119,6 +119,7 @@ extern struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev);
 extern struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem);
 extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
 extern int sysfs_resolve_link(char *path, size_t size);
+extern int sysfs_lookup_devpath_by_subsys_id(char *devpath, size_t len, const char *subsystem, const char *id);
 
 /* udev_node.c */
 extern int udev_node_mknod(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid);
index 1f9e6d91972a71775ef0f6aaaf33343d939aaecd..a3658bd548575915ff9705fd1060001c27dac3aa 100644 (file)
--- a/udev.xml
+++ b/udev.xml
               </listitem>
             </varlistentry>
 
+            <varlistentry>
+              <term><option>TEST{<replaceable>octal mode mask</replaceable>}</option></term>
+              <listitem>
+                <para>Test the existence of a file. An octal mode mask can be specified
+                if needed.</para>
+              </listitem>
+            </varlistentry>
+
             <varlistentry>
               <term><option>PROGRAM</option></term>
               <listitem>
index b1bbda8369c3e264e86b583015d122e1299f96fe..338948fc54b90ec0b610c31cf632a5a994b5571e 100644 (file)
@@ -322,7 +322,7 @@ int udev_node_add(struct udevice *udev)
 
                /* take the maximum registered minor range */
                attr = sysfs_attr_get_value(udev->dev->devpath, "range");
-               if (attr) {
+               if (attr != NULL) {
                        range = atoi(attr);
                        if (range > 1)
                                udev->partitions = range-1;
index e61c9a69b062c02fa2fe083911cc964ba8789d3e..5ded26d049d3c89202d08afec5a10fd8f1b9a041 100644 (file)
@@ -641,6 +641,29 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
                }
        }
 
+       if (rule->test.operation != KEY_OP_UNSET) {
+               char filename[PATH_SIZE];
+               struct stat statbuf;
+               int match;
+
+               strlcpy(filename, key_val(rule, &rule->test), sizeof(filename));
+               udev_rules_apply_format(udev, filename, sizeof(filename));
+
+               match = (stat(filename, &statbuf) == 0);
+               info("'%s' %s", filename, match ? "exists" : "does not exist");
+               if (match && rule->test_mode_mask > 0) {
+                       match = ((statbuf.st_mode & rule->test_mode_mask) > 0);
+                       info("'%s' has mode=%#o and %s %#o", filename, statbuf.st_mode,
+                            match ? "matches" : "does not match",
+                            rule->test_mode_mask);
+               }
+               if (match && rule->test.operation == KEY_OP_NOMATCH)
+                       goto nomatch;
+               if (!match && rule->test.operation == KEY_OP_MATCH)
+                       goto nomatch;
+               dbg("TEST key is true");
+       }
+
        if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) {
                int found;
 
@@ -1037,7 +1060,8 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev)
 
                dbg("process rule");
                if (rule->name.operation != KEY_OP_UNSET || rule->symlink.operation != KEY_OP_UNSET ||
-                   rule->mode_operation != KEY_OP_UNSET || rule->owner.operation != KEY_OP_UNSET || rule->group.operation != KEY_OP_UNSET) {
+                   rule->mode_operation != KEY_OP_UNSET || rule->owner.operation != KEY_OP_UNSET ||
+                   rule->group.operation != KEY_OP_UNSET) {
                        dbg("skip rule that names a device");
                        continue;
                }
@@ -1050,7 +1074,8 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev)
                        }
 
                        if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) {
-                               if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) {
+                               if (rule->run.operation == KEY_OP_ASSIGN ||
+                                   rule->run.operation == KEY_OP_ASSIGN_FINAL) {
                                        info("reset run list");
                                        name_list_cleanup(&udev->run_list);
                                }
index 7fbf88ba573a1c08b7b8a78ce3b49a5d3936c6c6..0e1ff76b42152439284114842ff32e2cf56bc35d 100644 (file)
@@ -75,6 +75,8 @@ struct udev_rule {
        struct key result;
        struct key import;
        enum import_type import_type;
+       struct key test;
+       mode_t test_mode_mask;
        struct key run;
        struct key wait_for_sysfs;
        struct key label;
index 9166980488fa0362fe8316753dd11fb0d278f35f..4420616903093e532e461fa269e745599626988e 100644 (file)
@@ -470,6 +470,15 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
+               if (strncasecmp(key, "TEST", sizeof("TEST")-1) == 0) {
+                       attr = get_key_attribute(key + sizeof("TEST")-1);
+                       if (attr != NULL)
+                               rule->test_mode_mask = strtol(attr, NULL, 8);
+                       add_rule_key(rule, &rule->test, operation, value);
+                       valid = 1;
+                       continue;
+               }
+
                if (strcasecmp(key, "RUN") == 0) {
                        add_rule_key(rule, &rule->run, operation, value);
                        valid = 1;