udev: use Hashmap for storing PROGRAM or BUILTIN
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 16 Oct 2018 21:11:33 +0000 (06:11 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 16 Oct 2018 21:49:56 +0000 (06:49 +0900)
src/udev/udev-event.c
src/udev/udev-rules.c
src/udev/udev.h
src/udev/udevadm-test.c

index e015ecf..966be0d 100644 (file)
@@ -44,16 +44,18 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
         if (event == NULL)
                 return NULL;
         event->dev = dev;
-        udev_list_init(NULL, &event->run_list, false);
         event->birth_usec = now(CLOCK_MONOTONIC);
         return event;
 }
 
 void udev_event_unref(struct udev_event *event) {
+        void *p;
+
         if (event == NULL)
                 return;
         sd_netlink_unref(event->rtnl);
-        udev_list_cleanup(&event->run_list);
+        while ((p = hashmap_steal_first_key(event->run_list)))
+                free(p);
         hashmap_free_free_free(event->seclabel_list);
         free(event->program_result);
         free(event->name);
@@ -888,12 +890,13 @@ void udev_event_execute_rules(struct udev_event *event,
 }
 
 void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec) {
-        struct udev_list_entry *list_entry;
+        const char *cmd;
+        void *val;
+        Iterator i;
 
-        udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
+        HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
+                enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val);
                 char command[UTIL_PATH_SIZE];
-                const char *cmd = udev_list_entry_get_name(list_entry);
-                enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
 
                 udev_event_apply_format(event, cmd, command, sizeof(command), false);
 
index 601b958..e90b762 100644 (file)
@@ -2388,16 +2388,33 @@ int udev_rules_apply_to_event(
                 }
                 case TK_A_RUN_BUILTIN:
                 case TK_A_RUN_PROGRAM: {
-                        struct udev_list_entry *entry;
+                        _cleanup_free_ char *cmd = NULL;
+
+                        if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL)) {
+                                void *p;
+
+                                while ((p = hashmap_steal_first_key(event->run_list)))
+                                        free(p);
+                        }
+
+                        r = hashmap_ensure_allocated(&event->run_list, NULL);
+                        if (r < 0)
+                                return log_oom();
+
+                        cmd = strdup(rules_str(rules, cur->key.value_off));
+                        if (!cmd)
+                                return log_oom();
+
+                        r = hashmap_put(event->run_list, cmd, INT_TO_PTR(cur->key.builtin_cmd));
+                        if (r < 0)
+                                return log_oom();
+
+                        cmd = NULL;
 
-                        if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
-                                udev_list_cleanup(&event->run_list);
                         log_debug("RUN '%s' %s:%u",
                                   rules_str(rules, cur->key.value_off),
                                   rules_str(rules, rule->rule.filename_off),
                                   rule->rule.filename_line);
-                        entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL);
-                        udev_list_entry_set_num(entry, cur->key.builtin_cmd);
                         break;
                 }
                 case TK_A_GOTO:
index afdd876..d5336ab 100644 (file)
@@ -30,7 +30,7 @@ struct udev_event {
         uid_t uid;
         gid_t gid;
         Hashmap *seclabel_list;
-        struct udev_list run_list;
+        Hashmap *run_list;
         int exec_delay;
         usec_t birth_usec;
         sd_netlink *rtnl;
index d2868d1..ea6471b 100644 (file)
@@ -92,6 +92,9 @@ int test_main(int argc, char *argv[], void *userdata) {
         _cleanup_(udev_event_unrefp) struct udev_event *event = NULL;
         struct udev_list_entry *entry;
         sigset_t mask, sigmask_orig;
+        const char *cmd;
+        Iterator i;
+        void *val;
         int r;
 
         log_set_max_level(LOG_DEBUG);
@@ -138,10 +141,10 @@ int test_main(int argc, char *argv[], void *userdata) {
         udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
                 printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
 
-        udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
+        HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
                 char program[UTIL_PATH_SIZE];
 
-                udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false);
+                udev_event_apply_format(event, cmd, program, sizeof(program), false);
                 printf("run: '%s'\n", program);
         }