diff options
Diffstat (limited to 'src/libmain/shared.cc')
-rw-r--r-- | src/libmain/shared.cc | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 12f083c7f794..52cb2312826b 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -97,6 +97,9 @@ static void opensslLockCallback(int mode, int type, const char * file, int line) } +static void sigHandler(int signo) { } + + void initNix() { /* Turn on buffering for cerr. */ @@ -116,20 +119,18 @@ void initNix() startSignalHandlerThread(); - /* Ignore SIGPIPE. */ + /* Reset SIGCHLD to its default. */ struct sigaction act; sigemptyset(&act.sa_mask); - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - if (sigaction(SIGPIPE, &act, 0)) - throw SysError("ignoring SIGPIPE"); - - /* Reset SIGCHLD to its default. */ act.sa_handler = SIG_DFL; act.sa_flags = 0; if (sigaction(SIGCHLD, &act, 0)) throw SysError("resetting SIGCHLD"); + /* Install a dummy SIGUSR1 handler for use with pthread_kill(). */ + act.sa_handler = sigHandler; + if (sigaction(SIGUSR1, &act, 0)) throw SysError("handling SIGUSR1"); + /* Register a SIGSEGV handler to detect stack overflows. */ detectStackOverflow(); @@ -245,7 +246,7 @@ void printVersion(const string & programName) void showManPage(const string & name) { - restoreSIGPIPE(); + restoreSignals(); execlp("man", "man", name.c_str(), NULL); throw SysError(format("command ‘man %1%’ failed") % name.c_str()); } @@ -253,6 +254,8 @@ void showManPage(const string & name) int handleExceptions(const string & programName, std::function<void()> fun) { + ReceiveInterrupts receiveInterrupts; // FIXME: need better place for this + string error = ANSI_RED "error:" ANSI_NORMAL " "; try { try { @@ -296,16 +299,6 @@ RunPager::RunPager() if (!pager) pager = getenv("PAGER"); if (pager && ((string) pager == "" || (string) pager == "cat")) return; - /* Ignore SIGINT. The pager will handle it (and we'll get - SIGPIPE). */ - struct sigaction act; - act.sa_handler = SIG_IGN; - act.sa_flags = 0; - sigemptyset(&act.sa_mask); - if (sigaction(SIGINT, &act, 0)) throw SysError("ignoring SIGINT"); - - restoreSIGPIPE(); - Pipe toPager; toPager.create(); @@ -314,6 +307,7 @@ RunPager::RunPager() throw SysError("dupping stdin"); if (!getenv("LESS")) setenv("LESS", "FRSXMK", 1); + restoreSignals(); if (pager) execl("/bin/sh", "sh", "-c", pager, NULL); execlp("pager", "pager", NULL); @@ -322,6 +316,8 @@ RunPager::RunPager() throw SysError(format("executing ‘%1%’") % pager); }); + pid.setKillSignal(SIGINT); + if (dup2(toPager.writeSide.get(), STDOUT_FILENO) == -1) throw SysError("dupping stdout"); } @@ -336,7 +332,11 @@ RunPager::~RunPager() pid.wait(); } } catch (...) { - ignoreException(); + try { + pid.kill(true); + } catch (...) { + ignoreException(); + } } } |