From 5b1316f78152a9c066b357ea9addf803d48e114a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:31:54 +0000 Subject: [PATCH 01/14] unix ExitStatus: Do not treat WIFSTOPPED as WIFSIGNALED A unix wait status can contain, at least, exit statuses, termination signals, and stop signals. WTERMSIG is only valid if WIFSIGNALED. https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html It will not be easy to experience this bug with `Command`, because that doesn't pass WUNTRACED. But you could make an ExitStatus containing, say, a WIFSTOPPED, from a call to one of the libc wait functions. (In the WIFSTOPPED case, there is WSTOPSIG. But a stop signal is encoded differently to a termination signal, so WTERMSIG and WSTOPSIG are by no means the same.) Signed-off-by: Ian Jackson --- library/std/src/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index a590c74435639..629180fd71231 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -479,7 +479,7 @@ impl ExitStatus { } pub fn signal(&self) -> Option { - if !self.exited() { Some(libc::WTERMSIG(self.0)) } else { None } + if libc::WIFSIGNALED(self.0) { Some(libc::WTERMSIG(self.0)) } else { None } } } From 12d62aa436ee3a7ae0a55f63c4089c09fe140ccb Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:37:34 +0000 Subject: [PATCH 02/14] unix ExitStatus: Clarify docs for .signal() We need to be clear that this never returns WSTOPSIG. That is, if WIFSTOPPED, the return value is None. Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 3615a8a5ee8b0..ab961a284d51b 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -171,6 +171,8 @@ pub trait ExitStatusExt { fn from_raw(raw: i32) -> Self; /// If the process was terminated by a signal, returns that signal. + /// + /// Ie, if `WIFSIGNALED`, this returns `WTERMSIG`. #[stable(feature = "rust1", since = "1.0.0")] fn signal(&self) -> Option; } From 530270f94a3d9f1c23257ad1c9c93675b31ecf6a Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:41:55 +0000 Subject: [PATCH 03/14] unix ExitStatus: Provide .into_raw() Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 8 ++++++++ library/std/src/sys/unix/process/process_unix.rs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index ab961a284d51b..4b65629e2b368 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -175,6 +175,10 @@ pub trait ExitStatusExt { /// Ie, if `WIFSIGNALED`, this returns `WTERMSIG`. #[stable(feature = "rust1", since = "1.0.0")] fn signal(&self) -> Option; + + /// Returns the underlying raw `wait` status. + #[unstable(feature = "unix_process_wait_more", issue = "none")] + fn into_raw(self) -> i32; } #[stable(feature = "rust1", since = "1.0.0")] @@ -186,6 +190,10 @@ impl ExitStatusExt for process::ExitStatus { fn signal(&self) -> Option { self.as_inner().signal() } + + fn into_raw(self) -> i32 { + self.as_inner().into_raw().into() + } } #[stable(feature = "process_extensions", since = "1.2.0")] diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 629180fd71231..f1cf402805781 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -481,6 +481,10 @@ impl ExitStatus { pub fn signal(&self) -> Option { if libc::WIFSIGNALED(self.0) { Some(libc::WTERMSIG(self.0)) } else { None } } + + pub fn into_raw(&self) -> c_int { + self.0 + } } /// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying. From 3f05051d6bcb7b8562577324d59a2435a40992e9 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:44:13 +0000 Subject: [PATCH 04/14] unix ExitStatus: Provide .core_dumped This is essential for proper reporting of child process status on Unix. Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 8 ++++++++ library/std/src/sys/unix/process/process_unix.rs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 4b65629e2b368..827cc0b9828b4 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -176,6 +176,10 @@ pub trait ExitStatusExt { #[stable(feature = "rust1", since = "1.0.0")] fn signal(&self) -> Option; + /// If the process was terminated by a signal, says whether it dumped core. + #[unstable(feature = "unix_process_wait_more", issue = "none")] + fn core_dumped(&self) -> bool; + /// Returns the underlying raw `wait` status. #[unstable(feature = "unix_process_wait_more", issue = "none")] fn into_raw(self) -> i32; @@ -191,6 +195,10 @@ impl ExitStatusExt for process::ExitStatus { self.as_inner().signal() } + fn core_dumped(&self) -> bool { + self.as_inner().core_dumped() + } + fn into_raw(self) -> i32 { self.as_inner().into_raw().into() } diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index f1cf402805781..99b1011578a5a 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -482,6 +482,10 @@ impl ExitStatus { if libc::WIFSIGNALED(self.0) { Some(libc::WTERMSIG(self.0)) } else { None } } + pub fn core_dumped(&self) -> bool { + libc::WIFSIGNALED(self.0) && libc::WCOREDUMP(self.0) + } + pub fn into_raw(&self) -> c_int { self.0 } From f060b9e0d9277ae522a34ca06312c5857c9aadb0 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:47:47 +0000 Subject: [PATCH 05/14] unix ExitStatus: Provide .stopped_signal() Necessary to handle WIFSTOPPED. Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 11 +++++++++++ library/std/src/sys/unix/process/process_unix.rs | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 827cc0b9828b4..5efe08340f488 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -180,6 +180,13 @@ pub trait ExitStatusExt { #[unstable(feature = "unix_process_wait_more", issue = "none")] fn core_dumped(&self) -> bool; + /// If the process was stopped by a signal, returns that signal. + /// + /// Ie, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from + /// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`. + #[unstable(feature = "unix_process_wait_more", issue = "none")] + fn stopped_signal(&self) -> Option; + /// Returns the underlying raw `wait` status. #[unstable(feature = "unix_process_wait_more", issue = "none")] fn into_raw(self) -> i32; @@ -199,6 +206,10 @@ impl ExitStatusExt for process::ExitStatus { self.as_inner().core_dumped() } + fn stopped_signal(&self) -> Option { + self.as_inner().stopped_signal() + } + fn into_raw(self) -> i32 { self.as_inner().into_raw().into() } diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 99b1011578a5a..069a1145f7645 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -486,6 +486,10 @@ impl ExitStatus { libc::WIFSIGNALED(self.0) && libc::WCOREDUMP(self.0) } + pub fn stopped_signal(&self) -> Option { + if libc::WIFSTOPPED(self.0) { Some(libc::WSTOPSIG(self.0)) } else { None } + } + pub fn into_raw(&self) -> c_int { self.0 } From 42ea8f64347e8c57972a043b00e6c02c9973e7df Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 12 Dec 2020 21:52:17 +0000 Subject: [PATCH 06/14] unix ExitStatus: Provide .continued() Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 11 +++++++++++ library/std/src/sys/unix/process/process_unix.rs | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 5efe08340f488..6ab109cdb08c2 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -187,6 +187,13 @@ pub trait ExitStatusExt { #[unstable(feature = "unix_process_wait_more", issue = "none")] fn stopped_signal(&self) -> Option; + /// Whether the process was continued from a stopped status. + /// + /// Ie, `WIFCONTINUED`. This is only possible if the status came from a `wait` system call + /// which was passed `WCONTINUED`, was then converted into an `ExitStatus`. + #[unstable(feature = "unix_process_wait_more", issue = "none")] + fn continued(&self) -> bool; + /// Returns the underlying raw `wait` status. #[unstable(feature = "unix_process_wait_more", issue = "none")] fn into_raw(self) -> i32; @@ -210,6 +217,10 @@ impl ExitStatusExt for process::ExitStatus { self.as_inner().stopped_signal() } + fn continued(&self) -> bool { + self.as_inner().continued() + } + fn into_raw(self) -> i32 { self.as_inner().into_raw().into() } diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 069a1145f7645..945b43678a919 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -490,6 +490,10 @@ impl ExitStatus { if libc::WIFSTOPPED(self.0) { Some(libc::WSTOPSIG(self.0)) } else { None } } + pub fn continued(&self) -> bool { + libc::WIFCONTINUED(self.0) + } + pub fn into_raw(&self) -> c_int { self.0 } From 29c851aef6c75e4ddedca1d5603daf3a25bd1ce1 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 13 Dec 2020 11:03:17 +0000 Subject: [PATCH 07/14] Replace `Ie` with `In other words` Co-authored-by: Joshua Nelson --- library/std/src/sys/unix/ext/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 6ab109cdb08c2..7830148b7e888 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -182,7 +182,7 @@ pub trait ExitStatusExt { /// If the process was stopped by a signal, returns that signal. /// - /// Ie, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from + /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from /// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`. #[unstable(feature = "unix_process_wait_more", issue = "none")] fn stopped_signal(&self) -> Option; From 06a405c49cfcdc091f1d84a3c6147d78fbdb5928 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 13 Dec 2020 11:03:37 +0000 Subject: [PATCH 08/14] Replace `Ie` with `In other words` Co-authored-by: Joshua Nelson --- library/std/src/sys/unix/ext/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 7830148b7e888..a20f826e7f05a 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -172,7 +172,7 @@ pub trait ExitStatusExt { /// If the process was terminated by a signal, returns that signal. /// - /// Ie, if `WIFSIGNALED`, this returns `WTERMSIG`. + /// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`. #[stable(feature = "rust1", since = "1.0.0")] fn signal(&self) -> Option; From fa68567a1fa87e92ad39b1749a134faedbbeae48 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 4 Jan 2021 17:37:34 +0000 Subject: [PATCH 09/14] unix ExitStatus: Add tracking issue to new methods Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index a20f826e7f05a..889382d3ed4ec 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -177,25 +177,25 @@ pub trait ExitStatusExt { fn signal(&self) -> Option; /// If the process was terminated by a signal, says whether it dumped core. - #[unstable(feature = "unix_process_wait_more", issue = "none")] + #[unstable(feature = "unix_process_wait_more", issue = "80695")] fn core_dumped(&self) -> bool; /// If the process was stopped by a signal, returns that signal. /// /// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from /// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`. - #[unstable(feature = "unix_process_wait_more", issue = "none")] + #[unstable(feature = "unix_process_wait_more", issue = "80695")] fn stopped_signal(&self) -> Option; /// Whether the process was continued from a stopped status. /// /// Ie, `WIFCONTINUED`. This is only possible if the status came from a `wait` system call /// which was passed `WCONTINUED`, was then converted into an `ExitStatus`. - #[unstable(feature = "unix_process_wait_more", issue = "none")] + #[unstable(feature = "unix_process_wait_more", issue = "80695")] fn continued(&self) -> bool; /// Returns the underlying raw `wait` status. - #[unstable(feature = "unix_process_wait_more", issue = "none")] + #[unstable(feature = "unix_process_wait_more", issue = "80695")] fn into_raw(self) -> i32; } From 70121941fffce3292e45b40c84d263af5bffb109 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 4 Jan 2021 17:11:41 +0000 Subject: [PATCH 10/14] ExitStatusExt unix: Retrospectively seal this trait As discussed in #79982. I think the "new interfaces", ie the new trait and impl, must be insta-stable. This seems OK because we are, in fact, adding a new restriction to the stable API. Signed-off-by: Ian Jackson --- library/std/src/sys/unix/ext/process.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index 889382d3ed4ec..a72417818d066 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -9,6 +9,14 @@ use crate::process; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +mod private { + /// This trait being unreachable from outside the crate + /// prevents other implementations of the `ExitStatusExt` trait, + /// which allows potentially adding more trait methods in the future. + #[stable(feature = "none", since = "1.51.0")] + pub trait Sealed {} +} + /// Unix-specific extensions to the [`process::Command`] builder. #[stable(feature = "rust1", since = "1.0.0")] pub trait CommandExt { @@ -163,8 +171,11 @@ impl CommandExt for process::Command { } /// Unix-specific extensions to [`process::ExitStatus`]. +/// +/// This trait is saeled (since Rust 1.51): it cannot be implemented outside the standard library. +/// This is so that future additional methods are not breaking changes. #[stable(feature = "rust1", since = "1.0.0")] -pub trait ExitStatusExt { +pub trait ExitStatusExt: private::Sealed { /// Creates a new `ExitStatus` from the raw underlying `i32` return value of /// a process. #[stable(feature = "exit_status_from", since = "1.12.0")] @@ -199,6 +210,9 @@ pub trait ExitStatusExt { fn into_raw(self) -> i32; } +#[stable(feature = "none", since = "1.51.0")] +impl private::Sealed for process::ExitStatus {} + #[stable(feature = "rust1", since = "1.0.0")] impl ExitStatusExt for process::ExitStatus { fn from_raw(raw: i32) -> Self { From f3e7199a79d23741e1fc6b0e58652d6de5f97fa0 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Mon, 4 Jan 2021 17:45:23 +0000 Subject: [PATCH 11/14] ExitStatusExt windows: Retrospectively seal this trait Signed-off-by: Ian Jackson --- library/std/src/sys/windows/ext/process.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/windows/ext/process.rs b/library/std/src/sys/windows/ext/process.rs index 61e4c6a1d1718..300385e966d37 100644 --- a/library/std/src/sys/windows/ext/process.rs +++ b/library/std/src/sys/windows/ext/process.rs @@ -7,6 +7,14 @@ use crate::process; use crate::sys; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; +mod private { + /// This trait being unreachable from outside the crate + /// prevents other implementations of the `ExitStatusExt` trait, + /// which allows potentially adding more trait methods in the future. + #[stable(feature = "none", since = "1.51.0")] + pub trait Sealed {} +} + #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio { @@ -73,8 +81,11 @@ impl IntoRawHandle for process::ChildStderr { } /// Windows-specific extensions to [`process::ExitStatus`]. +/// +/// This trait is saeled (since Rust 1.51): it cannot be implemented outside the standard library. +/// This is so that future additional methods are not breaking changes. #[stable(feature = "exit_status_from", since = "1.12.0")] -pub trait ExitStatusExt { +pub trait ExitStatusExt: private::Sealed { /// Creates a new `ExitStatus` from the raw underlying `u32` return value of /// a process. #[stable(feature = "exit_status_from", since = "1.12.0")] @@ -88,6 +99,9 @@ impl ExitStatusExt for process::ExitStatus { } } +#[stable(feature = "none", since = "1.51.0")] +impl private::Sealed for process::ExitStatus {} + /// Windows-specific extensions to the [`process::Command`] builder. #[stable(feature = "windows_process_extensions", since = "1.16.0")] pub trait CommandExt { From efddf5949f36d68ff28abddb2c297c934d5b8eb5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 10 Jan 2021 18:11:00 -0800 Subject: [PATCH 12/14] Fix typo saeled -> sealed --- library/std/src/sys/unix/ext/process.rs | 2 +- library/std/src/sys/windows/ext/process.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/ext/process.rs b/library/std/src/sys/unix/ext/process.rs index a72417818d066..f4c67b225e6e1 100644 --- a/library/std/src/sys/unix/ext/process.rs +++ b/library/std/src/sys/unix/ext/process.rs @@ -172,7 +172,7 @@ impl CommandExt for process::Command { /// Unix-specific extensions to [`process::ExitStatus`]. /// -/// This trait is saeled (since Rust 1.51): it cannot be implemented outside the standard library. +/// This trait is sealed: it cannot be implemented outside the standard library. /// This is so that future additional methods are not breaking changes. #[stable(feature = "rust1", since = "1.0.0")] pub trait ExitStatusExt: private::Sealed { diff --git a/library/std/src/sys/windows/ext/process.rs b/library/std/src/sys/windows/ext/process.rs index 300385e966d37..7a92381d6609b 100644 --- a/library/std/src/sys/windows/ext/process.rs +++ b/library/std/src/sys/windows/ext/process.rs @@ -82,7 +82,7 @@ impl IntoRawHandle for process::ChildStderr { /// Windows-specific extensions to [`process::ExitStatus`]. /// -/// This trait is saeled (since Rust 1.51): it cannot be implemented outside the standard library. +/// This trait is sealed: it cannot be implemented outside the standard library. /// This is so that future additional methods are not breaking changes. #[stable(feature = "exit_status_from", since = "1.12.0")] pub trait ExitStatusExt: private::Sealed { From 05a88aabc1bca6d06f5827bae9e8f448f5d39f28 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Wed, 13 Jan 2021 11:17:41 +0000 Subject: [PATCH 13/14] ExitStatusExt: Fix build on Fuchsia This is not particularly pretty but the current situation is a mess and I don't think I'm making it significantly worse. Signed-off-by: Ian Jackson --- .../src/sys/unix/process/process_fuchsia.rs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index b64636c3f3d15..3102661b83dad 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -245,6 +245,50 @@ impl ExitStatus { pub fn signal(&self) -> Option { None } + + // FIXME: The actually-Unix implementation in process_unix.rs uses WSTOPSIG, WCOREDUMP et al. + // I infer from the implementation of `success`, `code` and `signal` above that these are not + // available on Fuchsia. + // + // It does not appear that Fuchsia is Unix-like enough to implement ExitStatus (or indeed many + // other things from std::os::unix) properly. This veneer is always going to be a bdoge. So + // while I don't know if these implementations are actually correct, I think they will do for + // now at least. + pub fn core_dumped(&self) -> bool { + false + } + pub fn stopped_signal(&self) -> Option { + None + } + pub fn continued(&self) -> bool { + false + } + + pub fn into_raw(&self) -> c_int { + // We don't know what someone who calls into_raw() will do with this value, but it should + // have the conventional Unix representation. Despite the fact that this is not + // standardised in SuS or POSIX, all Unix systems encode the signal and exit status the + // same way. (Ie the WIFEXITED, WEXITSTATUS etc. macros have identical behaviour on every + // Unix.) + // + // The caller of `std::os::unix::into_raw` is probably wanting a Unix exit status, and may + // do their own shifting and masking, or even pass the status to another computer running a + // different Unix variant. + // + // The other view would be to say that the caller on Fuchsia ought to know that `into_raw` + // will give a raw Fuchsia status (whatever that is - I don't know, personally). That is + // not possible here becaause we must return a c_int because that's what Unix (including + // SuS and POSIX) say a wait status is, but Fuchsia apparently uses a u64, so it won't + // necessarily fit. + // + // It seems to me that that the right answer would be to provide std::os::fuchsia with its + // own ExitStatusExt, rather that trying to provide a not very convincing imitation of + // Unix. Ie, std::os::unix::process:ExitStatusExt ought not to exist on Fuchsia. But + // fixing this up that is beyond the scope of my efforts now. + let exit_status_as_if_unix: u8 = self.0.try_into().expect("Fuchsia process return code bigger than 8 bits, but std::os::unix::ExitStatusExt::into_raw() was called to try to covert the value into a traditional Unix-style wait status, which cannot represent values greater than 255."); + let wait_status_as_if_unix = (exit_status_as_if_unix as c_int) << 8; + wait_status_as_if_unix + } } /// Converts a raw `c_int` to a type-safe `ExitStatus` by wrapping it without copying. From a8d01619608715e6abc4c6d3c6f347f393262725 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 13 Jan 2021 22:13:45 -0800 Subject: [PATCH 14/14] Fix typos in Fuchsia unix_process_wait_more --- library/std/src/sys/unix/process/process_fuchsia.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index 3102661b83dad..0d4703d7f503a 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -251,7 +251,7 @@ impl ExitStatus { // available on Fuchsia. // // It does not appear that Fuchsia is Unix-like enough to implement ExitStatus (or indeed many - // other things from std::os::unix) properly. This veneer is always going to be a bdoge. So + // other things from std::os::unix) properly. This veneer is always going to be a bodge. So // while I don't know if these implementations are actually correct, I think they will do for // now at least. pub fn core_dumped(&self) -> bool { @@ -285,7 +285,7 @@ impl ExitStatus { // own ExitStatusExt, rather that trying to provide a not very convincing imitation of // Unix. Ie, std::os::unix::process:ExitStatusExt ought not to exist on Fuchsia. But // fixing this up that is beyond the scope of my efforts now. - let exit_status_as_if_unix: u8 = self.0.try_into().expect("Fuchsia process return code bigger than 8 bits, but std::os::unix::ExitStatusExt::into_raw() was called to try to covert the value into a traditional Unix-style wait status, which cannot represent values greater than 255."); + let exit_status_as_if_unix: u8 = self.0.try_into().expect("Fuchsia process return code bigger than 8 bits, but std::os::unix::ExitStatusExt::into_raw() was called to try to convert the value into a traditional Unix-style wait status, which cannot represent values greater than 255."); let wait_status_as_if_unix = (exit_status_as_if_unix as c_int) << 8; wait_status_as_if_unix }