chiark / gitweb /
import: print nice warning if we need btrfs but /var/lib/machines is not btrfs
[elogind.git] / src / libudev / libudev-queue.c
index eb0e096f843f44cc0f57ef012bfe83aa35fbab95..11e15d13e62806014c494e97dfb57b5055c3bd3d 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <unistd.h>
 #include <errno.h>
-#include <string.h>
-#include <limits.h>
-#include <sys/stat.h>
+#include <sys/inotify.h>
 
-#include "libudev.h"
 #include "libudev-private.h"
 
 /**
@@ -45,6 +41,7 @@
 struct udev_queue {
         struct udev *udev;
         int refcount;
+        int fd;
 };
 
 /**
@@ -69,6 +66,7 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev)
 
         udev_queue->refcount = 1;
         udev_queue->udev = udev;
+        udev_queue->fd = -1;
         return udev_queue;
 }
 
@@ -107,6 +105,8 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
         if (udev_queue->refcount > 0)
                 return NULL;
 
+        safe_close(udev_queue->fd);
+
         free(udev_queue);
         return NULL;
 }
@@ -175,7 +175,7 @@ _public_ int udev_queue_get_udev_is_active(struct udev_queue *udev_queue)
  **/
 _public_ int udev_queue_get_queue_is_empty(struct udev_queue *udev_queue)
 {
-        return access("/run/udev/queue", F_OK) >= 0;
+        return access("/run/udev/queue", F_OK) < 0;
 }
 
 /**
@@ -222,3 +222,44 @@ _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_qu
 {
         return NULL;
 }
+
+/**
+ * udev_queue_get_fd:
+ * @udev_queue: udev queue context
+ *
+ * Returns: a file descriptor to watch for a queue to become empty.
+ */
+_public_ int udev_queue_get_fd(struct udev_queue *udev_queue) {
+        int fd;
+        int r;
+
+        if (udev_queue->fd >= 0)
+                return udev_queue->fd;
+
+        fd = inotify_init1(IN_CLOEXEC);
+        if (fd < 0)
+                return -errno;
+
+        r = inotify_add_watch(fd, "/run/udev" , IN_DELETE);
+        if (r < 0) {
+                r = -errno;
+                close(fd);
+                return r;
+        }
+
+        udev_queue->fd = fd;
+        return fd;
+}
+
+/**
+ * udev_queue_flush:
+ * @udev_queue: udev queue context
+ *
+ * Returns: the result of clearing the watch for queue changes.
+ */
+_public_ int udev_queue_flush(struct udev_queue *udev_queue) {
+        if (udev_queue->fd < 0)
+                return -EINVAL;
+
+        return flush_fd(udev_queue->fd);
+}