- /* read current udev seqnum */
- strlcpy(filename, udev_root, sizeof(filename));
- strlcat(filename, "/.udev/uevent_seqnum", sizeof(filename));
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto exit;
- len = read(fd, seqnum, sizeof(seqnum)-1);
- close(fd);
- if (len <= 0)
- goto exit;
- seqnum[len] = '\0';
- seq_udev = strtoull(seqnum, NULL, 10);
- info("udev seqnum = %llu\n", seq_udev);
-
- /* read current kernel seqnum */
- strlcpy(filename, sysfs_path, sizeof(filename));
- strlcat(filename, "/kernel/uevent_seqnum", sizeof(filename));
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto exit;
- len = read(fd, seqnum, sizeof(seqnum)-1);
- close(fd);
- if (len <= 0)
- goto exit;
- seqnum[len] = '\0';
- seq_kernel = strtoull(seqnum, NULL, 10);
- info("kernel seqnum = %llu\n", seq_kernel);
-
- /* make sure all kernel events have arrived in the queue */
- if (seq_udev >= seq_kernel) {
- info("queue is empty and no pending events left\n");
- rc = 0;
- goto exit;
+ /* guarantee that the udev daemon isn't pre-processing */
+ if (getuid() == 0) {
+ struct udev_ctrl *uctrl;
+
+ 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);
+ udev_ctrl_unref(uctrl);
+ }
+ }
+
+ while (!is_timeout) {
+ /* exit if queue is empty */
+ if (udev_queue_get_queue_is_empty(udev_queue))
+ break;
+
+ /* if asked for, wait for a specific sequence of events */
+ if (start > 0) {
+ unsigned long long seq;
+ int finished;
+
+ finished = 0;
+ for (seq = start; seq <= end; seq++) {
+ finished = udev_queue_get_seqnum_is_finished(udev_queue, seq);
+ if (!finished)
+ break;
+ }
+ if (finished)
+ break;