Skip to content

Commit 2c7796a

Browse files
authored
Rollup merge of rust-lang#64787 - tmandry:fuchsia-exitstatus, r=cramertj
Fix ExitStatus on Fuchsia Fuchsia exit codes don't follow the convention of libc::WEXITSTATUS et al, and they are 64 bits instead of 32 bits. This gives Fuchsia its own representation of ExitStatus. Additionally, the zircon syscall structs were out of date, causing us to see bogus exit codes. r? @cramertj @alexcrichton
2 parents 64e8527 + 80db06d commit 2c7796a

File tree

5 files changed

+93
-75
lines changed

5 files changed

+93
-75
lines changed

src/libstd/sys/unix/process/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
2-
pub use self::process_inner::Process;
1+
pub use self::process_common::{Command, ExitCode, Stdio, StdioPipes};
2+
pub use self::process_inner::{ExitStatus, Process};
33
pub use crate::ffi::OsString as EnvKey;
44

55
mod process_common;

src/libstd/sys/unix/process/process_common.rs

-51
Original file line numberDiff line numberDiff line change
@@ -393,57 +393,6 @@ impl fmt::Debug for Command {
393393
}
394394
}
395395

396-
/// Unix exit statuses
397-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
398-
pub struct ExitStatus(c_int);
399-
400-
impl ExitStatus {
401-
pub fn new(status: c_int) -> ExitStatus {
402-
ExitStatus(status)
403-
}
404-
405-
fn exited(&self) -> bool {
406-
unsafe { libc::WIFEXITED(self.0) }
407-
}
408-
409-
pub fn success(&self) -> bool {
410-
self.code() == Some(0)
411-
}
412-
413-
pub fn code(&self) -> Option<i32> {
414-
if self.exited() {
415-
Some(unsafe { libc::WEXITSTATUS(self.0) })
416-
} else {
417-
None
418-
}
419-
}
420-
421-
pub fn signal(&self) -> Option<i32> {
422-
if !self.exited() {
423-
Some(unsafe { libc::WTERMSIG(self.0) })
424-
} else {
425-
None
426-
}
427-
}
428-
}
429-
430-
impl From<c_int> for ExitStatus {
431-
fn from(a: c_int) -> ExitStatus {
432-
ExitStatus(a)
433-
}
434-
}
435-
436-
impl fmt::Display for ExitStatus {
437-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
438-
if let Some(code) = self.code() {
439-
write!(f, "exit code: {}", code)
440-
} else {
441-
let signal = self.signal().unwrap();
442-
write!(f, "signal: {}", signal)
443-
}
444-
}
445-
}
446-
447396
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
448397
pub struct ExitCode(u8);
449398

src/libstd/sys/unix/process/process_fuchsia.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use crate::convert::TryInto;
12
use crate::io;
3+
use crate::fmt;
24
use crate::mem;
35
use crate::ptr;
46

57
use crate::sys::process::zircon::{Handle, zx_handle_t};
68
use crate::sys::process::process_common::*;
79

8-
use libc::size_t;
10+
use libc::{c_int, size_t};
911

1012
////////////////////////////////////////////////////////////////////////////////
1113
// Command
@@ -160,7 +162,7 @@ impl Process {
160162
return Err(io::Error::new(io::ErrorKind::InvalidData,
161163
"Failed to get exit status of process"));
162164
}
163-
Ok(ExitStatus::new(proc_info.rec.return_code))
165+
Ok(ExitStatus(proc_info.return_code))
164166
}
165167

166168
pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
@@ -190,6 +192,36 @@ impl Process {
190192
return Err(io::Error::new(io::ErrorKind::InvalidData,
191193
"Failed to get exit status of process"));
192194
}
193-
Ok(Some(ExitStatus::new(proc_info.rec.return_code)))
195+
Ok(Some(ExitStatus(proc_info.return_code)))
196+
}
197+
}
198+
199+
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
200+
pub struct ExitStatus(i64);
201+
202+
impl ExitStatus {
203+
pub fn success(&self) -> bool {
204+
self.code() == Some(0)
205+
}
206+
207+
pub fn code(&self) -> Option<i32> {
208+
// FIXME: support extracting return code as an i64
209+
self.0.try_into().ok()
210+
}
211+
212+
pub fn signal(&self) -> Option<i32> {
213+
None
214+
}
215+
}
216+
217+
impl From<c_int> for ExitStatus {
218+
fn from(a: c_int) -> ExitStatus {
219+
ExitStatus(a as i64)
220+
}
221+
}
222+
223+
impl fmt::Display for ExitStatus {
224+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225+
write!(f, "exit code: {}", self.0)
194226
}
195227
}

src/libstd/sys/unix/process/process_unix.rs

+52
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::fmt;
12
use crate::io::{self, Error, ErrorKind};
23
use crate::ptr;
34
use crate::sys::cvt;
@@ -441,3 +442,54 @@ impl Process {
441442
}
442443
}
443444
}
445+
446+
/// Unix exit statuses
447+
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
448+
pub struct ExitStatus(c_int);
449+
450+
impl ExitStatus {
451+
pub fn new(status: c_int) -> ExitStatus {
452+
ExitStatus(status)
453+
}
454+
455+
fn exited(&self) -> bool {
456+
unsafe { libc::WIFEXITED(self.0) }
457+
}
458+
459+
pub fn success(&self) -> bool {
460+
self.code() == Some(0)
461+
}
462+
463+
pub fn code(&self) -> Option<i32> {
464+
if self.exited() {
465+
Some(unsafe { libc::WEXITSTATUS(self.0) })
466+
} else {
467+
None
468+
}
469+
}
470+
471+
pub fn signal(&self) -> Option<i32> {
472+
if !self.exited() {
473+
Some(unsafe { libc::WTERMSIG(self.0) })
474+
} else {
475+
None
476+
}
477+
}
478+
}
479+
480+
impl From<c_int> for ExitStatus {
481+
fn from(a: c_int) -> ExitStatus {
482+
ExitStatus(a)
483+
}
484+
}
485+
486+
impl fmt::Display for ExitStatus {
487+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
488+
if let Some(code) = self.code() {
489+
write!(f, "exit code: {}", code)
490+
} else {
491+
let signal = self.signal().unwrap();
492+
write!(f, "signal: {}", signal)
493+
}
494+
}
495+
}

src/libstd/sys/unix/process/zircon.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -65,29 +65,14 @@ impl Drop for Handle {
6565
}
6666
}
6767

68-
// Common ZX_INFO header
69-
#[derive(Default)]
70-
#[repr(C)]
71-
pub struct zx_info_header_t {
72-
pub topic: u32, // identifies the info struct
73-
pub avail_topic_size: u16, // “native” size of the struct
74-
pub topic_size: u16, // size of the returned struct (<=topic_size)
75-
pub avail_count: u32, // number of records the kernel has
76-
pub count: u32, // number of records returned (limited by buffer size)
77-
}
78-
79-
#[derive(Default)]
80-
#[repr(C)]
81-
pub struct zx_record_process_t {
82-
pub return_code: c_int,
83-
}
84-
8568
// Returned for topic ZX_INFO_PROCESS
8669
#[derive(Default)]
8770
#[repr(C)]
8871
pub struct zx_info_process_t {
89-
pub hdr: zx_info_header_t,
90-
pub rec: zx_record_process_t,
72+
pub return_code: i64,
73+
pub started: bool,
74+
pub exited: bool,
75+
pub debugger_attached: bool,
9176
}
9277

9378
extern {

0 commit comments

Comments
 (0)