chiark / gitweb /
don't create $tempnode for devices without major
[elogind.git] / udev_rules.c
index ea02b8e9455763ae9346dfc96a2661ecc2f44b97..5c3d7d5d0646a81d98507a5124d5efde603cf5dd 100644 (file)
@@ -289,7 +289,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
                        info("file '%s' appeared after %i loops", filepath, (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
                        return 0;
                }
-               /* make sure the device does not have disappeared in the meantime */
+               /* make sure, the device did not disappear in the meantime */
                if (stat(devicepath, &stats) != 0) {
                        info("device disappeared while waiting for '%s'", filepath);
                        return -2;
@@ -532,7 +532,7 @@ found:
                        }
                        break;
                case SUBST_TEMP_NODE:
-                       if (udev->tmp_node[0] == '\0') {
+                       if (udev->tmp_node[0] == '\0' && major(udev->devt) > 0) {
                                dbg("create temporary device node for callout");
                                snprintf(udev->tmp_node, sizeof(udev->tmp_node), "%s/.tmp-%u-%u",
                                         udev_root, major(udev->devt), minor(udev->devt));
@@ -584,18 +584,18 @@ static char *key_pair_name(struct udev_rule *rule, struct key_pair *pair)
 
 static int match_key(const char *key_name, struct udev_rule *rule, struct key *key, const char *val)
 {
-       int match;
        char value[PATH_SIZE];
        char *key_value;
        char *pos;
+       int match = 0;
 
        if (key->operation != KEY_OP_MATCH &&
            key->operation != KEY_OP_NOMATCH)
                return 0;
 
+       /* look for a matching string, parts are separated by '|' */
        strlcpy(value, rule->buf + key->val_off, sizeof(value));
        key_value = value;
-
        dbg("key %s value='%s'", key_name, key_value);
        while (key_value) {
                pos = strchr(key_value, '|');
@@ -603,19 +603,23 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k
                        pos[0] = '\0';
                        pos++;
                }
+
                dbg("match %s '%s' <-> '%s'", key_name, key_value, val);
                match = (fnmatch(key_value, val, 0) == 0);
-               if (match && (key->operation != KEY_OP_NOMATCH)) {
-                       dbg("%s is true (matching value)", key_name);
-                       return 0;
-               }
-               if (!match && (key->operation == KEY_OP_NOMATCH)) {
-                       dbg("%s is true (non-matching value)", key_name);
-                       return 0;
-               }
+               if (match)
+                       break;
+
                key_value = pos;
        }
-       dbg("%s is false", key_name);
+
+       if (match && (key->operation == KEY_OP_MATCH)) {
+               dbg("%s is true (matching value)", key_name);
+               return 0;
+       }
+       if (!match && (key->operation == KEY_OP_NOMATCH)) {
+               dbg("%s is true (non-matching value)", key_name);
+               return 0;
+       }
        return -1;
 }
 
@@ -827,18 +831,23 @@ try_parent:
                        char temp_value[NAME_SIZE];
                        const char *key_name = key_pair_name(rule, pair);
                        const char *value = key_val(rule, &pair->key);
-                       char *key_value;
 
                        /* make sure we don't write to the same string we possibly read from */
                        strlcpy(temp_value, value, sizeof(temp_value));
                        udev_rules_apply_format(udev, temp_value, NAME_SIZE);
 
-                       key_value = name_list_key_add(&udev->env_list, key_name, temp_value);
-                       if (key_value == NULL)
-                               break;
+                       if (temp_value[0] == '\0') {
+                               name_list_key_remove(&udev->env_list, key_name);
+                               unsetenv(key_name);
+                               info("unset ENV '%s'", key_name);
+                       } else {
+                               char *key_value = name_list_key_add(&udev->env_list, key_name, temp_value);
 
-                       putenv(key_value);
-                       dbg("export ENV '%s'", key_value);
+                               if (key_value == NULL)
+                                       break;
+                               putenv(key_value);
+                               info("set ENV '%s'", key_value);
+                       }
                }
        }
 
@@ -861,8 +870,9 @@ try_parent:
                        info("writing '%s' to sysfs file '%s'", value, attr);
                        f = fopen(attr, "w");
                        if (f != NULL) {
-                               if (fprintf(f, "%s", value) <= 0)
-                                       err("error writing ATTR{%s}: %s", attr, strerror(errno));
+                               if (!udev->test_run)
+                                       if (fprintf(f, "%s", value) <= 0)
+                                               err("error writing ATTR{%s}: %s", attr, strerror(errno));
                                fclose(f);
                        } else
                                err("error opening ATTR{%s} for writing: %s", attr, strerror(errno));
@@ -909,7 +919,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
                                udev->ignore_remove = 1;
                                dbg("remove event should be ignored");
                        }
-                       if (rule->link_priority) {
+                       if (rule->link_priority != 0) {
                                udev->link_priority = rule->link_priority;
                                info("link_priority=%i", udev->link_priority);
                        }