提交 de3a63d6 编写于 作者: A Alex Crichton

Rollup merge of #48618 - scottmcm:elaborate-exitcode, r=alexcrichton

Better docs and associated SUCCESS/FAILURE for process::ExitCode

Follow-up to https://github.com/rust-lang/rust/pull/48497#discussion_r170676525, since that PR was the minimal thing to unblock https://github.com/rust-lang/rust/issues/48453#issuecomment-368155082.

r? @nikomatsakis
......@@ -1080,14 +1080,45 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
/// 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`]: #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
/// 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);
#[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
pub struct ExitCode(imp::ExitCode);
#[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 = "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 = "48711")]
pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
}
impl Child {
/// Forces the child to exit. This is equivalent to sending a
......@@ -1401,18 +1432,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 +1452,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<E: fmt::Debug> 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,15 +1475,14 @@ impl<E: fmt::Debug> Termination for Result<!, E> {
fn report(self) -> i32 {
let Err(err) = self;
eprintln!("Error: {:?}", err);
exit::FAILURE
ExitCode::FAILURE.report()
}
}
#[unstable(feature = "termination_trait_lib", issue = "43301")]
impl Termination for ExitCode {
fn report(self) -> i32 {
let ExitCode(code) = self;
code
self.0.as_i32()
}
}
......
......@@ -126,6 +126,18 @@ fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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 {
......
......@@ -13,6 +13,7 @@
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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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,
......
......@@ -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;
......
......@@ -13,7 +13,7 @@
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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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::*;
......
......@@ -129,6 +129,18 @@ fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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 {
......
......@@ -18,7 +18,7 @@
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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
#[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,
......
......@@ -14,5 +14,5 @@
use std::process::ExitCode;
fn main() -> ExitCode {
ExitCode(0)
ExitCode::SUCCESS
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册