Skip to content

Commit 4bb8425

Browse files
committed
ExitStatus: Improve documentation re wait status vs exit status
The use of `ExitStatus` as the Rust type name for a Unix *wait status*, not an *exit status*, is very confusing, but sadly probably too late to change. This area is confusing enough in Unix already (and many programmers are already confuxed). We can at least document it. I chose *not* to mention the way shells like to exit with signal numbers, thus turning signal numbers into exit statuses. This is only relevant for Rust programs using `std::process` if they run shells. Signed-off-by: Ian Jackson <[email protected]>
1 parent d8cfd56 commit 4bb8425

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

library/std/src/process.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ impl Command {
885885
}
886886

887887
/// Executes a command as a child process, waiting for it to finish and
888-
/// collecting its exit status.
888+
/// collecting its status.
889889
///
890890
/// By default, stdin, stdout and stderr are inherited from the parent.
891891
///
@@ -899,7 +899,7 @@ impl Command {
899899
/// .status()
900900
/// .expect("failed to execute process");
901901
///
902-
/// println!("process exited with: {}", status);
902+
/// println!("process finished with: {}", status);
903903
///
904904
/// assert!(status.success());
905905
/// ```
@@ -1368,11 +1368,17 @@ impl From<fs::File> for Stdio {
13681368

13691369
/// Describes the result of a process after it has terminated.
13701370
///
1371-
/// This `struct` is used to represent the exit status of a child process.
1371+
/// This `struct` is used to represent the exit status or other termination of a child process.
13721372
/// Child processes are created via the [`Command`] struct and their exit
13731373
/// status is exposed through the [`status`] method, or the [`wait`] method
13741374
/// of a [`Child`] process.
13751375
///
1376+
/// An `ExitStatus` represents every possible disposition of a process. On Unix this
1377+
/// is the **wait status**. It is *not* simply an *exit status* (a value passed to `exit`).
1378+
///
1379+
/// For proper error reporting of failed processes, print the value of `ExitStatus` using its
1380+
/// implementation of [`Display`](crate::fmt::Display).
1381+
///
13761382
/// [`status`]: Command::status
13771383
/// [`wait`]: Child::wait
13781384
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@@ -1400,7 +1406,7 @@ impl ExitStatus {
14001406
/// if status.success() {
14011407
/// println!("'projects/' directory created");
14021408
/// } else {
1403-
/// println!("failed to create 'projects/' directory");
1409+
/// println!("failed to create 'projects/' directory: {}", status);
14041410
/// }
14051411
/// ```
14061412
#[stable(feature = "process", since = "1.0.0")]
@@ -1410,9 +1416,14 @@ impl ExitStatus {
14101416

14111417
/// Returns the exit code of the process, if any.
14121418
///
1413-
/// On Unix, this will return `None` if the process was terminated
1414-
/// by a signal; `std::os::unix` provides an extension trait for
1415-
/// extracting the signal and other details from the `ExitStatus`.
1419+
/// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the
1420+
/// process finished by calling `exit`. Note that on Unix the exit status is truncated to 8
1421+
/// bits, and that values that didn't come from a program's call to `exit` may be invented the
1422+
/// runtime system (often, for example, 255, 254, 127 or 126).
1423+
///
1424+
/// On Unix, this will return `None` if the process was terminated by a signal.
1425+
/// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) is an
1426+
/// extension trait for extracting any such signal, and other details, from the `ExitStatus`.
14161427
///
14171428
/// # Examples
14181429
///

library/std/src/sys/unix/ext/process.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,20 @@ impl CommandExt for process::Command {
186186

187187
/// Unix-specific extensions to [`process::ExitStatus`].
188188
///
189+
/// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as passed to the
190+
/// `exit` system call or returned by [`ExitStatus::code()`](crate::process::ExitStatus::code).
191+
/// It represents **any wait status**, as returned by one of the `wait` family of system calls.
192+
///
193+
/// This is because a Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but
194+
/// can also represent other kinds of process event.
195+
///
189196
/// This trait is sealed: it cannot be implemented outside the standard library.
190197
/// This is so that future additional methods are not breaking changes.
191198
#[stable(feature = "rust1", since = "1.0.0")]
192199
pub trait ExitStatusExt: Sealed {
193-
/// Creates a new `ExitStatus` from the raw underlying `i32` return value of
194-
/// a process.
200+
/// Creates a new `ExitStatus` from the raw underlying integer status value from `wait`
201+
///
202+
/// The value should be a **wait status, not an exit status**.
195203
#[stable(feature = "exit_status_from", since = "1.12.0")]
196204
fn from_raw(raw: i32) -> Self;
197205

@@ -220,6 +228,8 @@ pub trait ExitStatusExt: Sealed {
220228
fn continued(&self) -> bool;
221229

222230
/// Returns the underlying raw `wait` status.
231+
///
232+
/// The returned integer is a **wait status, not an exit status**.
223233
#[unstable(feature = "unix_process_wait_more", issue = "80695")]
224234
fn into_raw(self) -> i32;
225235
}

0 commit comments

Comments
 (0)