@@ -4,42 +4,26 @@ use unistd::Pid;
4
4
5
5
use sys:: signal:: Signal ;
6
6
7
- mod ffi {
8
- use libc:: { pid_t, c_int} ;
9
-
10
- extern {
11
- pub fn waitpid ( pid : pid_t , status : * mut c_int , options : c_int ) -> pid_t ;
12
- }
13
- }
14
-
15
- #[ cfg( not( any( target_os = "linux" ,
16
- target_os = "android" ) ) ) ]
17
- libc_bitflags ! (
18
- pub struct WaitPidFlag : c_int {
19
- WNOHANG ;
20
- WUNTRACED ;
21
- }
22
- ) ;
23
-
24
- #[ cfg( any( target_os = "linux" ,
25
- target_os = "android" ) ) ]
26
7
libc_bitflags ! (
27
8
pub struct WaitPidFlag : c_int {
28
9
WNOHANG ;
29
10
WUNTRACED ;
30
11
WEXITED ;
31
12
WCONTINUED ;
32
- WNOWAIT ; // Don't reap, just poll status.
33
- __WNOTHREAD; // Don't wait on children of other threads in this group
34
- __WALL; // Wait on all children, regardless of type
13
+ WSTOPPED ;
14
+ /// Don't reap, just poll status.
15
+ WNOWAIT ;
16
+ /// Don't wait on children of other threads in this group
17
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
18
+ __WNOTHREAD;
19
+ /// Wait on all children, regardless of type
20
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
21
+ __WALL;
22
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
35
23
__WCLONE;
36
24
}
37
25
) ;
38
26
39
- #[ cfg( any( target_os = "linux" ,
40
- target_os = "android" ) ) ]
41
- const WSTOPPED : WaitPidFlag = WUNTRACED ;
42
-
43
27
/// Possible return values from `wait()` or `waitpid()`.
44
28
///
45
29
/// Each status (other than `StillAlive`) describes a state transition
@@ -54,7 +38,7 @@ pub enum WaitStatus {
54
38
/// The process exited normally (as with `exit()` or returning from
55
39
/// `main`) with the given exit code. This case matches the C macro
56
40
/// `WIFEXITED(status)`; the second field is `WEXITSTATUS(status)`.
57
- Exited ( Pid , i8 ) ,
41
+ Exited ( Pid , i32 ) ,
58
42
/// The process was killed by the given signal. The third field
59
43
/// indicates whether the signal generated a core dump. This case
60
44
/// matches the C macro `WIFSIGNALED(status)`; the last two fields
@@ -112,179 +96,77 @@ impl WaitStatus {
112
96
}
113
97
}
114
98
115
- #[ cfg( any( target_os = "linux" ,
116
- target_os = "android" ) ) ]
117
- mod status {
118
- use sys:: signal:: Signal ;
119
- use libc:: c_int;
120
- use libc:: SIGTRAP ;
121
-
122
- pub fn exited ( status : i32 ) -> bool {
123
- ( status & 0x7F ) == 0
124
- }
125
-
126
- pub fn exit_status ( status : i32 ) -> i8 {
127
- ( ( status & 0xFF00 ) >> 8 ) as i8
128
- }
129
-
130
- pub fn signaled ( status : i32 ) -> bool {
131
- ( ( ( ( status & 0x7f ) + 1 ) as i8 ) >> 1 ) > 0
132
- }
133
-
134
- pub fn term_signal ( status : i32 ) -> Signal {
135
- Signal :: from_c_int ( status & 0x7f ) . unwrap ( )
136
- }
137
-
138
- pub fn dumped_core ( status : i32 ) -> bool {
139
- ( status & 0x80 ) != 0
140
- }
141
-
142
- pub fn stopped ( status : i32 ) -> bool {
143
- ( status & 0xff ) == 0x7f
144
- }
145
-
146
- pub fn stop_signal ( status : i32 ) -> Signal {
147
- // Keep only 7 bits of the signal: the high bit
148
- // is used to indicate syscall stops, below.
149
- Signal :: from_c_int ( ( status & 0x7F00 ) >> 8 ) . unwrap ( )
150
- }
151
-
152
- pub fn syscall_stop ( status : i32 ) -> bool {
153
- // From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
154
- // of delivering SIGTRAP | 0x80 as the signal number for syscall
155
- // stops. This allows easily distinguishing syscall stops from
156
- // genuine SIGTRAP signals.
157
- ( ( status & 0xFF00 ) >> 8 ) == SIGTRAP | 0x80
158
- }
159
-
160
- pub fn stop_additional ( status : i32 ) -> c_int {
161
- ( status >> 16 ) as c_int
162
- }
163
-
164
- pub fn continued ( status : i32 ) -> bool {
165
- status == 0xFFFF
166
- }
99
+ fn exited ( status : i32 ) -> bool {
100
+ unsafe { libc:: WIFEXITED ( status) }
167
101
}
168
102
169
- #[ cfg( any( target_os = "macos" ,
170
- target_os = "ios" ) ) ]
171
- mod status {
172
- use sys:: signal:: { Signal , SIGCONT } ;
173
-
174
- const WCOREFLAG : i32 = 0x80 ;
175
- const WSTOPPED : i32 = 0x7f ;
176
-
177
- fn wstatus ( status : i32 ) -> i32 {
178
- status & 0x7F
179
- }
180
-
181
- pub fn exit_status ( status : i32 ) -> i8 {
182
- ( ( status >> 8 ) & 0xFF ) as i8
183
- }
184
-
185
- pub fn stop_signal ( status : i32 ) -> Signal {
186
- Signal :: from_c_int ( status >> 8 ) . unwrap ( )
187
- }
188
-
189
- pub fn continued ( status : i32 ) -> bool {
190
- wstatus ( status) == WSTOPPED && stop_signal ( status) == SIGCONT
191
- }
192
-
193
- pub fn stopped ( status : i32 ) -> bool {
194
- wstatus ( status) == WSTOPPED && stop_signal ( status) != SIGCONT
195
- }
196
-
197
- pub fn exited ( status : i32 ) -> bool {
198
- wstatus ( status) == 0
199
- }
200
-
201
- pub fn signaled ( status : i32 ) -> bool {
202
- wstatus ( status) != WSTOPPED && wstatus ( status) != 0
203
- }
204
-
205
- pub fn term_signal ( status : i32 ) -> Signal {
206
- Signal :: from_c_int ( wstatus ( status) ) . unwrap ( )
207
- }
208
-
209
- pub fn dumped_core ( status : i32 ) -> bool {
210
- ( status & WCOREFLAG ) != 0
211
- }
103
+ fn exit_status ( status : i32 ) -> i32 {
104
+ unsafe { libc:: WEXITSTATUS ( status) }
212
105
}
213
106
214
- #[ cfg( any( target_os = "freebsd" ,
215
- target_os = "openbsd" ,
216
- target_os = "dragonfly" ,
217
- target_os = "netbsd" ) ) ]
218
- mod status {
219
- use sys:: signal:: Signal ;
220
-
221
- const WCOREFLAG : i32 = 0x80 ;
222
- const WSTOPPED : i32 = 0x7f ;
223
-
224
- fn wstatus ( status : i32 ) -> i32 {
225
- status & 0x7F
226
- }
227
-
228
- pub fn stopped ( status : i32 ) -> bool {
229
- wstatus ( status) == WSTOPPED
230
- }
107
+ fn signaled ( status : i32 ) -> bool {
108
+ unsafe { libc:: WIFSIGNALED ( status) }
109
+ }
231
110
232
- pub fn stop_signal ( status : i32 ) -> Signal {
233
- Signal :: from_c_int ( status >> 8 ) . unwrap ( )
234
- }
111
+ fn term_signal ( status : i32 ) -> Signal {
112
+ Signal :: from_c_int ( unsafe { libc :: WTERMSIG ( status ) } ) . unwrap ( )
113
+ }
235
114
236
- pub fn signaled ( status : i32 ) -> bool {
237
- wstatus ( status) != WSTOPPED && wstatus ( status ) != 0 && status != 0x13
238
- }
115
+ fn dumped_core ( status : i32 ) -> bool {
116
+ unsafe { libc :: WCOREDUMP ( status) }
117
+ }
239
118
240
- pub fn term_signal ( status : i32 ) -> Signal {
241
- Signal :: from_c_int ( wstatus ( status) ) . unwrap ( )
242
- }
119
+ fn stopped ( status : i32 ) -> bool {
120
+ unsafe { libc :: WIFSTOPPED ( status) }
121
+ }
243
122
244
- pub fn exited ( status : i32 ) -> bool {
245
- wstatus ( status) == 0
246
- }
123
+ fn stop_signal ( status : i32 ) -> Signal {
124
+ Signal :: from_c_int ( unsafe { libc :: WSTOPSIG ( status) } ) . unwrap ( )
125
+ }
247
126
248
- pub fn exit_status ( status : i32 ) -> i8 {
249
- ( status >> 8 ) as i8
250
- }
127
+ fn syscall_stop ( status : i32 ) -> bool {
128
+ // From ptrace(2), setting PTRACE_O_TRACESYSGOOD has the effect
129
+ // of delivering SIGTRAP | 0x80 as the signal number for syscall
130
+ // stops. This allows easily distinguishing syscall stops from
131
+ // genuine SIGTRAP signals.
132
+ unsafe { libc:: WSTOPSIG ( status) == libc:: SIGTRAP | 0x80 }
133
+ }
251
134
252
- pub fn continued ( status : i32 ) -> bool {
253
- status == 0x13
254
- }
135
+ fn stop_additional ( status : i32 ) -> c_int {
136
+ ( status >> 16 ) as c_int
137
+ }
255
138
256
- pub fn dumped_core ( status : i32 ) -> bool {
257
- ( status & WCOREFLAG ) != 0
258
- }
139
+ fn continued ( status : i32 ) -> bool {
140
+ unsafe { libc:: WIFCONTINUED ( status) }
259
141
}
260
142
261
143
fn decode ( pid : Pid , status : i32 ) -> WaitStatus {
262
- if status :: exited ( status) {
263
- WaitStatus :: Exited ( pid, status :: exit_status ( status) )
264
- } else if status :: signaled ( status) {
265
- WaitStatus :: Signaled ( pid, status :: term_signal ( status) , status :: dumped_core ( status) )
266
- } else if status :: stopped ( status) {
144
+ if exited ( status) {
145
+ WaitStatus :: Exited ( pid, exit_status ( status) )
146
+ } else if signaled ( status) {
147
+ WaitStatus :: Signaled ( pid, term_signal ( status) , dumped_core ( status) )
148
+ } else if stopped ( status) {
267
149
cfg_if ! {
268
150
if #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ] {
269
151
fn decode_stopped( pid: Pid , status: i32 ) -> WaitStatus {
270
- let status_additional = status :: stop_additional( status) ;
271
- if status :: syscall_stop( status) {
152
+ let status_additional = stop_additional( status) ;
153
+ if syscall_stop( status) {
272
154
WaitStatus :: PtraceSyscall ( pid)
273
155
} else if status_additional == 0 {
274
- WaitStatus :: Stopped ( pid, status :: stop_signal( status) )
156
+ WaitStatus :: Stopped ( pid, stop_signal( status) )
275
157
} else {
276
- WaitStatus :: PtraceEvent ( pid, status :: stop_signal( status) , status :: stop_additional( status) )
158
+ WaitStatus :: PtraceEvent ( pid, stop_signal( status) , stop_additional( status) )
277
159
}
278
160
}
279
161
} else {
280
162
fn decode_stopped( pid: Pid , status: i32 ) -> WaitStatus {
281
- WaitStatus :: Stopped ( pid, status :: stop_signal( status) )
163
+ WaitStatus :: Stopped ( pid, stop_signal( status) )
282
164
}
283
165
}
284
166
}
285
167
decode_stopped ( pid, status)
286
168
} else {
287
- assert ! ( status :: continued( status) ) ;
169
+ assert ! ( continued( status) ) ;
288
170
WaitStatus :: Continued ( pid)
289
171
}
290
172
}
@@ -299,7 +181,7 @@ pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Re
299
181
None => 0
300
182
} ;
301
183
302
- let res = unsafe { ffi :: waitpid ( pid. into ( ) . unwrap_or ( Pid :: from_raw ( -1 ) ) . into ( ) , & mut status as * mut c_int , option_bits) } ;
184
+ let res = unsafe { libc :: waitpid ( pid. into ( ) . unwrap_or ( Pid :: from_raw ( -1 ) ) . into ( ) , & mut status as * mut c_int , option_bits) } ;
303
185
304
186
Ok ( match try!( Errno :: result ( res) ) {
305
187
0 => StillAlive ,
0 commit comments