about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2022-04-08 13:39:24 -0700
committerMichael Howell <michael@notriddle.com>2022-04-23 11:54:17 -0700
commit47030d300a7f3fe40fbab3454d298354c863fa10 (patch)
tree664c2367f186d8984d18f270819ee8e9d0248e16
parent2d5a21f63c98f8a1d5f3c3af93bcb0a8af19af36 (diff)
downloadrust-47030d300a7f3fe40fbab3454d298354c863fa10.tar.gz
rust-47030d300a7f3fe40fbab3454d298354c863fa10.zip
std: `<ExitStatus as Display>::fmt` name the signal it died from
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs63
-rw-r--r--library/std/src/sys/unix/process/process_unix/tests.rs6
2 files changed, 66 insertions, 3 deletions
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 3d305cd7310..188e356a8b4 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -695,17 +695,80 @@ impl From<c_int> for ExitStatus {
     }
 }
 
+/// Convert a signal number to a readable, searchable name.
+fn signal_string(signal: i32) -> String {
+    (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",
+        #[cfg(target_os = "linux")]
+        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",
+        _ => return format!("{signal}"),
+    })
+    .to_string()
+}
+
 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 = signal_string(signal);
             if self.core_dumped() {
                 write!(f, "signal: {signal} (core dumped)")
             } else {
                 write!(f, "signal: {signal}")
             }
         } else if let Some(signal) = self.stopped_signal() {
+            let signal = signal_string(signal);
             write!(f, "stopped (not terminated) by signal: {signal}")
         } else if self.continued() {
             write!(f, "continued (WIFCONTINUED)")
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..8d4f6b5179e 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: SIGTERM");
+    t(0x0008b, "signal: 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: SIGSTOP");
         t(0x0ffff, "continued (WIFCONTINUED)");
     }