- /* read current udev seqnum */
- strlcpy(filename, udev_get_dev_path(udev), 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, "udev seqnum = %llu\n", seq_udev);
-
- /* read current kernel seqnum */
- strlcpy(filename, udev_get_sys_path(udev), 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(udev, "kernel seqnum = %llu\n", seq_kernel);
-
- /* make sure all kernel events have arrived in the queue */
- if (seq_udev >= seq_kernel) {
- info(udev, "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);
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ udev_ctrl_unref(uctrl);
+ }
+ }
+
+ while (1) {
+ if (start > 0) {
+ /* if asked for, wait for a specific sequence of events */
+ if (udev_queue_get_seqnum_sequence_is_finished(udev_queue, start, end) == 1) {
+ rc = 0;
+ break;
+ }
+ } else {
+ /* exit if queue is empty */
+ if (udev_queue_get_queue_is_empty(udev_queue)) {
+ rc = 0;
+ break;
+ }