aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-03-09 22:36:47 -0800
committerJade Lovelace <lix@jade.fyi>2024-03-11 00:52:09 -0700
commit8be7030299699edd3732411d8d97f237a67fbc08 (patch)
tree118f6c5c8dfac9ae9c65f54c5eb5942323324b17
parenta9b813cc3bcf89f03de0db96fc2e88d1c83b8303 (diff)
util.hh: split out signals stuff
Copies part of the changes of ac89bb064aeea85a62b82a6daf0ecca7190a28b7 Change-Id: I9ce601875cd6d4db5eb1132d7835c5bab9f126d8
-rw-r--r--src/libcmd/repl.cc1
-rw-r--r--src/libexpr/print-ambiguous.cc1
-rw-r--r--src/libexpr/print.cc1
-rw-r--r--src/libexpr/value-to-json.cc1
-rw-r--r--src/libexpr/value-to-xml.cc1
-rw-r--r--src/libmain/shared.cc1
-rw-r--r--src/libstore/binary-cache-store.cc1
-rw-r--r--src/libstore/build/substitution-goal.cc1
-rw-r--r--src/libstore/build/worker.cc1
-rw-r--r--src/libstore/filetransfer.cc1
-rw-r--r--src/libstore/gc.cc1
-rw-r--r--src/libstore/local-store.cc1
-rw-r--r--src/libstore/optimise-store.cc1
-rw-r--r--src/libstore/pathlocks.cc1
-rw-r--r--src/libstore/remote-store.cc1
-rw-r--r--src/libstore/sqlite.cc1
-rw-r--r--src/libstore/store-api.cc1
-rw-r--r--src/libutil/archive.cc1
-rw-r--r--src/libutil/compression.cc1
-rw-r--r--src/libutil/filesystem.cc1
-rw-r--r--src/libutil/monitor-fd.hh2
-rw-r--r--src/libutil/serialise.cc1
-rw-r--r--src/libutil/signals.cc184
-rw-r--r--src/libutil/signals.hh93
-rw-r--r--src/libutil/thread-pool.cc1
-rw-r--r--src/libutil/util.cc179
-rw-r--r--src/libutil/util.hh76
-rw-r--r--src/nix-collect-garbage/nix-collect-garbage.cc1
-rw-r--r--src/nix/daemon.cc1
-rw-r--r--src/nix/optimise-store.cc1
-rw-r--r--src/nix/sigs.cc1
-rw-r--r--src/nix/verify.cc1
32 files changed, 310 insertions, 251 deletions
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 20567f840..5268ce44b 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -40,6 +40,7 @@ extern "C" {
#include "finally.hh"
#include "markdown.hh"
#include "local-fs-store.hh"
+#include "signals.hh"
#include "print.hh"
#if HAVE_BOEHMGC
diff --git a/src/libexpr/print-ambiguous.cc b/src/libexpr/print-ambiguous.cc
index 5355dff65..eaba02122 100644
--- a/src/libexpr/print-ambiguous.cc
+++ b/src/libexpr/print-ambiguous.cc
@@ -1,6 +1,7 @@
#include "print-ambiguous.hh"
#include "print.hh"
#include "eval.hh"
+#include "signals.hh"
namespace nix {
diff --git a/src/libexpr/print.cc b/src/libexpr/print.cc
index df79718fb..7ef21dfa9 100644
--- a/src/libexpr/print.cc
+++ b/src/libexpr/print.cc
@@ -5,6 +5,7 @@
#include "ansicolor.hh"
#include "store-api.hh"
#include "english.hh"
+#include "signals.hh"
#include "eval.hh"
namespace nix {
diff --git a/src/libexpr/value-to-json.cc b/src/libexpr/value-to-json.cc
index 787a46426..ebb3379a8 100644
--- a/src/libexpr/value-to-json.cc
+++ b/src/libexpr/value-to-json.cc
@@ -1,6 +1,7 @@
#include "value-to-json.hh"
#include "eval-inline.hh"
#include "util.hh"
+#include "signals.hh"
#include "store-api.hh"
#include <cstdlib>
diff --git a/src/libexpr/value-to-xml.cc b/src/libexpr/value-to-xml.cc
index 2539ad1c1..5d1fbd28d 100644
--- a/src/libexpr/value-to-xml.cc
+++ b/src/libexpr/value-to-xml.cc
@@ -2,6 +2,7 @@
#include "xml-writer.hh"
#include "eval-inline.hh"
#include "util.hh"
+#include "signals.hh"
#include <cstdlib>
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 4ad1faec3..6d851d776 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -3,6 +3,7 @@
#include "store-api.hh"
#include "gc-store.hh"
#include "util.hh"
+#include "signals.hh"
#include "loggers.hh"
#include "progress-bar.hh"
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index b4fea693f..2e1f84859 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -10,6 +10,7 @@
#include "nar-info-disk-cache.hh"
#include "nar-accessor.hh"
#include "thread-pool.hh"
+#include "signals.hh"
#include "callback.hh"
#include <chrono>
diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc
index e77772f96..d8d9ba283 100644
--- a/src/libstore/build/substitution-goal.cc
+++ b/src/libstore/build/substitution-goal.cc
@@ -1,6 +1,7 @@
#include "worker.hh"
#include "substitution-goal.hh"
#include "nar-info.hh"
+#include "signals.hh"
#include "finally.hh"
namespace nix {
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc
index d6bcba3ff..83167b0f3 100644
--- a/src/libstore/build/worker.cc
+++ b/src/libstore/build/worker.cc
@@ -3,6 +3,7 @@
#include "substitution-goal.hh"
#include "drv-output-substitution-goal.hh"
#include "local-derivation-goal.hh"
+#include "signals.hh"
#include "hook-instance.hh"
#include <poll.h>
diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc
index 0d09fff98..5664579e7 100644
--- a/src/libstore/filetransfer.cc
+++ b/src/libstore/filetransfer.cc
@@ -3,6 +3,7 @@
#include "globals.hh"
#include "store-api.hh"
#include "s3.hh"
+#include "signals.hh"
#include "compression.hh"
#include "finally.hh"
#include "callback.hh"
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index ac61f7f53..bd9be52f3 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -1,6 +1,7 @@
#include "derivations.hh"
#include "globals.hh"
#include "local-store.hh"
+#include "signals.hh"
#include "finally.hh"
#include <functional>
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 78ca79c89..ecaab8f37 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -8,6 +8,7 @@
#include "references.hh"
#include "callback.hh"
#include "topo-sort.hh"
+#include "signals.hh"
#include "finally.hh"
#include "compression.hh"
diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc
index 4a79cf4a1..e09072e90 100644
--- a/src/libstore/optimise-store.cc
+++ b/src/libstore/optimise-store.cc
@@ -1,6 +1,7 @@
#include "util.hh"
#include "local-store.hh"
#include "globals.hh"
+#include "signals.hh"
#include <cstdlib>
#include <cstring>
diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc
index adc763e6a..955ae3a34 100644
--- a/src/libstore/pathlocks.cc
+++ b/src/libstore/pathlocks.cc
@@ -1,5 +1,6 @@
#include "pathlocks.hh"
#include "util.hh"
+#include "signals.hh"
#include "sync.hh"
#include <cerrno>
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index 58fac40dc..7572473cf 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -1,5 +1,6 @@
#include "serialise.hh"
#include "util.hh"
+#include "signals.hh"
#include "path-with-outputs.hh"
#include "gc-store.hh"
#include "remote-fs-accessor.hh"
diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc
index 365794bd3..4bd425b46 100644
--- a/src/libstore/sqlite.cc
+++ b/src/libstore/sqlite.cc
@@ -1,6 +1,7 @@
#include "sqlite.hh"
#include "globals.hh"
#include "util.hh"
+#include "signals.hh"
#include "url.hh"
#include <sqlite3.h>
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 9a6c920f7..94202d46e 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -11,6 +11,7 @@
#include "archive.hh"
#include "callback.hh"
#include "remote-store.hh"
+#include "signals.hh"
// FIXME this should not be here, see TODO below on
// `addMultipleToStore`.
#include "worker-protocol.hh"
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc
index ce10a35ae..e3ff7345f 100644
--- a/src/libutil/archive.cc
+++ b/src/libutil/archive.cc
@@ -14,6 +14,7 @@
#include "archive.hh"
#include "util.hh"
#include "config.hh"
+#include "signals.hh"
namespace nix {
diff --git a/src/libutil/compression.cc b/src/libutil/compression.cc
index ba0847cde..575a03712 100644
--- a/src/libutil/compression.cc
+++ b/src/libutil/compression.cc
@@ -2,6 +2,7 @@
#include "tarfile.hh"
#include "util.hh"
#include "finally.hh"
+#include "signals.hh"
#include "logging.hh"
#include <archive.h>
diff --git a/src/libutil/filesystem.cc b/src/libutil/filesystem.cc
index 2a7787c0e..ea934ffaf 100644
--- a/src/libutil/filesystem.cc
+++ b/src/libutil/filesystem.cc
@@ -4,6 +4,7 @@
#include "finally.hh"
#include "util.hh"
+#include "signals.hh"
#include "types.hh"
namespace fs = std::filesystem;
diff --git a/src/libutil/monitor-fd.hh b/src/libutil/monitor-fd.hh
index 86d0115fc..228fb13f8 100644
--- a/src/libutil/monitor-fd.hh
+++ b/src/libutil/monitor-fd.hh
@@ -10,6 +10,8 @@
#include <unistd.h>
#include <signal.h>
+#include "signals.hh"
+
namespace nix {
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index 3d9dcf728..692144b75 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -1,5 +1,6 @@
#include "serialise.hh"
#include "util.hh"
+#include "signals.hh"
#include <cstring>
#include <cerrno>
diff --git a/src/libutil/signals.cc b/src/libutil/signals.cc
new file mode 100644
index 000000000..f5c79b325
--- /dev/null
+++ b/src/libutil/signals.cc
@@ -0,0 +1,184 @@
+#include "signals.hh"
+#include "util.hh"
+#include "error.hh"
+#include "sync.hh"
+
+#include <thread>
+
+namespace nix {
+
+std::atomic<bool> _isInterrupted = false;
+
+static thread_local bool interruptThrown = false;
+thread_local std::function<bool()> interruptCheck;
+
+void setInterruptThrown()
+{
+ interruptThrown = true;
+}
+
+void _interrupted()
+{
+ /* Block user interrupts while an exception is being handled.
+ Throwing an exception while another exception is being handled
+ kills the program! */
+ if (!interruptThrown && !std::uncaught_exceptions()) {
+ interruptThrown = true;
+ throw Interrupted("interrupted by the user");
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+
+/* We keep track of interrupt callbacks using integer tokens, so we can iterate
+ safely without having to lock the data structure while executing arbitrary
+ functions.
+ */
+struct InterruptCallbacks {
+ typedef int64_t Token;
+
+ /* We use unique tokens so that we can't accidentally delete the wrong
+ handler because of an erroneous double delete. */
+ Token nextToken = 0;
+
+ /* Used as a list, see InterruptCallbacks comment. */
+ std::map<Token, std::function<void()>> callbacks;
+};
+
+static Sync<InterruptCallbacks> _interruptCallbacks;
+
+static void signalHandlerThread(sigset_t set)
+{
+ while (true) {
+ int signal = 0;
+ sigwait(&set, &signal);
+
+ if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
+ triggerInterrupt();
+
+ else if (signal == SIGWINCH) {
+ updateWindowSize();
+ }
+ }
+}
+
+void triggerInterrupt()
+{
+ _isInterrupted = true;
+
+ {
+ InterruptCallbacks::Token i = 0;
+ while (true) {
+ std::function<void()> callback;
+ {
+ auto interruptCallbacks(_interruptCallbacks.lock());
+ auto lb = interruptCallbacks->callbacks.lower_bound(i);
+ if (lb == interruptCallbacks->callbacks.end())
+ break;
+
+ callback = lb->second;
+ i = lb->first + 1;
+ }
+
+ try {
+ callback();
+ } catch (...) {
+ ignoreException();
+ }
+ }
+ }
+}
+
+static sigset_t savedSignalMask;
+static bool savedSignalMaskIsSet = false;
+
+void setChildSignalMask(sigset_t * sigs)
+{
+ assert(sigs); // C style function, but think of sigs as a reference
+
+#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
+ sigemptyset(&savedSignalMask);
+ // There's no "assign" or "copy" function, so we rely on (math) idempotence
+ // of the or operator: a or a = a.
+ sigorset(&savedSignalMask, sigs, sigs);
+#else
+ // Without sigorset, our best bet is to assume that sigset_t is a type that
+ // can be assigned directly, such as is the case for a sigset_t defined as
+ // an integer type.
+ savedSignalMask = *sigs;
+#endif
+
+ savedSignalMaskIsSet = true;
+}
+
+void saveSignalMask() {
+ if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask))
+ throw SysError("querying signal mask");
+
+ savedSignalMaskIsSet = true;
+}
+
+void startSignalHandlerThread()
+{
+ updateWindowSize();
+
+ saveSignalMask();
+
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGHUP);
+ sigaddset(&set, SIGPIPE);
+ sigaddset(&set, SIGWINCH);
+ if (pthread_sigmask(SIG_BLOCK, &set, nullptr))
+ throw SysError("blocking signals");
+
+ std::thread(signalHandlerThread, set).detach();
+}
+
+void restoreSignals()
+{
+ // If startSignalHandlerThread wasn't called, that means we're not running
+ // in a proper libmain process, but a process that presumably manages its
+ // own signal handlers. Such a process should call either
+ // - initNix(), to be a proper libmain process
+ // - startSignalHandlerThread(), to resemble libmain regarding signal
+ // handling only
+ // - saveSignalMask(), for processes that define their own signal handling
+ // thread
+ // TODO: Warn about this? Have a default signal mask? The latter depends on
+ // whether we should generally inherit signal masks from the caller.
+ // I don't know what the larger unix ecosystem expects from us here.
+ if (!savedSignalMaskIsSet)
+ return;
+
+ if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
+ throw SysError("restoring signals");
+}
+
+/* RAII helper to automatically deregister a callback. */
+struct InterruptCallbackImpl : InterruptCallback
+{
+ InterruptCallbacks::Token token;
+ ~InterruptCallbackImpl() override
+ {
+ auto interruptCallbacks(_interruptCallbacks.lock());
+ interruptCallbacks->callbacks.erase(token);
+ }
+};
+
+std::unique_ptr<InterruptCallback> createInterruptCallback(std::function<void()> callback)
+{
+ auto interruptCallbacks(_interruptCallbacks.lock());
+ auto token = interruptCallbacks->nextToken++;
+ interruptCallbacks->callbacks.emplace(token, callback);
+
+ auto res = std::make_unique<InterruptCallbackImpl>();
+ res->token = token;
+
+ return std::unique_ptr<InterruptCallback>(res.release());
+}
+
+};
diff --git a/src/libutil/signals.hh b/src/libutil/signals.hh
new file mode 100644
index 000000000..c58dc37cf
--- /dev/null
+++ b/src/libutil/signals.hh
@@ -0,0 +1,93 @@
+#pragma once
+/// @file
+
+#include "types.hh"
+#include "error.hh"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <atomic>
+#include <functional>
+#include <sstream>
+
+namespace nix {
+
+/* User interruption. */
+
+extern std::atomic<bool> _isInterrupted;
+
+extern thread_local std::function<bool()> interruptCheck;
+
+void setInterruptThrown();
+
+void _interrupted();
+
+void inline checkInterrupt()
+{
+ if (_isInterrupted || (interruptCheck && interruptCheck()))
+ _interrupted();
+}
+
+MakeError(Interrupted, BaseError);
+
+void restoreSignals();
+
+
+/**
+ * Start a thread that handles various signals. Also block those signals
+ * on the current thread (and thus any threads created by it).
+ * Saves the signal mask before changing the mask to block those signals.
+ * See saveSignalMask().
+ */
+void startSignalHandlerThread();
+
+/**
+ * Saves the signal mask, which is the signal mask that nix will restore
+ * before creating child processes.
+ * See setChildSignalMask() to set an arbitrary signal mask instead of the
+ * current mask.
+ */
+void saveSignalMask();
+
+/**
+ * Sets the signal mask. Like saveSignalMask() but for a signal set that doesn't
+ * necessarily match the current thread's mask.
+ * See saveSignalMask() to set the saved mask to the current mask.
+ */
+void setChildSignalMask(sigset_t *sigs);
+
+struct InterruptCallback
+{
+ virtual ~InterruptCallback() { };
+};
+
+/**
+ * Register a function that gets called on SIGINT (in a non-signal
+ * context).
+ */
+std::unique_ptr<InterruptCallback> createInterruptCallback(
+ std::function<void()> callback);
+
+void triggerInterrupt();
+
+/**
+ * A RAII class that causes the current thread to receive SIGUSR1 when
+ * the signal handler thread receives SIGINT. That is, this allows
+ * SIGINT to be multiplexed to multiple threads.
+ */
+struct ReceiveInterrupts
+{
+ pthread_t target;
+ std::unique_ptr<InterruptCallback> callback;
+
+ ReceiveInterrupts()
+ : target(pthread_self())
+ , callback(createInterruptCallback([&]() { pthread_kill(target, SIGUSR1); }))
+ { }
+};
+
+};
diff --git a/src/libutil/thread-pool.cc b/src/libutil/thread-pool.cc
index 6513234ba..c6ffa75f2 100644
--- a/src/libutil/thread-pool.cc
+++ b/src/libutil/thread-pool.cc
@@ -1,4 +1,5 @@
#include "thread-pool.hh"
+#include "signals.hh"
namespace nix {
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 007ec8bef..9bb769fc2 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -3,6 +3,7 @@
#include "finally.hh"
#include "serialise.hh"
#include "cgroup.hh"
+#include "signals.hh"
#include <array>
#include <cctype>
@@ -1361,31 +1362,6 @@ void closeOnExec(int fd)
//////////////////////////////////////////////////////////////////////
-std::atomic<bool> _isInterrupted = false;
-
-static thread_local bool interruptThrown = false;
-thread_local std::function<bool()> interruptCheck;
-
-void setInterruptThrown()
-{
- interruptThrown = true;
-}
-
-void _interrupted()
-{
- /* Block user interrupts while an exception is being handled.
- Throwing an exception while another exception is being handled
- kills the program! */
- if (!interruptThrown && !std::uncaught_exceptions()) {
- interruptThrown = true;
- throw Interrupted("interrupted by the user");
- }
-}
-
-
-//////////////////////////////////////////////////////////////////////
-
-
template<class C> C tokenizeString(std::string_view s, std::string_view separators)
{
C result;
@@ -1717,7 +1693,7 @@ std::pair<std::string_view, std::string_view> getLine(std::string_view s)
static Sync<std::pair<unsigned short, unsigned short>> windowSize{{0, 0}};
-static void updateWindowSize()
+void updateWindowSize()
{
struct winsize ws;
if (ioctl(2, TIOCGWINSZ, &ws) == 0) {
@@ -1734,133 +1710,6 @@ std::pair<unsigned short, unsigned short> getWindowSize()
}
-/* We keep track of interrupt callbacks using integer tokens, so we can iterate
- safely without having to lock the data structure while executing arbitrary
- functions.
- */
-struct InterruptCallbacks {
- typedef int64_t Token;
-
- /* We use unique tokens so that we can't accidentally delete the wrong
- handler because of an erroneous double delete. */
- Token nextToken = 0;
-
- /* Used as a list, see InterruptCallbacks comment. */
- std::map<Token, std::function<void()>> callbacks;
-};
-
-static Sync<InterruptCallbacks> _interruptCallbacks;
-
-static void signalHandlerThread(sigset_t set)
-{
- while (true) {
- int signal = 0;
- sigwait(&set, &signal);
-
- if (signal == SIGINT || signal == SIGTERM || signal == SIGHUP)
- triggerInterrupt();
-
- else if (signal == SIGWINCH) {
- updateWindowSize();
- }
- }
-}
-
-void triggerInterrupt()
-{
- _isInterrupted = true;
-
- {
- InterruptCallbacks::Token i = 0;
- while (true) {
- std::function<void()> callback;
- {
- auto interruptCallbacks(_interruptCallbacks.lock());
- auto lb = interruptCallbacks->callbacks.lower_bound(i);
- if (lb == interruptCallbacks->callbacks.end())
- break;
-
- callback = lb->second;
- i = lb->first + 1;
- }
-
- try {
- callback();
- } catch (...) {
- ignoreException();
- }
- }
- }
-}
-
-static sigset_t savedSignalMask;
-static bool savedSignalMaskIsSet = false;
-
-void setChildSignalMask(sigset_t * sigs)
-{
- assert(sigs); // C style function, but think of sigs as a reference
-
-#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
- sigemptyset(&savedSignalMask);
- // There's no "assign" or "copy" function, so we rely on (math) idempotence
- // of the or operator: a or a = a.
- sigorset(&savedSignalMask, sigs, sigs);
-#else
- // Without sigorset, our best bet is to assume that sigset_t is a type that
- // can be assigned directly, such as is the case for a sigset_t defined as
- // an integer type.
- savedSignalMask = *sigs;
-#endif
-
- savedSignalMaskIsSet = true;
-}
-
-void saveSignalMask() {
- if (sigprocmask(SIG_BLOCK, nullptr, &savedSignalMask))
- throw SysError("querying signal mask");
-
- savedSignalMaskIsSet = true;
-}
-
-void startSignalHandlerThread()
-{
- updateWindowSize();
-
- saveSignalMask();
-
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, SIGINT);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGHUP);
- sigaddset(&set, SIGPIPE);
- sigaddset(&set, SIGWINCH);
- if (pthread_sigmask(SIG_BLOCK, &set, nullptr))
- throw SysError("blocking signals");
-
- std::thread(signalHandlerThread, set).detach();
-}
-
-static void restoreSignals()
-{
- // If startSignalHandlerThread wasn't called, that means we're not running
- // in a proper libmain process, but a process that presumably manages its
- // own signal handlers. Such a process should call either
- // - initNix(), to be a proper libmain process
- // - startSignalHandlerThread(), to resemble libmain regarding signal
- // handling only
- // - saveSignalMask(), for processes that define their own signal handling
- // thread
- // TODO: Warn about this? Have a default signal mask? The latter depends on
- // whether we should generally inherit signal masks from the caller.
- // I don't know what the larger unix ecosystem expects from us here.
- if (!savedSignalMaskIsSet)
- return;
-
- if (sigprocmask(SIG_SETMASK, &savedSignalMask, nullptr))
- throw SysError("restoring signals");
-}
-
rlim_t savedStackSize = 0;
void setStackSize(rlim_t stackSize)
@@ -1951,30 +1800,6 @@ void restoreProcessContext(bool restoreMounts)
}
}
-/* RAII helper to automatically deregister a callback. */
-struct InterruptCallbackImpl : InterruptCallback
-{
- InterruptCallbacks::Token token;
- ~InterruptCallbackImpl() override
- {
- auto interruptCallbacks(_interruptCallbacks.lock());
- interruptCallbacks->callbacks.erase(token);
- }
-};
-
-std::unique_ptr<InterruptCallback> createInterruptCallback(std::function<void()> callback)
-{
- auto interruptCallbacks(_interruptCallbacks.lock());
- auto token = interruptCallbacks->nextToken++;
- interruptCallbacks->callbacks.emplace(token, callback);
-
- auto res = std::make_unique<InterruptCallbackImpl>();
- res->token = token;
-
- return std::unique_ptr<InterruptCallback>(res.release());
-}
-
-
AutoCloseFD createUnixDomainSocket()
{
AutoCloseFD fdSocket = socket(PF_UNIX, SOCK_STREAM
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index acd77ee33..ed4c8705a 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -516,25 +516,6 @@ void closeMostFDs(const std::set<int> & exceptions);
void closeOnExec(int fd);
-/* User interruption. */
-
-extern std::atomic<bool> _isInterrupted;
-
-extern thread_local std::function<bool()> interruptCheck;
-
-void setInterruptThrown();
-
-void _interrupted();
-
-void inline checkInterrupt()
-{
- if (_isInterrupted || (interruptCheck && interruptCheck()))
- _interrupted();
-}
-
-MakeError(Interrupted, BaseError);
-
-
MakeError(FormatError, Error);
@@ -830,61 +811,6 @@ class Callback;
/**
- * Start a thread that handles various signals. Also block those signals
- * on the current thread (and thus any threads created by it).
- * Saves the signal mask before changing the mask to block those signals.
- * See saveSignalMask().
- */
-void startSignalHandlerThread();
-
-/**
- * Saves the signal mask, which is the signal mask that nix will restore
- * before creating child processes.
- * See setChildSignalMask() to set an arbitrary signal mask instead of the
- * current mask.
- */
-void saveSignalMask();
-
-/**
- * Sets the signal mask. Like saveSignalMask() but for a signal set that doesn't
- * necessarily match the current thread's mask.
- * See saveSignalMask() to set the saved mask to the current mask.
- */
-void setChildSignalMask(sigset_t *sigs);
-
-struct InterruptCallback
-{
- virtual ~InterruptCallback() { };
-};
-
-/**
- * Register a function that gets called on SIGINT (in a non-signal
- * context).
- */
-std::unique_ptr<InterruptCallback> createInterruptCallback(
- std::function<void()> callback);
-
-void triggerInterrupt();
-
-/**
- * A RAII class that causes the current thread to receive SIGUSR1 when
- * the signal handler thread receives SIGINT. That is, this allows
- * SIGINT to be multiplexed to multiple threads.
- */
-struct ReceiveInterrupts
-{
- pthread_t target;
- std::unique_ptr<InterruptCallback> callback;
-
- ReceiveInterrupts()
- : target(pthread_self())
- , callback(createInterruptCallback([&]() { pthread_kill(target, SIGUSR1); }))
- { }
-};
-
-
-
-/**
* A RAII helper that increments a counter on construction and
* decrements it on destruction.
*/
@@ -903,6 +829,8 @@ struct MaintainCount
*/
std::pair<unsigned short, unsigned short> getWindowSize();
+void updateWindowSize();
+
/**
* Used in various places.
diff --git a/src/nix-collect-garbage/nix-collect-garbage.cc b/src/nix-collect-garbage/nix-collect-garbage.cc
index 70af53b28..1cbba0537 100644
--- a/src/nix-collect-garbage/nix-collect-garbage.cc
+++ b/src/nix-collect-garbage/nix-collect-garbage.cc
@@ -5,6 +5,7 @@
#include "shared.hh"
#include "globals.hh"
#include "legacy.hh"
+#include "signals.hh"
#include <iostream>
#include <cerrno>
diff --git a/src/nix/daemon.cc b/src/nix/daemon.cc
index f2eea2cf4..42ce3b996 100644
--- a/src/nix/daemon.cc
+++ b/src/nix/daemon.cc
@@ -12,6 +12,7 @@
#include "derivations.hh"
#include "finally.hh"
#include "legacy.hh"
+#include "signals.hh"
#include "daemon.hh"
#include <algorithm>
diff --git a/src/nix/optimise-store.cc b/src/nix/optimise-store.cc
index 985006e5a..6d7d928bd 100644
--- a/src/nix/optimise-store.cc
+++ b/src/nix/optimise-store.cc
@@ -1,5 +1,6 @@
#include "command.hh"
#include "shared.hh"
+#include "signals.hh"
#include "store-api.hh"
#include <atomic>
diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc
index 45cd2e1a6..730aa6532 100644
--- a/src/nix/sigs.cc
+++ b/src/nix/sigs.cc
@@ -2,6 +2,7 @@
#include "shared.hh"
#include "store-api.hh"
#include "thread-pool.hh"
+#include "signals.hh"
#include <atomic>
diff --git a/src/nix/verify.cc b/src/nix/verify.cc
index 0b306cc11..9be4c25dc 100644
--- a/src/nix/verify.cc
+++ b/src/nix/verify.cc
@@ -3,6 +3,7 @@
#include "store-api.hh"
#include "sync.hh"
#include "thread-pool.hh"
+#include "signals.hh"
#include "references.hh"
#include <atomic>