about summary refs log tree commit diff
path: root/src/libutil/monitor-fd.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/monitor-fd.hh')
-rw-r--r--src/libutil/monitor-fd.hh43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/libutil/monitor-fd.hh b/src/libutil/monitor-fd.hh
new file mode 100644
index 000000000000..d8db6508aede
--- /dev/null
+++ b/src/libutil/monitor-fd.hh
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <thread>
+
+#include <poll.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+
+namespace nix {
+
+
+class MonitorFdHup
+{
+private:
+    std::thread thread;
+
+public:
+    MonitorFdHup(int fd)
+    {
+        thread = std::thread([&]() {
+            /* Wait indefinitely until a POLLHUP occurs. */
+            struct pollfd fds[1];
+            fds[0].fd = fd;
+            fds[0].events = 0;
+            if (poll(fds, 1, -1) == -1) {
+                if (errno != EINTR) abort(); // can't happen
+                return; // destructor is asking us to exit
+            }
+            /* We got POLLHUP, so send an INT signal to the main thread. */
+            kill(getpid(), SIGINT);
+        });
+    };
+
+    ~MonitorFdHup()
+    {
+        pthread_kill(thread.native_handle(), SIGINT);
+        thread.join();
+    }
+};
+
+
+}