chiark / gitweb /
udevd: do not nice processes
[elogind.git] / udev / udevadm-settle.c
index 5030f18602c9e8a8bd3163b80f6b1f5379987157..38cb4f496845bf5fc9c18c7e97531cc53ee6d680 100644 (file)
 #include <getopt.h>
 #include <signal.h>
 #include <time.h>
+#include <sys/inotify.h>
+#include <sys/poll.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
 #include "udev.h"
 
-#define DEFAULT_TIMEOUT                        180
-#define LOOP_PER_SECOND                        20
-
 static volatile sig_atomic_t is_timeout;
 
 static void sig_handler(int signum)
@@ -44,8 +43,6 @@ static void sig_handler(int signum)
        switch (signum) {
                case SIGALRM:
                        is_timeout = 1;
-               case SIGUSR1:
-                       ;
        }
 }
 
@@ -64,8 +61,10 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[])
        unsigned long long end = 0;
        int quiet = 0;
        const char *exists = NULL;
-       int timeout = DEFAULT_TIMEOUT;
+       int timeout = 180;
+       struct pollfd pfd[1];
        struct sigaction act;
+       sigset_t mask;
        struct udev_queue *udev_queue = NULL;
        int rc = 1;
 
@@ -77,9 +76,11 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[])
        sigemptyset (&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGALRM, &act, NULL);
-       sigaction(SIGUSR1, &act, NULL);
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGALRM);
+       sigprocmask(SIG_UNBLOCK, &mask, NULL);
 
-       while (1) {
+       for (;;) {
                int option;
                int seconds;
 
@@ -163,22 +164,31 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[])
 
                uctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
                if (uctrl != NULL) {
-                       sigset_t mask, oldmask;
-
-                       sigemptyset(&mask);
-                       sigaddset(&mask, SIGUSR1);
-                       sigaddset(&mask, SIGALRM);
-                       sigprocmask(SIG_BLOCK, &mask, &oldmask);
-                       if (udev_ctrl_send_settle(uctrl) > 0)
-                               sigsuspend(&oldmask);
-                       sigprocmask(SIG_SETMASK, &oldmask, NULL);
+                       if (udev_ctrl_send_ping(uctrl, timeout) < 0) {
+                               info(udev, "no connection to daemon\n");
+                               udev_ctrl_unref(uctrl);
+                               rc = 0;
+                               goto out;
+                       }
                        udev_ctrl_unref(uctrl);
                }
        }
 
-       while (1) {
+       pfd[0].events = POLLIN;
+       pfd[0].fd = inotify_init1(IN_CLOEXEC);
+       if (pfd[0].fd < 0) {
+               err(udev, "inotify_init failed: %m\n");
+       } else {
+               if (inotify_add_watch(pfd[0].fd, udev_get_run_path(udev), IN_CLOSE_WRITE) < 0) {
+                       err(udev, "watching '%s' failed\n", udev_get_run_path(udev));
+                       close(pfd[0].fd);
+                       pfd[0].fd = -1;
+               }
+       }
+
+       for (;;) {
                struct stat statbuf;
-               const struct timespec duration = { 0 , 1000 * 1000 * 1000 / LOOP_PER_SECOND };
+               const struct timespec duration = { 1 , 0 };
 
                if (exists != NULL && stat(exists, &statbuf) == 0) {
                        rc = 0;
@@ -202,7 +212,16 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[])
                if (is_timeout)
                        break;
 
-               nanosleep(&duration, NULL);
+               if (pfd[0].fd >= 0) {
+                       /* wake up once every second, or whenever the queue file gets gets closed */
+                       if (poll(pfd, 1, 1000) > 0 && pfd[0].revents & POLLIN) {
+                               char buf[sizeof(struct inotify_event) + PATH_MAX];
+
+                               read(pfd[0].fd, buf, sizeof(buf));
+                       }
+               } else {
+                       nanosleep(&duration, NULL);
+               }
        }
 
        /* if we reached the timeout, print the list of remaining events */
@@ -218,7 +237,9 @@ int udevadm_settle(struct udev *udev, int argc, char *argv[])
                                       udev_list_entry_get_value(list_entry));
                }
        }
-
+out:
+       if (pfd[0].fd >= 0)
+               close(pfd[0].fd);
        udev_queue_unref(udev_queue);
        return rc;
 }