8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ #![ allow( non_snake_case) ]
12
+
11
13
use prelude:: v1:: * ;
12
14
use os:: unix:: prelude:: * ;
13
15
@@ -84,33 +86,62 @@ impl Command {
84
86
85
87
/// Unix exit statuses
86
88
#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
87
- pub enum ExitStatus {
88
- /// Normal termination with an exit code.
89
- Code ( i32 ) ,
90
-
91
- /// Termination by signal, with the signal number.
92
- ///
93
- /// Never generated on Windows.
94
- Signal ( i32 ) ,
89
+ pub struct ExitStatus ( c_int ) ;
90
+
91
+ #[ cfg( any( target_os = "linux" , target_os = "android" ,
92
+ target_os = "nacl" ) ) ]
93
+ mod status_imp {
94
+ pub fn WIFEXITED ( status : i32 ) -> bool { ( status & 0xff ) == 0 }
95
+ pub fn WEXITSTATUS ( status : i32 ) -> i32 { ( status >> 8 ) & 0xff }
96
+ pub fn WTERMSIG ( status : i32 ) -> i32 { status & 0x7f }
97
+ }
98
+
99
+ #[ cfg( any( target_os = "macos" ,
100
+ target_os = "ios" ,
101
+ target_os = "freebsd" ,
102
+ target_os = "dragonfly" ,
103
+ target_os = "bitrig" ,
104
+ target_os = "netbsd" ,
105
+ target_os = "openbsd" ) ) ]
106
+ mod status_imp {
107
+ pub fn WIFEXITED ( status : i32 ) -> bool { ( status & 0x7f ) == 0 }
108
+ pub fn WEXITSTATUS ( status : i32 ) -> i32 { status >> 8 }
109
+ pub fn WTERMSIG ( status : i32 ) -> i32 { status & 0o177 }
95
110
}
96
111
97
112
impl ExitStatus {
113
+ fn exited ( & self ) -> bool {
114
+ status_imp:: WIFEXITED ( self . 0 )
115
+ }
116
+
98
117
pub fn success ( & self ) -> bool {
99
- * self == ExitStatus :: Code ( 0 )
118
+ self . code ( ) == Some ( 0 )
100
119
}
120
+
101
121
pub fn code ( & self ) -> Option < i32 > {
102
- match * self {
103
- ExitStatus :: Code ( c) => Some ( c) ,
104
- _ => None
122
+ if self . exited ( ) {
123
+ Some ( status_imp:: WEXITSTATUS ( self . 0 ) )
124
+ } else {
125
+ None
126
+ }
127
+ }
128
+
129
+ pub fn signal ( & self ) -> Option < i32 > {
130
+ if !self . exited ( ) {
131
+ Some ( status_imp:: WTERMSIG ( self . 0 ) )
132
+ } else {
133
+ None
105
134
}
106
135
}
107
136
}
108
137
109
138
impl fmt:: Display for ExitStatus {
110
139
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
111
- match * self {
112
- ExitStatus :: Code ( code) => write ! ( f, "exit code: {}" , code) ,
113
- ExitStatus :: Signal ( code) => write ! ( f, "signal: {}" , code) ,
140
+ if let Some ( code) = self . code ( ) {
141
+ write ! ( f, "exit code: {}" , code)
142
+ } else {
143
+ let signal = self . signal ( ) . unwrap ( ) ;
144
+ write ! ( f, "signal: {}" , signal)
114
145
}
115
146
}
116
147
}
@@ -351,7 +382,7 @@ impl Process {
351
382
pub fn wait ( & self ) -> io:: Result < ExitStatus > {
352
383
let mut status = 0 as c_int ;
353
384
try!( cvt_r ( || unsafe { c:: waitpid ( self . pid , & mut status, 0 ) } ) ) ;
354
- Ok ( translate_status ( status) )
385
+ Ok ( ExitStatus ( status) )
355
386
}
356
387
357
388
pub fn try_wait ( & self ) -> Option < ExitStatus > {
@@ -360,7 +391,7 @@ impl Process {
360
391
c:: waitpid ( self . pid , & mut status, c:: WNOHANG )
361
392
} ) {
362
393
Ok ( 0 ) => None ,
363
- Ok ( n) if n == self . pid => Some ( translate_status ( status) ) ,
394
+ Ok ( n) if n == self . pid => Some ( ExitStatus ( status) ) ,
364
395
Ok ( n) => panic ! ( "unknown pid: {}" , n) ,
365
396
Err ( e) => panic ! ( "unknown waitpid error: {}" , e) ,
366
397
}
@@ -418,36 +449,6 @@ fn make_envp(env: Option<&HashMap<OsString, OsString>>)
418
449
}
419
450
}
420
451
421
- fn translate_status ( status : c_int ) -> ExitStatus {
422
- #![ allow( non_snake_case) ]
423
- #[ cfg( any( target_os = "linux" , target_os = "android" ,
424
- target_os = "nacl" ) ) ]
425
- mod imp {
426
- pub fn WIFEXITED ( status : i32 ) -> bool { ( status & 0xff ) == 0 }
427
- pub fn WEXITSTATUS ( status : i32 ) -> i32 { ( status >> 8 ) & 0xff }
428
- pub fn WTERMSIG ( status : i32 ) -> i32 { status & 0x7f }
429
- }
430
-
431
- #[ cfg( any( target_os = "macos" ,
432
- target_os = "ios" ,
433
- target_os = "freebsd" ,
434
- target_os = "dragonfly" ,
435
- target_os = "bitrig" ,
436
- target_os = "netbsd" ,
437
- target_os = "openbsd" ) ) ]
438
- mod imp {
439
- pub fn WIFEXITED ( status : i32 ) -> bool { ( status & 0x7f ) == 0 }
440
- pub fn WEXITSTATUS ( status : i32 ) -> i32 { status >> 8 }
441
- pub fn WTERMSIG ( status : i32 ) -> i32 { status & 0o177 }
442
- }
443
-
444
- if imp:: WIFEXITED ( status) {
445
- ExitStatus :: Code ( imp:: WEXITSTATUS ( status) )
446
- } else {
447
- ExitStatus :: Signal ( imp:: WTERMSIG ( status) )
448
- }
449
- }
450
-
451
452
#[ cfg( test) ]
452
453
mod tests {
453
454
use super :: * ;
0 commit comments