about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-03 20:18:14 +0000
committerbors <bors@rust-lang.org>2022-06-03 20:18:14 +0000
commita6b8c6954829669a5c4fa320c3e6132edf04fcfc (patch)
treef962ba05af88d885ecb43e0b0cd7949767d7ce97 /library/std/src/sys
parent7e9b92cb43a489b34e2bcb8d21f36198e02eedbc (diff)
parent22791bbccd6dd8c1c3981fc9cb662774f2117d3b (diff)
downloadrust-a6b8c6954829669a5c4fa320c3e6132edf04fcfc.tar.gz
rust-a6b8c6954829669a5c4fa320c3e6132edf04fcfc.zip
Auto merge of #95833 - notriddle:notriddle/human-readable-signals, r=yaahc
std: `<ExitStatus as Display>::fmt` name the signal it died from

Related to #95601
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs82
-rw-r--r--library/std/src/sys/unix/process/process_unix/tests.rs6
2 files changed, 82 insertions, 6 deletions
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 23bb6d6c15f..ef29aa3c890 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -695,18 +695,94 @@ impl From<c_int> for ExitStatus {
     }
 }
 
+/// Convert a signal number to a readable, searchable name.
+///
+/// This string should be displayed right after the signal number.
+/// If a signal is unrecognized, it returns the empty string, so that
+/// you just get the number like "0". If it is recognized, you'll get
+/// something like "9 (SIGKILL)".
+fn signal_string(signal: i32) -> &'static str {
+    match signal {
+        libc::SIGHUP => " (SIGHUP)",
+        libc::SIGINT => " (SIGINT)",
+        libc::SIGQUIT => " (SIGQUIT)",
+        libc::SIGILL => " (SIGILL)",
+        libc::SIGTRAP => " (SIGTRAP)",
+        libc::SIGABRT => " (SIGABRT)",
+        libc::SIGBUS => " (SIGBUS)",
+        libc::SIGFPE => " (SIGFPE)",
+        libc::SIGKILL => " (SIGKILL)",
+        libc::SIGUSR1 => " (SIGUSR1)",
+        libc::SIGSEGV => " (SIGSEGV)",
+        libc::SIGUSR2 => " (SIGUSR2)",
+        libc::SIGPIPE => " (SIGPIPE)",
+        libc::SIGALRM => " (SIGALRM)",
+        libc::SIGTERM => " (SIGTERM)",
+        libc::SIGCHLD => " (SIGCHLD)",
+        libc::SIGCONT => " (SIGCONT)",
+        libc::SIGSTOP => " (SIGSTOP)",
+        libc::SIGTSTP => " (SIGTSTP)",
+        libc::SIGTTIN => " (SIGTTIN)",
+        libc::SIGTTOU => " (SIGTTOU)",
+        libc::SIGURG => " (SIGURG)",
+        libc::SIGXCPU => " (SIGXCPU)",
+        libc::SIGXFSZ => " (SIGXFSZ)",
+        libc::SIGVTALRM => " (SIGVTALRM)",
+        libc::SIGPROF => " (SIGPROF)",
+        libc::SIGWINCH => " (SIGWINCH)",
+        libc::SIGIO => " (SIGIO)",
+        libc::SIGSYS => " (SIGSYS)",
+        // For information on Linux signals, run `man 7 signal`
+        #[cfg(all(
+            target_os = "linux",
+            any(
+                target_arch = "x86_64",
+                target_arch = "x86",
+                target_arch = "arm",
+                target_arch = "aarch64"
+            )
+        ))]
+        libc::SIGSTKFLT => " (SIGSTKFLT)",
+        #[cfg(target_os = "linux")]
+        libc::SIGPWR => " (SIGPWR)",
+        #[cfg(any(
+            target_os = "macos",
+            target_os = "ios",
+            target_os = "tvos",
+            target_os = "freebsd",
+            target_os = "netbsd",
+            target_os = "openbsd",
+            target_os = "dragonfly"
+        ))]
+        libc::SIGEMT => " (SIGEMT)",
+        #[cfg(any(
+            target_os = "macos",
+            target_os = "ios",
+            target_os = "tvos",
+            target_os = "freebsd",
+            target_os = "netbsd",
+            target_os = "openbsd",
+            target_os = "dragonfly"
+        ))]
+        libc::SIGINFO => " (SIGINFO)",
+        _ => "",
+    }
+}
+
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if let Some(code) = self.code() {
             write!(f, "exit status: {code}")
         } else if let Some(signal) = self.signal() {
+            let signal_string = signal_string(signal);
             if self.core_dumped() {
-                write!(f, "signal: {signal} (core dumped)")
+                write!(f, "signal: {signal}{signal_string} (core dumped)")
             } else {
-                write!(f, "signal: {signal}")
+                write!(f, "signal: {signal}{signal_string}")
             }
         } else if let Some(signal) = self.stopped_signal() {
-            write!(f, "stopped (not terminated) by signal: {signal}")
+            let signal_string = signal_string(signal);
+            write!(f, "stopped (not terminated) by signal: {signal}{signal_string}")
         } else if self.continued() {
             write!(f, "continued (WIFCONTINUED)")
         } else {
diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs
index 560c62155d9..e0e2d478fad 100644
--- a/library/std/src/sys/unix/process/process_unix/tests.rs
+++ b/library/std/src/sys/unix/process/process_unix/tests.rs
@@ -14,8 +14,8 @@ fn exitstatus_display_tests() {
 
     let t = |v, s| assert_eq!(s, format!("{}", <ExitStatus as ExitStatusExt>::from_raw(v)));
 
-    t(0x0000f, "signal: 15");
-    t(0x0008b, "signal: 11 (core dumped)");
+    t(0x0000f, "signal: 15 (SIGTERM)");
+    t(0x0008b, "signal: 11 (SIGSEGV) (core dumped)");
     t(0x00000, "exit status: 0");
     t(0x0ff00, "exit status: 255");
 
@@ -24,7 +24,7 @@ fn exitstatus_display_tests() {
     // The purpose of this test is to test our string formatting, not our understanding of the wait
     // status magic numbers.  So restrict these to Linux.
     if cfg!(target_os = "linux") {
-        t(0x0137f, "stopped (not terminated) by signal: 19");
+        t(0x0137f, "stopped (not terminated) by signal: 19 (SIGSTOP)");
         t(0x0ffff, "continued (WIFCONTINUED)");
     }