chiark / gitweb /
test: add RUN+="socket: ..." to a test to run monitor code
[elogind.git] / udev / udevd.c
index 5388961c42d468646bab1b4050eecedf1a8ca2e9..0bacb3994b00a716fa2af15aaaa64af7391fa4c5 100644 (file)
@@ -58,7 +58,7 @@ static void log_fn(struct udev *udev, int priority,
 }
 
 static int debug_trace;
-static struct udev_rules rules;
+static struct udev_rules *rules;
 static struct udev_ctrl *udev_ctrl;
 static struct udev_monitor *kernel_monitor;
 static int inotify_fd = -1;
@@ -108,9 +108,9 @@ static void export_event_state(struct udev_event *event, enum event_state state)
 
        switch (state) {
        case EVENT_QUEUED:
-               unlink(filename_failed);
-               delete_path(event->udev, filename_failed);
-               create_path(event->udev, filename);
+               if(unlink(filename_failed) == 0)
+                       util_delete_path(event->udev, filename_failed);
+               util_create_path(event->udev, filename);
                udev_selinux_setfscreatecon(event->udev, filename, S_IFLNK);
                symlink(udev_device_get_devpath(event->dev), filename);
                udev_selinux_resetfscreatecon(event->udev);
@@ -130,20 +130,24 @@ static void export_event_state(struct udev_event *event, enum event_state state)
                                info(event->udev, "renamed devpath, moved failed state of '%s' to %s'\n",
                                     udev_device_get_devpath_old(event->dev), udev_device_get_devpath(event->dev));
                } else {
-                       unlink(filename_failed);
-                       delete_path(event->udev, filename_failed);
+                       if (unlink(filename_failed) == 0)
+                               util_delete_path(event->udev, filename_failed);
                }
 
                unlink(filename);
-               delete_path(event->udev, filename);
+
+               /* clean up possibly empty queue directory */
+               if (udev_list_is_empty(&exec_list) && udev_list_is_empty(&running_list))
+                       util_delete_path(event->udev, filename);
                break;
        case EVENT_FAILED:
                /* move failed event to the failed directory */
-               create_path(event->udev, filename_failed);
+               util_create_path(event->udev, filename_failed);
                rename(filename, filename_failed);
 
                /* clean up possibly empty queue directory */
-               delete_path(event->udev, filename);
+               if (udev_list_is_empty(&exec_list) && udev_list_is_empty(&running_list))
+                       util_delete_path(event->udev, filename);
                break;
        }
 
@@ -208,7 +212,7 @@ static void event_fork(struct udev_event *event)
                alarm(UDEV_EVENT_TIMEOUT);
 
                /* apply rules, create node, symlinks */
-               err = udev_event_run(event, &rules);
+               err = udev_event_execute_rules(event, rules);
 
                /* rules may change/disable the timeout */
                if (udev_device_get_event_timeout(event->dev) >= 0)
@@ -216,7 +220,7 @@ static void event_fork(struct udev_event *event)
 
                /* execute RUN= */
                if (err == 0 && !event->ignore_device && udev_get_run(event->udev))
-                       udev_rules_run(event);
+                       udev_event_execute_run(event);
                info(event->udev, "seq %llu exit with %i\n", udev_device_get_seqnum(event->dev), err);
                logging_close();
                if (err != 0)
@@ -306,26 +310,24 @@ static int mem_size_mb(void)
 
 static int compare_devpath(const char *running, const char *waiting)
 {
-       int i;
+       int i = 0;
 
-       for (i = 0; i < UTIL_PATH_SIZE; i++) {
-               /* identical device event found */
-               if (running[i] == '\0' && waiting[i] == '\0')
-                       return 1;
+       while (running[i] == waiting[i] && running[i] != '\0')
+               i++;
 
-               /* parent device event found */
-               if (running[i] == '\0' && waiting[i] == '/')
-                       return 2;
+       /* identical device event found */
+       if (running[i] == '\0' && waiting[i] == '\0')
+               return 1;
 
-               /* child device event found */
-               if (running[i] == '/' && waiting[i] == '\0')
-                       return 3;
+       /* parent device event found */
+       if (running[i] == '\0' && waiting[i] == '/')
+               return 2;
 
-               /* no matching event */
-               if (running[i] != waiting[i])
-                       break;
-       }
+       /* child device event found */
+       if (running[i] == '/' && waiting[i] == '\0')
+               return 3;
 
+       /* no matching event */
        return 0;
 }
 
@@ -609,7 +611,7 @@ static void export_initial_seqnum(struct udev *udev)
        }
        util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
        util_strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename));
-       create_path(udev, filename);
+       util_create_path(udev, filename);
        fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0644);
        if (fd >= 0) {
                write(fd, seqnum, len);
@@ -644,7 +646,7 @@ int main(int argc, char *argv[])
        logging_init("udevd");
        udev_set_log_fn(udev, log_fn);
        info(udev, "version %s\n", VERSION);
-       selinux_init(udev);
+       udev_selinux_init(udev);
 
        while (1) {
                int option;
@@ -748,9 +750,13 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
+       rules = udev_rules_new(udev, 1);
+       if (rules == NULL) {
+               err(udev, "error reading rules\n");
+               goto exit;
+       }
        udev_list_init(&running_list);
        udev_list_init(&exec_list);
-       udev_rules_init(udev, &rules, 1);
        export_initial_seqnum(udev);
 
        if (daemonize) {
@@ -934,9 +940,14 @@ int main(int argc, char *argv[])
 
                /* rules changed, set by inotify or a HUP signal */
                if (reload_config) {
+                       struct udev_rules *rules_new;
+
                        reload_config = 0;
-                       udev_rules_cleanup(&rules);
-                       udev_rules_init(udev, &rules, 1);
+                       rules_new = udev_rules_new(udev, 1);
+                       if (rules_new != NULL) {
+                               udev_rules_unref(rules);
+                               rules = rules_new;
+                       }
                }
 
                if (sigchilds_waiting) {
@@ -953,7 +964,7 @@ int main(int argc, char *argv[])
        rc = 0;
 
 exit:
-       udev_rules_cleanup(&rules);
+       udev_rules_unref(rules);
 
        if (signal_pipe[READ_END] >= 0)
                close(signal_pipe[READ_END]);
@@ -965,7 +976,7 @@ exit:
                close(inotify_fd);
        udev_monitor_unref(kernel_monitor);
 
-       selinux_exit(udev);
+       udev_selinux_exit(udev);
        udev_unref(udev);
        logging_close();
        return rc;