chiark / gitweb /
split up long line
[elogind.git] / udev / udevd.c
index bc6484b1b0b55a17c6dc51e06313515dc8e1e715..7e87068068ae9409ff915629bfca7f6d6df700a1 100644 (file)
@@ -59,6 +59,8 @@ static void log_fn(struct udev *udev, int priority,
        }
 }
 
+static void reap_sigchilds(void);
+
 static int debug_trace;
 static struct udev_rules *rules;
 static struct udev_ctrl *udev_ctrl;
@@ -403,6 +405,7 @@ static void event_queue_manager(struct udev *udev)
        struct udev_list_node *loop;
        struct udev_list_node *tmp;
 
+start_over:
        if (udev_list_is_empty(&event_list)) {
                if (childs > 0) {
                        err(udev, "event list empty, but childs count is %i", childs);
@@ -432,6 +435,13 @@ static void event_queue_manager(struct udev *udev)
 
                event_fork(loop_event);
                dbg(udev, "moved seq %llu to running list\n", udev_device_get_seqnum(loop_event->dev));
+
+               /* retry if events finished in the meantime */
+               if (sigchilds_waiting) {
+                       sigchilds_waiting = 0;
+                       reap_sigchilds();
+                       goto start_over;
+               }
        }
 }
 
@@ -635,12 +645,14 @@ int main(int argc, char *argv[])
        struct sigaction act;
        const char *value;
        int daemonize = 0;
+       int resolve_names = 1;
        static const struct option options[] = {
                { "daemon", no_argument, NULL, 'd' },
                { "debug-trace", no_argument, NULL, 't' },
                { "debug", no_argument, NULL, 'D' },
                { "help", no_argument, NULL, 'h' },
                { "version", no_argument, NULL, 'V' },
+               { "resolve-names", required_argument, NULL, 'N' },
                {}
        };
        int rc = 1;
@@ -673,8 +685,22 @@ int main(int argc, char *argv[])
                        if (udev_get_log_priority(udev) < LOG_INFO)
                                udev_set_log_priority(udev, LOG_INFO);
                        break;
+               case 'N':
+                       if (strcmp (optarg, "early") == 0) {
+                               resolve_names = 1;
+                       } else if (strcmp (optarg, "late") == 0) {
+                               resolve_names = 0;
+                       } else if (strcmp (optarg, "never") == 0) {
+                               resolve_names = -1;
+                       } else {
+                               fprintf(stderr, "resolve-names must be early, late or never\n");
+                               err(udev, "resolve-names must be early, late or never\n");
+                               goto exit;
+                       }
+                       break;
                case 'h':
-                       printf("Usage: udevd [--help] [--daemon] [--debug-trace] [--debug] [--version]\n");
+                       printf("Usage: udevd [--help] [--daemon] [--debug-trace] [--debug] "
+                              "[--resolve-names=early|late|never] [--version]\n");
                        goto exit;
                case 'V':
                        printf("%s\n", VERSION);
@@ -726,7 +752,7 @@ int main(int argc, char *argv[])
        }
        udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
 
-       rules = udev_rules_new(udev, 1);
+       rules = udev_rules_new(udev, resolve_names);
        if (rules == NULL) {
                err(udev, "error reading rules\n");
                goto exit;
@@ -853,9 +879,10 @@ int main(int argc, char *argv[])
 
        while (!udev_exit) {
                sigset_t blocked_mask, orig_mask;
+               struct pollfd pfd[4];
                struct pollfd *ctrl_poll, *monitor_poll, *inotify_poll = NULL;
-               struct pollfd pfd[10];
-               int fdcount, nfds = 0;
+               int nfds = 0;
+               int fdcount;
 
                sigfillset(&blocked_mask);
                sigprocmask(SIG_SETMASK, &blocked_mask, &orig_mask);
@@ -864,19 +891,22 @@ int main(int argc, char *argv[])
                        goto handle_signals;
                }
 
-#define POLL_FOR(__desc, __pollptr) do { \
-       pfd[nfds].fd = (__desc); pfd[nfds].events = POLLIN; \
-       __pollptr = &pfd[nfds++]; \
-} while (0)
-               POLL_FOR(udev_ctrl_get_fd(udev_ctrl), ctrl_poll);
-               POLL_FOR(udev_monitor_get_fd(kernel_monitor), monitor_poll);
-               if (inotify_fd >= 0)
-                       POLL_FOR(inotify_fd, inotify_poll);
-#undef POLL_FOR
+               ctrl_poll = &pfd[nfds++];
+               ctrl_poll->fd = udev_ctrl_get_fd(udev_ctrl);
+               ctrl_poll->events = POLLIN;
+
+               monitor_poll = &pfd[nfds++];
+               monitor_poll->fd = udev_monitor_get_fd(kernel_monitor);
+               monitor_poll->events = POLLIN;
+
+               if (inotify_fd >= 0) {
+                       inotify_poll = &pfd[nfds++];
+                       inotify_poll->fd = inotify_fd;
+                       inotify_poll->events = POLLIN;
+               }
 
                fdcount = ppoll(pfd, nfds, NULL, &orig_mask);
                sigprocmask(SIG_SETMASK, &orig_mask, NULL);
-
                if (fdcount < 0) {
                        if (errno == EINTR)
                                goto handle_signals;
@@ -932,7 +962,7 @@ handle_signals:
                        struct udev_rules *rules_new;
 
                        reload_config = 0;
-                       rules_new = udev_rules_new(udev, 1);
+                       rules_new = udev_rules_new(udev, resolve_names);
                        if (rules_new != NULL) {
                                udev_rules_unref(rules);
                                rules = rules_new;