From fc2e4e7833d3af20ec9cb646fff4f7f5426f10fa Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 27 Feb 2018 10:31:17 -0800 Subject: [PATCH 1/3] Put some thought and documentation effort into process::ExitCode --- src/libstd/process.rs | 76 +++++++++++++------ .../termination-trait-for-exitcode.rs | 2 +- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index e5fc33e241c89..483e58eb0f461 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1080,15 +1080,58 @@ impl fmt::Display for ExitStatus { } } -/// This is ridiculously unstable, as it's a completely-punted-upon part -/// of the `?`-in-`main` RFC. It's here only to allow experimenting with -/// returning a code directly from main. It will definitely change -/// drastically before being stabilized, if it doesn't just get deleted. -#[doc(hidden)] +/// This type represents the status code a process can return to its +/// parent under normal termination. +/// +/// Numeric values used in this type don't have portable meanings, and +/// different platforms may mask different amounts of them. +/// +/// For the platform's canonical successful and unsuccessful codes, see +/// the [`SUCCESS`] and [`FAILURE`] associated items. +/// +/// [`SUCCESS`]: #constant.SUCCESS +/// [`FAILURE`]: #constant.FAILURE +/// +/// **Warning**: While various forms of this were discussed in [RFC #1937], +/// it was ultimately cut from that RFC, and thus this type is more subject +/// to change even than the usual unstable item churn. +/// +/// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937 #[derive(Clone, Copy, Debug)] #[unstable(feature = "process_exitcode_placeholder", issue = "43301")] pub struct ExitCode(pub i32); +#[cfg(target_arch = "wasm32")] +mod rawexit { + pub const SUCCESS: i32 = 0; + pub const FAILURE: i32 = 1; +} +#[cfg(not(target_arch = "wasm32"))] +mod rawexit { + use libc; + pub const SUCCESS: i32 = libc::EXIT_SUCCESS; + pub const FAILURE: i32 = libc::EXIT_FAILURE; +} + +#[unstable(feature = "process_exitcode_placeholder", issue = "43301")] +impl ExitCode { + /// The canonical ExitCode for successful termination on this platform. + /// + /// Note that a `()`-returning `main` implicitly results in a successful + /// termination, so there's no need to return this from `main` unless + /// you're also returning other possible codes. + #[unstable(feature = "process_exitcode_placeholder", issue = "43301")] + pub const SUCCESS: ExitCode = ExitCode(rawexit::SUCCESS); + + /// The canonical ExitCode for unsuccessful termination on this platform. + /// + /// If you're only returning this and `SUCCESS` from `main`, consider + /// instead returning `Err(_)` and `Ok(())` respectively, which will + /// return the same codes (but will also `eprintln!` the error). + #[unstable(feature = "process_exitcode_placeholder", issue = "43301")] + pub const FAILURE: ExitCode = ExitCode(rawexit::FAILURE); +} + impl Child { /// Forces the child to exit. This is equivalent to sending a /// SIGKILL on unix platforms. @@ -1401,18 +1444,6 @@ pub fn id() -> u32 { ::sys::os::getpid() } -#[cfg(target_arch = "wasm32")] -mod exit { - pub const SUCCESS: i32 = 0; - pub const FAILURE: i32 = 1; -} -#[cfg(not(target_arch = "wasm32"))] -mod exit { - use libc; - pub const SUCCESS: i32 = libc::EXIT_SUCCESS; - pub const FAILURE: i32 = libc::EXIT_FAILURE; -} - /// A trait for implementing arbitrary return types in the `main` function. /// /// The c-main function only supports to return integers as return type. @@ -1433,18 +1464,15 @@ pub trait Termination { #[unstable(feature = "termination_trait_lib", issue = "43301")] impl Termination for () { - fn report(self) -> i32 { exit::SUCCESS } + fn report(self) -> i32 { ExitCode::SUCCESS.report() } } #[unstable(feature = "termination_trait_lib", issue = "43301")] impl Termination for Result<(), E> { fn report(self) -> i32 { match self { - Ok(val) => val.report(), - Err(err) => { - eprintln!("Error: {:?}", err); - exit::FAILURE - } + Ok(()) => ().report(), + Err(err) => Err::(err).report(), } } } @@ -1459,7 +1487,7 @@ impl Termination for Result { fn report(self) -> i32 { let Err(err) = self; eprintln!("Error: {:?}", err); - exit::FAILURE + ExitCode::FAILURE.report() } } diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs index 30ecc4e89372b..80fa4d17b6116 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -14,5 +14,5 @@ use std::process::ExitCode; fn main() -> ExitCode { - ExitCode(0) + ExitCode::SUCCESS } From 2ce2b40ee5f847f02d6da1b81f3303b8e8b23531 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 28 Feb 2018 23:34:20 -0800 Subject: [PATCH 2/3] Fix linkchecker --- src/libstd/process.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 483e58eb0f461..5a06bf45aaabd 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1089,8 +1089,8 @@ impl fmt::Display for ExitStatus { /// For the platform's canonical successful and unsuccessful codes, see /// the [`SUCCESS`] and [`FAILURE`] associated items. /// -/// [`SUCCESS`]: #constant.SUCCESS -/// [`FAILURE`]: #constant.FAILURE +/// [`SUCCESS`]: #associatedconstant.SUCCESS +/// [`FAILURE`]: #associatedconstant.FAILURE /// /// **Warning**: While various forms of this were discussed in [RFC #1937], /// it was ultimately cut from that RFC, and thus this type is more subject From 74c5c6e6cb0425284f57fece6fbf248e827ea06d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 3 Mar 2018 18:29:30 -0800 Subject: [PATCH 3/3] Move process::ExitCode internals to sys Now begins the saga of fixing compilation errors on other platforms... --- src/libstd/process.rs | 29 +++++-------------- src/libstd/sys/cloudabi/shims/process.rs | 12 ++++++++ src/libstd/sys/redox/process.rs | 13 +++++++++ src/libstd/sys/unix/process/mod.rs | 2 +- src/libstd/sys/unix/process/process_common.rs | 14 ++++++++- src/libstd/sys/wasm/process.rs | 12 ++++++++ src/libstd/sys/windows/process.rs | 14 ++++++++- 7 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 5a06bf45aaabd..d5ac2d19e831f 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1098,38 +1098,26 @@ impl fmt::Display for ExitStatus { /// /// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937 #[derive(Clone, Copy, Debug)] -#[unstable(feature = "process_exitcode_placeholder", issue = "43301")] -pub struct ExitCode(pub i32); +#[unstable(feature = "process_exitcode_placeholder", issue = "48711")] +pub struct ExitCode(imp::ExitCode); -#[cfg(target_arch = "wasm32")] -mod rawexit { - pub const SUCCESS: i32 = 0; - pub const FAILURE: i32 = 1; -} -#[cfg(not(target_arch = "wasm32"))] -mod rawexit { - use libc; - pub const SUCCESS: i32 = libc::EXIT_SUCCESS; - pub const FAILURE: i32 = libc::EXIT_FAILURE; -} - -#[unstable(feature = "process_exitcode_placeholder", issue = "43301")] +#[unstable(feature = "process_exitcode_placeholder", issue = "48711")] impl ExitCode { /// The canonical ExitCode for successful termination on this platform. /// /// Note that a `()`-returning `main` implicitly results in a successful /// termination, so there's no need to return this from `main` unless /// you're also returning other possible codes. - #[unstable(feature = "process_exitcode_placeholder", issue = "43301")] - pub const SUCCESS: ExitCode = ExitCode(rawexit::SUCCESS); + #[unstable(feature = "process_exitcode_placeholder", issue = "48711")] + pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS); /// The canonical ExitCode for unsuccessful termination on this platform. /// /// If you're only returning this and `SUCCESS` from `main`, consider /// instead returning `Err(_)` and `Ok(())` respectively, which will /// return the same codes (but will also `eprintln!` the error). - #[unstable(feature = "process_exitcode_placeholder", issue = "43301")] - pub const FAILURE: ExitCode = ExitCode(rawexit::FAILURE); + #[unstable(feature = "process_exitcode_placeholder", issue = "48711")] + pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE); } impl Child { @@ -1494,8 +1482,7 @@ impl Termination for Result { #[unstable(feature = "termination_trait_lib", issue = "43301")] impl Termination for ExitCode { fn report(self) -> i32 { - let ExitCode(code) = self; - code + self.0.as_i32() } } diff --git a/src/libstd/sys/cloudabi/shims/process.rs b/src/libstd/sys/cloudabi/shims/process.rs index 52e8c82e2b239..fcd40c15c1708 100644 --- a/src/libstd/sys/cloudabi/shims/process.rs +++ b/src/libstd/sys/cloudabi/shims/process.rs @@ -126,6 +126,18 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(bool); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(false); + pub const FAILURE: ExitCode = ExitCode(true); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + pub struct Process(Void); impl Process { diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 3fd5497389697..d0b94e14f54e9 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -13,6 +13,7 @@ use ffi::OsStr; use os::unix::ffi::OsStrExt; use fmt; use io::{self, Error, ErrorKind}; +use libc::{EXIT_SUCCESS, EXIT_FAILURE}; use path::{Path, PathBuf}; use sys::fd::FileDesc; use sys::fs::{File, OpenOptions}; @@ -480,6 +481,18 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(u8); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); + pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + /// The unique id of the process (this should never be negative). pub struct Process { pid: usize, diff --git a/src/libstd/sys/unix/process/mod.rs b/src/libstd/sys/unix/process/mod.rs index 2a331069bc2c2..d8ac26c45b172 100644 --- a/src/libstd/sys/unix/process/mod.rs +++ b/src/libstd/sys/unix/process/mod.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::process_common::{Command, ExitStatus, Stdio, StdioPipes}; +pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes}; pub use self::process_inner::Process; mod process_common; diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 7e057401fab70..d0486f06a143a 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -13,7 +13,7 @@ use os::unix::prelude::*; use ffi::{OsString, OsStr, CString, CStr}; use fmt; use io; -use libc::{self, c_int, gid_t, uid_t, c_char}; +use libc::{self, c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE}; use ptr; use sys::fd::FileDesc; use sys::fs::{File, OpenOptions}; @@ -393,6 +393,18 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(u8); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); + pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + #[cfg(all(test, not(target_os = "emscripten")))] mod tests { use super::*; diff --git a/src/libstd/sys/wasm/process.rs b/src/libstd/sys/wasm/process.rs index f3f5de350f176..433e9cec7c8ac 100644 --- a/src/libstd/sys/wasm/process.rs +++ b/src/libstd/sys/wasm/process.rs @@ -129,6 +129,18 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(bool); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(false); + pub const FAILURE: ExitCode = ExitCode(true); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + pub struct Process(Void); impl Process { diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index c93179869a651..f1ab9c4760965 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -18,7 +18,7 @@ use ffi::{OsString, OsStr}; use fmt; use fs; use io::{self, Error, ErrorKind}; -use libc::c_void; +use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE}; use mem; use os::windows::ffi::OsStrExt; use path::Path; @@ -408,6 +408,18 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitCode(c::DWORD); + +impl ExitCode { + pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); + pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); + + pub fn as_i32(&self) -> i32 { + self.0 as i32 + } +} + fn zeroed_startupinfo() -> c::STARTUPINFO { c::STARTUPINFO { cb: 0,