diff options
| author | Corey Farwell <coreyf@rwell.org> | 2017-02-08 10:19:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-08 10:19:48 -0500 |
| commit | 96bf9ba94da034a5999e71b5bdbed60559d7b373 (patch) | |
| tree | c3e92f8d296bee5fc0a732d5f20a4c10fab8026c /src/libstd/sys | |
| parent | f69259ecf8cc5577cd24065f9a5a6498cfff77db (diff) | |
| parent | 2a345bbcc1e6332241883f784896ea93d2a7ccb3 (diff) | |
| download | rust-96bf9ba94da034a5999e71b5bdbed60559d7b373.tar.gz rust-96bf9ba94da034a5999e71b5bdbed60559d7b373.zip | |
Rollup merge of #39512 - oconnor663:try_wait, r=alexcrichton
make Child::try_wait return io::Result<Option<ExitStatus>>
This is much nicer for callers who want to short-circuit real I/O errors
with `?`, because they can write this
if let Some(status) = foo.try_wait()? {
...
} else {
...
}
instead of this
match foo.try_wait() {
Ok(status) => {
...
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
...
}
Err(err) => return Err(err),
}
The original design of `try_wait` was patterned after the `Read` and
`Write` traits, which support both blocking and non-blocking
implementations in a single API. But since `try_wait` is never blocking,
it makes sense to optimize for the non-blocking case.
Tracking issue: https://github.com/rust-lang/rust/issues/38903
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/redox/process.rs | 8 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process/process_fuchsia.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process/process_unix.rs | 8 | ||||
| -rw-r--r-- | src/libstd/sys/windows/process.rs | 6 |
4 files changed, 14 insertions, 14 deletions
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index 50dcd44b42e..60dc03fcf47 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -502,17 +502,17 @@ impl Process { Ok(ExitStatus(status as i32)) } - pub fn try_wait(&mut self) -> io::Result<ExitStatus> { + pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { if let Some(status) = self.status { - return Ok(status) + return Ok(Some(status)) } let mut status = 0; let pid = cvt(syscall::waitpid(self.pid, &mut status, syscall::WNOHANG))?; if pid == 0 { - Err(io::Error::from_raw_os_error(syscall::EWOULDBLOCK)) + Ok(None) } else { self.status = Some(ExitStatus(status as i32)); - Ok(ExitStatus(status as i32)) + Ok(Some(ExitStatus(status as i32))) } } } diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs index 87acb0ed9b9..0bb2e0c1a83 100644 --- a/src/libstd/sys/unix/process/process_fuchsia.rs +++ b/src/libstd/sys/unix/process/process_fuchsia.rs @@ -165,7 +165,7 @@ impl Process { Ok(ExitStatus::new(proc_info.rec.return_code)) } - pub fn try_wait(&mut self) -> io::Result<ExitStatus> { + pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { use default::Default; use sys::process::magenta::*; @@ -179,7 +179,7 @@ impl Process { match status { 0 => { }, // Success x if x == ERR_TIMED_OUT => { - return Err(io::Error::from(io::ErrorKind::WouldBlock)); + return Ok(None); }, _ => { panic!("Failed to wait on process handle: {}", status); }, } @@ -192,7 +192,7 @@ impl Process { return Err(io::Error::new(io::ErrorKind::InvalidData, "Failed to get exit status of process")); } - Ok(ExitStatus::new(proc_info.rec.return_code)) + Ok(Some(ExitStatus::new(proc_info.rec.return_code))) } } diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 0dc1739c1a1..bbc987209e3 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -249,19 +249,19 @@ impl Process { Ok(ExitStatus::new(status)) } - pub fn try_wait(&mut self) -> io::Result<ExitStatus> { + pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { if let Some(status) = self.status { - return Ok(status) + return Ok(Some(status)) } let mut status = 0 as c_int; let pid = cvt(unsafe { libc::waitpid(self.pid, &mut status, libc::WNOHANG) })?; if pid == 0 { - Err(io::Error::from_raw_os_error(libc::EWOULDBLOCK)) + Ok(None) } else { self.status = Some(ExitStatus::new(status)); - Ok(ExitStatus::new(status)) + Ok(Some(ExitStatus::new(status))) } } } diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index d2ad81023e7..1afb3728c9d 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -340,18 +340,18 @@ impl Process { } } - pub fn try_wait(&mut self) -> io::Result<ExitStatus> { + pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { unsafe { match c::WaitForSingleObject(self.handle.raw(), 0) { c::WAIT_OBJECT_0 => {} c::WAIT_TIMEOUT => { - return Err(io::Error::from_raw_os_error(c::WSAEWOULDBLOCK)) + return Ok(None); } _ => return Err(io::Error::last_os_error()), } let mut status = 0; cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?; - Ok(ExitStatus(status)) + Ok(Some(ExitStatus(status))) } } |
