chiark / gitweb /
rename WAIT_FOR_SYSFS to WAIT_FOR and accept an absolute path
authorKay Sievers <kay.sievers@vrfy.org>
Tue, 20 May 2008 13:02:17 +0000 (15:02 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Tue, 20 May 2008 13:02:17 +0000 (15:02 +0200)
This allows us to watch any file to appear, not only sysfs
attributes. Files without a leading slash will be device sysfs
attributes. The key WAIT_FOR_SYSFS still works for backwards
compat, but is removed from the man page.

udev.7
udev.xml
udev_rules.c
udev_rules.h
udev_rules_parse.c

diff --git a/udev.7 b/udev.7
index 79e61ea..a09bdf9 100644 (file)
--- a/udev.7
+++ b/udev.7
@@ -257,9 +257,9 @@ and
 based on the executable bit of the file permissions\.
 .RE
 .PP
-\fBWAIT_FOR_SYSFS\fR
+\fBWAIT_FOR\fR
 .RS 4
-Wait for the specified sysfs file of the device to be created\. Can be used to fight against kernel sysfs timing issues\.
+Wait for a file to become available\.
 .RE
 .PP
 \fBOPTIONS\fR
index 184457a..a7422e1 100644 (file)
--- a/udev.xml
+++ b/udev.xml
             </varlistentry>
 
             <varlistentry>
-              <term><option>WAIT_FOR_SYSFS</option></term>
+              <term><option>WAIT_FOR</option></term>
               <listitem>
-                <para>Wait for the specified sysfs file of the device to be created. Can be used
-                to fight against kernel sysfs timing issues.</para>
+                <para>Wait for a file to become available.</para>
               </listitem>
             </varlistentry>
 
index f4ee11a..a102e2d 100644 (file)
@@ -528,35 +528,40 @@ int udev_rules_run(struct udevice *udev)
 }
 
 #define WAIT_LOOP_PER_SECOND           50
-static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
+static int wait_for_file(struct udevice *udev, const char *file, int timeout)
 {
-       char devicepath[PATH_SIZE];
        char filepath[PATH_SIZE];
+       char devicepath[PATH_SIZE] = "";
        struct stat stats;
        int loop = timeout * WAIT_LOOP_PER_SECOND;
 
-       strlcpy(devicepath, sysfs_path, sizeof(devicepath));
-       strlcat(devicepath, udev->dev->devpath, sizeof(devicepath));
-       strlcpy(filepath, devicepath, sizeof(filepath));
-       strlcat(filepath, "/", sizeof(filepath));
-       strlcat(filepath, file, sizeof(filepath));
+       /* a relative path is a device attribute */
+       if (file[0] != '/') {
+               strlcpy(devicepath, sysfs_path, sizeof(devicepath));
+               strlcat(devicepath, udev->dev->devpath, sizeof(devicepath));
 
-       dbg("will wait %i sec for '%s'\n", timeout, filepath);
+               strlcpy(filepath, devicepath, sizeof(filepath));
+               strlcat(filepath, "/", sizeof(filepath));
+               strlcat(filepath, file, sizeof(filepath));
+               file = filepath;
+       }
+
+       dbg("will wait %i sec for '%s'\n", timeout, file);
        while (--loop) {
                /* lookup file */
-               if (stat(filepath, &stats) == 0) {
-                       info("file '%s' appeared after %i loops\n", filepath, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
+               if (stat(file, &stats) == 0) {
+                       info("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
                        return 0;
                }
                /* make sure, the device did not disappear in the meantime */
-               if (stat(devicepath, &stats) != 0) {
-                       info("device disappeared while waiting for '%s'\n", filepath);
+               if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) {
+                       info("device disappeared while waiting for '%s'\n", file);
                        return -2;
                }
-               info("wait for '%s' for %i mseconds\n", filepath, 1000 / WAIT_LOOP_PER_SECOND);
+               info("wait for '%s' for %i mseconds\n", file, 1000 / WAIT_LOOP_PER_SECOND);
                usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
        }
-       info("waiting for '%s' failed\n", filepath);
+       info("waiting for '%s' failed\n", file);
        return -1;
 }
 
@@ -1110,11 +1115,14 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
                dbg("TEST key is true\n");
        }
 
-       if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) {
+       if (rule->wait_for.operation != KEY_OP_UNSET) {
+               char filename[PATH_SIZE];
                int found;
 
-               found = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 10) == 0);
-               if (!found && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH))
+               strlcpy(filename, key_val(rule, &rule->wait_for), sizeof(filename));
+               udev_rules_apply_format(udev, filename, sizeof(filename));
+               found = (wait_for_file(udev, filename, 10) == 0);
+               if (!found && (rule->wait_for.operation != KEY_OP_NOMATCH))
                        goto nomatch;
        }
 
index da5ac3e..fe0f9df 100644 (file)
@@ -84,7 +84,7 @@ struct udev_rule {
        struct key test;
        mode_t test_mode_mask;
        struct key run;
-       struct key wait_for_sysfs;
+       struct key wait_for;
        struct key label;
        struct key goto_label;
 
index 5119b7e..bdaf55b 100644 (file)
@@ -495,8 +495,8 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                        continue;
                }
 
-               if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
-                       add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
+               if (strcasecmp(key, "WAIT_FOR") == 0 || strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
+                       add_rule_key(rule, &rule->wait_for, operation, value);
                        valid = 1;
                        continue;
                }
@@ -629,7 +629,7 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena
                err("unknown key '%s' in %s:%u\n", key, filename, lineno);
        }
 
-       if (physdev && rule->wait_for_sysfs.operation == KEY_OP_UNSET)
+       if (physdev && rule->wait_for.operation == KEY_OP_UNSET)
                err("PHYSDEV* values are deprecated and will be removed from a future kernel, \n"
                    "please fix it in %s:%u", filename, lineno);