aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 843a10eab..21d1c8dcd 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -47,6 +47,9 @@ extern char * * environ __attribute__((weak));
namespace nix {
+void initLibUtil() {
+}
+
std::optional<std::string> getEnv(const std::string & key)
{
char * value = getenv(key.c_str());
@@ -1744,14 +1747,40 @@ void triggerInterrupt()
}
static sigset_t savedSignalMask;
+static bool savedSignalMaskIsSet = false;
-void startSignalHandlerThread()
+void setChildSignalMask(sigset_t * sigs)
{
- updateWindowSize();
+ 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);
@@ -1767,6 +1796,20 @@ void startSignalHandlerThread()
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");
}