From 9b2e01344022916bb37bd658148a7028a86ed0a8 Mon Sep 17 00:00:00 2001
From: loguru Upstream <kwrobot@kitware.com>
Date: Tue, 22 Aug 2023 14:06:00 -0400
Subject: [PATCH] loguru 2023-08-22 (b69cac88)

Code extracted from:

    https://gitlab.kitware.com/third-party/loguru.git

at commit b69cac8812da6b2a3a10ac83a401094787467cc2 (for/vtk-20230822-2.1.0).
---
 loguru.cpp | 80 ++++++++++++++++++++++++++++--------------------------
 loguru.hpp | 54 +++++++++++++++++++++++++++++++-----
 2 files changed, 89 insertions(+), 45 deletions(-)

diff --git a/loguru.cpp b/loguru.cpp
index 468675d5128..400a41da328 100644
--- a/loguru.cpp
+++ b/loguru.cpp
@@ -200,6 +200,8 @@ namespace loguru
 	static std::thread* s_flush_thread   = nullptr;
 	static bool         s_needs_flushing = false;
 
+	static SignalOptions s_signal_options = SignalOptions::none();
+
 	static const bool s_terminal_has_color = [](){
 		#ifdef _WIN32
 			#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
@@ -486,7 +488,7 @@ namespace loguru
 		flush();
 	}
 
-	static void install_signal_handlers(bool unsafe_signal_handler);
+	static void install_signal_handlers(const SignalOptions& signal_options);
 
 	static void write_hex_digit(std::string& out, unsigned num)
 	{
@@ -611,7 +613,7 @@ namespace loguru
 		VLOG_F(g_internal_verbosity, "stderr verbosity: " LOGURU_FMT(d) "", g_stderr_verbosity);
 		VLOG_F(g_internal_verbosity, "-----------------------------------");
 
-		install_signal_handlers(options.unsafe_signal_handler);
+		install_signal_handlers(options.signal_options);
 
 		atexit(on_atexit);
 	}
@@ -1310,9 +1312,11 @@ namespace loguru
 			}
 
 			if (abort_if_fatal) {
-#if LOGURU_CATCH_SIGABRT && !defined(_WIN32)
-				// Make sure we don't catch our own abort:
-				signal(SIGABRT, SIG_DFL);
+#if !defined(_WIN32)
+				if (s_signal_options.sigabrt) {
+					// Make sure we don't catch our own abort:
+					signal(SIGABRT, SIG_DFL);
+				}
 #endif
 				abort();
 			}
@@ -1713,9 +1717,9 @@ namespace loguru
 
 #ifdef _WIN32
 namespace loguru {
-	void install_signal_handlers(bool unsafe_signal_handler)
+	void install_signal_handlers(const SignalOptions& signal_options)
 	{
-		(void)unsafe_signal_handler;
+		(void)signal_options;
 		// TODO: implement signal handlers on windows
 	}
 } // namespace loguru
@@ -1724,23 +1728,6 @@ namespace loguru {
 
 namespace loguru
 {
-	struct Signal
-	{
-		int         number;
-		const char* name;
-	};
-	const Signal ALL_SIGNALS[] = {
-#if LOGURU_CATCH_SIGABRT
-		{ SIGABRT, "SIGABRT" },
-#endif
-		{ SIGBUS,  "SIGBUS"  },
-		{ SIGFPE,  "SIGFPE"  },
-		{ SIGILL,  "SIGILL"  },
-		{ SIGINT,  "SIGINT"  },
-		{ SIGSEGV, "SIGSEGV" },
-		{ SIGTERM, "SIGTERM" },
-	};
-
 	void write_to_stderr(const char* data, size_t size)
 	{
 		auto result = write(STDERR_FILENO, data, size);
@@ -1762,18 +1749,17 @@ namespace loguru
 		kill(getpid(), signal_number);
 	}
 
-	static bool s_unsafe_signal_handler = false;
-
 	void signal_handler(int signal_number, siginfo_t*, void*)
 	{
 		const char* signal_name = "UNKNOWN SIGNAL";
 
-		for (const auto& s : ALL_SIGNALS) {
-			if (s.number == signal_number) {
-				signal_name = s.name;
-				break;
-			}
-		}
+		if (signal_number == SIGABRT) { signal_name = "SIGABRT"; }
+		if (signal_number == SIGBUS)  { signal_name = "SIGBUS";  }
+		if (signal_number == SIGFPE)  { signal_name = "SIGFPE";  }
+		if (signal_number == SIGILL)  { signal_name = "SIGILL";  }
+		if (signal_number == SIGINT)  { signal_name = "SIGINT";  }
+		if (signal_number == SIGSEGV) { signal_name = "SIGSEGV"; }
+		if (signal_number == SIGTERM) { signal_name = "SIGTERM"; }
 
 		// --------------------------------------------------------------------
 		/* There are few things that are safe to do in a signal handler,
@@ -1797,7 +1783,7 @@ namespace loguru
 
 		// --------------------------------------------------------------------
 
-		if (s_unsafe_signal_handler) {
+		if (s_signal_options.unsafe_signal_handler) {
 			// --------------------------------------------------------------------
 			/* Now we do unsafe things. This can for example lead to deadlocks if
 			   the signal was triggered from the system's memory management functions
@@ -1822,18 +1808,36 @@ namespace loguru
 		call_default_signal_handler(signal_number);
 	}
 
-	void install_signal_handlers(bool unsafe_signal_handler)
+	void install_signal_handlers(const SignalOptions& signal_options)
 	{
-		s_unsafe_signal_handler = unsafe_signal_handler;
+		s_signal_options = signal_options;
 
 		struct sigaction sig_action;
 		memset(&sig_action, 0, sizeof(sig_action));
 		sigemptyset(&sig_action.sa_mask);
 		sig_action.sa_flags |= SA_SIGINFO;
 		sig_action.sa_sigaction = &signal_handler;
-		for (const auto& s : ALL_SIGNALS) {
-			CHECK_F(sigaction(s.number, &sig_action, NULL) != -1,
-				"Failed to install handler for " LOGURU_FMT(s) "", s.name);
+
+		if (signal_options.sigabrt) {
+			CHECK_F(sigaction(SIGABRT, &sig_action, NULL) != -1, "Failed to install handler for SIGABRT");
+		}
+		if (signal_options.sigbus) {
+			CHECK_F(sigaction(SIGBUS, &sig_action, NULL) != -1, "Failed to install handler for SIGBUS");
+		}
+		if (signal_options.sigfpe) {
+			CHECK_F(sigaction(SIGFPE, &sig_action, NULL) != -1, "Failed to install handler for SIGFPE");
+		}
+		if (signal_options.sigill) {
+			CHECK_F(sigaction(SIGILL, &sig_action, NULL) != -1, "Failed to install handler for SIGILL");
+		}
+		if (signal_options.sigint) {
+			CHECK_F(sigaction(SIGINT, &sig_action, NULL) != -1, "Failed to install handler for SIGINT");
+		}
+		if (signal_options.sigsegv) {
+			CHECK_F(sigaction(SIGSEGV, &sig_action, NULL) != -1, "Failed to install handler for SIGSEGV");
+		}
+		if (signal_options.sigterm) {
+			CHECK_F(sigaction(SIGTERM, &sig_action, NULL) != -1, "Failed to install handler for SIGTERM");
 		}
 	}
 } // namespace loguru
diff --git a/loguru.hpp b/loguru.hpp
index 91d14ec4811..850d0b6efa3 100644
--- a/loguru.hpp
+++ b/loguru.hpp
@@ -56,6 +56,7 @@ Website: www.ilikebigbits.com
 	* Version 1.9.0 - 2018-09-22 - Adjust terminal colors, add LOGURU_VERBOSE_SCOPE_ENDINGS, add LOGURU_SCOPE_TIME_PRECISION, add named log levels
 	* Version 2.0.0 - 2018-09-22 - Split loguru.hpp into loguru.hpp and loguru.cpp
 	* Version 2.1.0 - 2019-09-23 - Update fmtlib + add option to loguru::init to NOT set main thread name.
+	* Version 2.2.0 - 2020-07-31 - Replace LOGURU_CATCH_SIGABRT with struct SignalOptions
 
 # Compiling
 	Just include <loguru.hpp> where you want to use Loguru.
@@ -136,9 +137,8 @@ Website: www.ilikebigbits.com
 	#define LOGURU_SCOPE_TIME_PRECISION 3
 #endif
 
-#ifndef LOGURU_CATCH_SIGABRT
-	// Should Loguru catch SIGABRT to print stack trace etc?
-	#define LOGURU_CATCH_SIGABRT 1
+#ifdef LOGURU_CATCH_SIGABRT
+	#error "You are defining LOGURU_CATCH_SIGABRT. his is for older versions of Loguru. You should now instead set the options passed to loguru::init"
 #endif
 
 #ifndef LOGURU_VERBOSE_SCOPE_ENDINGS
@@ -395,6 +395,49 @@ namespace loguru
 	// Verbosity_INVALID if name is not recognized.
 	typedef Verbosity (*name_to_verbosity_t)(const char* name);
 
+	struct SignalOptions
+	{
+		/// Make Loguru try to do unsafe but useful things,
+		/// like printing a stack trace, when catching signals.
+		/// This may lead to bad things like deadlocks in certain situations.
+		bool unsafe_signal_handler = true;
+
+		/// Should Loguru catch SIGABRT ?
+		bool sigabrt = true;
+
+		/// Should Loguru catch SIGBUS ?
+		bool sigbus = true;
+
+		/// Should Loguru catch SIGFPE ?
+		bool sigfpe = true;
+
+		/// Should Loguru catch SIGILL ?
+		bool sigill = true;
+
+		/// Should Loguru catch SIGINT ?
+		bool sigint = true;
+
+		/// Should Loguru catch SIGSEGV ?
+		bool sigsegv = true;
+
+		/// Should Loguru catch SIGTERM ?
+		bool sigterm = true;
+
+		static SignalOptions none()
+		{
+			SignalOptions options;
+			options.unsafe_signal_handler = false;
+			options.sigabrt = false;
+			options.sigbus = false;
+			options.sigfpe = false;
+			options.sigill = false;
+			options.sigint = false;
+			options.sigsegv = false;
+			options.sigterm = false;
+			return options;
+		}
+	};
+
 	// Runtime options passed to loguru::init
 	struct Options
 	{
@@ -410,10 +453,7 @@ namespace loguru
 		// To always set a thread name, use loguru::set_thread_name instead.
 		const char* main_thread_name = "main thread";
 
-		// Make Loguru try to do unsafe but useful things,
-		// like printing a stack trace, when catching signals.
-		// This may lead to bad things like deadlocks in certain situations.
-		bool unsafe_signal_handler = true;
+		SignalOptions signal_options;
 	};
 
 	/*  Should be called from the main thread.
-- 
GitLab