summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-05-20 15:02:17 +0200
committerKay Sievers <kay.sievers@vrfy.org>2008-05-20 15:02:17 +0200
commitea97dc3792642fa8187a339cc258f9a5a7df4523 (patch)
treeb36a9a7d0f35e929fe953c59805d566461c66339
parentbc44071db2ea1f20d955e5f1310c8038e78abd73 (diff)
rename WAIT_FOR_SYSFS to WAIT_FOR and accept an absolute path
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.
-rw-r--r--udev.74
-rw-r--r--udev.xml5
-rw-r--r--udev_rules.c42
-rw-r--r--udev_rules.h2
-rw-r--r--udev_rules_parse.c6
5 files changed, 33 insertions, 26 deletions
diff --git a/udev.7 b/udev.7
index 79e61ea9f4..a09bdf9ec7 100644
--- 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
diff --git a/udev.xml b/udev.xml
index 184457aa6c..a7422e1ca0 100644
--- a/udev.xml
+++ b/udev.xml
@@ -394,10 +394,9 @@
</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>
diff --git a/udev_rules.c b/udev_rules.c
index f4ee11a56c..a102e2da50 100644
--- a/udev_rules.c
+++ b/udev_rules.c
@@ -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;
}
diff --git a/udev_rules.h b/udev_rules.h
index da5ac3ea18..fe0f9dfbb5 100644
--- a/udev_rules.h
+++ b/udev_rules.h
@@ -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;
diff --git a/udev_rules_parse.c b/udev_rules_parse.c
index 5119b7e84f..bdaf55bd48 100644
--- a/udev_rules_parse.c
+++ b/udev_rules_parse.c
@@ -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);