diff options
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/InitLLVM.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Signals.inc | 24 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Signals.inc | 7 |
3 files changed, 32 insertions, 5 deletions
diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp index 0d7d7fcc8cb..bb9b569d2de 100644 --- a/llvm/lib/Support/InitLLVM.cpp +++ b/llvm/lib/Support/InitLLVM.cpp @@ -21,7 +21,11 @@ using namespace llvm; using namespace llvm::sys; -InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) { +InitLLVM::InitLLVM(int &Argc, const char **&Argv, + bool InstallPipeSignalExitHandler) + : StackPrinter(Argc, Argv) { + if (InstallPipeSignalExitHandler) + sys::SetOneShotPipeSignalFunction(sys::DefaultOneShotPipeSignalHandler); sys::PrintStackTraceOnErrorSignal(Argv[0]); install_out_of_memory_new_handler(); diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index be05eabfb2e..8c26fa9b8f2 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -88,6 +88,9 @@ static std::atomic<SignalHandlerFunctionType> InterruptFunction = ATOMIC_VAR_INIT(nullptr); static std::atomic<SignalHandlerFunctionType> InfoSignalFunction = ATOMIC_VAR_INIT(nullptr); +/// The function to call on SIGPIPE (one-time use only). +static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction = + ATOMIC_VAR_INIT(nullptr); namespace { /// Signal-safe removal of files. @@ -206,7 +209,7 @@ static StringRef Argv0; /// if there is, it's not our direct responsibility. For whatever reason, our /// continued execution is no longer desirable. static const int IntSigs[] = { - SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR2 + SIGHUP, SIGINT, SIGTERM, SIGUSR2 }; /// Signals that represent that we have a bug, and our prompt termination has @@ -237,7 +240,7 @@ static const int InfoSigs[] = { static const size_t NumSigs = array_lengthof(IntSigs) + array_lengthof(KillSigs) + - array_lengthof(InfoSigs); + array_lengthof(InfoSigs) + 1 /* SIGPIPE */; static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0); @@ -322,6 +325,8 @@ static void RegisterHandlers() { // Not signal-safe. registerHandler(S, SignalKind::IsKill); for (auto S : KillSigs) registerHandler(S, SignalKind::IsKill); + if (OneShotPipeSignalFunction) + registerHandler(SIGPIPE, SignalKind::IsKill); for (auto S : InfoSigs) registerHandler(S, SignalKind::IsInfo); } @@ -361,9 +366,10 @@ static RETSIGTYPE SignalHandler(int Sig) { if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr)) return OldInterruptFunction(); - // Send a special return code that drivers can check for, from sysexits.h. if (Sig == SIGPIPE) - exit(EX_IOERR); + if (auto OldOneShotPipeFunction = + OneShotPipeSignalFunction.exchange(nullptr)) + return OldOneShotPipeFunction(); raise(Sig); // Execute the default handler. return; @@ -403,6 +409,16 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { RegisterHandlers(); } +void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { + OneShotPipeSignalFunction.exchange(Handler); + RegisterHandlers(); +} + +void llvm::sys::DefaultOneShotPipeSignalHandler() { + // Send a special return code that drivers can check for, from sysexits.h. + exit(EX_IOERR); +} + // The public API bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index 6a820ef22b1..08a3616427b 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -560,6 +560,13 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { // Unimplemented. } +void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { + // Unimplemented. +} + +void llvm::sys::DefaultOneShotPipeSignalHandler() { + // Unimplemented. +} /// Add a function to be called when a signal is delivered to the process. The /// handler can have a cookie passed to it to identify what instance of the |