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.hh42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/libutil/monitor-fd.hh b/src/libutil/monitor-fd.hh
new file mode 100644
index 000000000000..72d23fb6934c
--- /dev/null
+++ b/src/libutil/monitor-fd.hh
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <thread>
+#include <atomic>
+
+#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([fd]() {
+            /* Wait indefinitely until a POLLHUP occurs. */
+            struct pollfd fds[1];
+            fds[0].fd = fd;
+            fds[0].events = 0;
+            if (poll(fds, 1, -1) == -1) abort(); // can't happen
+            assert(fds[0].revents & POLLHUP);
+            /* We got POLLHUP, so send an INT signal to the main thread. */
+            kill(getpid(), SIGINT);
+        });
+    };
+
+    ~MonitorFdHup()
+    {
+        pthread_cancel(thread.native_handle());
+        thread.join();
+    }
+};
+
+
+}