@@ -129,8 +129,8 @@ fn signaled(status: i32) -> bool {
129
129
unsafe { libc:: WIFSIGNALED ( status) }
130
130
}
131
131
132
- fn term_signal ( status : i32 ) -> Signal {
133
- Signal :: from_c_int ( unsafe { libc:: WTERMSIG ( status) } ) . unwrap ( )
132
+ fn term_signal ( status : i32 ) -> Result < Signal > {
133
+ Signal :: from_c_int ( unsafe { libc:: WTERMSIG ( status) } )
134
134
}
135
135
136
136
fn dumped_core ( status : i32 ) -> bool {
@@ -141,8 +141,8 @@ fn stopped(status: i32) -> bool {
141
141
unsafe { libc:: WIFSTOPPED ( status) }
142
142
}
143
143
144
- fn stop_signal ( status : i32 ) -> Signal {
145
- Signal :: from_c_int ( unsafe { libc:: WSTOPSIG ( status) } ) . unwrap ( )
144
+ fn stop_signal ( status : i32 ) -> Result < Signal > {
145
+ Signal :: from_c_int ( unsafe { libc:: WSTOPSIG ( status) } )
146
146
}
147
147
148
148
fn syscall_stop ( status : i32 ) -> bool {
@@ -161,34 +161,53 @@ fn continued(status: i32) -> bool {
161
161
unsafe { libc:: WIFCONTINUED ( status) }
162
162
}
163
163
164
- fn decode ( pid : Pid , status : i32 ) -> WaitStatus {
165
- if exited ( status) {
166
- WaitStatus :: Exited ( pid, exit_status ( status) )
167
- } else if signaled ( status) {
168
- WaitStatus :: Signaled ( pid, term_signal ( status) , dumped_core ( status) )
169
- } else if stopped ( status) {
170
- cfg_if ! {
171
- if #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ] {
172
- fn decode_stopped( pid: Pid , status: i32 ) -> WaitStatus {
173
- let status_additional = stop_additional( status) ;
174
- if syscall_stop( status) {
175
- WaitStatus :: PtraceSyscall ( pid)
176
- } else if status_additional == 0 {
177
- WaitStatus :: Stopped ( pid, stop_signal( status) )
178
- } else {
179
- WaitStatus :: PtraceEvent ( pid, stop_signal( status) , stop_additional( status) )
164
+ impl WaitStatus {
165
+ /// Convert a raw `wstatus` as returned by `waitpid`/`wait` into a `WaitStatus`
166
+ ///
167
+ /// # Errors
168
+ ///
169
+ /// Returns an `Error` corresponding to `EINVAL` for invalid status values.
170
+ ///
171
+ /// # Examples
172
+ ///
173
+ /// Convert a `wstatus` obtained from `libc::waitpid` into a `WaitStatus`:
174
+ ///
175
+ /// ```
176
+ /// use nix::sys::wait::WaitStatus;
177
+ /// use nix::sys::signal::Signal;
178
+ /// let pid = nix::unistd::Pid::from_raw(1);
179
+ /// let status = WaitStatus::from_raw(pid, 0x0002);
180
+ /// assert_eq!(status, Ok(WaitStatus::Signaled(pid, Signal::SIGINT, false)));
181
+ /// ```
182
+ pub fn from_raw ( pid : Pid , status : i32 ) -> Result < WaitStatus > {
183
+ Ok ( if exited ( status) {
184
+ WaitStatus :: Exited ( pid, exit_status ( status) )
185
+ } else if signaled ( status) {
186
+ WaitStatus :: Signaled ( pid, try!( term_signal ( status) ) , dumped_core ( status) )
187
+ } else if stopped ( status) {
188
+ cfg_if ! {
189
+ if #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ] {
190
+ fn decode_stopped( pid: Pid , status: i32 ) -> Result <WaitStatus > {
191
+ let status_additional = stop_additional( status) ;
192
+ Ok ( if syscall_stop( status) {
193
+ WaitStatus :: PtraceSyscall ( pid)
194
+ } else if status_additional == 0 {
195
+ WaitStatus :: Stopped ( pid, try!( stop_signal( status) ) )
196
+ } else {
197
+ WaitStatus :: PtraceEvent ( pid, try!( stop_signal( status) ) , stop_additional( status) )
198
+ } )
199
+ }
200
+ } else {
201
+ fn decode_stopped( pid: Pid , status: i32 ) -> Result <WaitStatus > {
202
+ Ok ( WaitStatus :: Stopped ( pid, try!( stop_signal( status) ) ) )
180
203
}
181
- }
182
- } else {
183
- fn decode_stopped( pid: Pid , status: i32 ) -> WaitStatus {
184
- WaitStatus :: Stopped ( pid, stop_signal( status) )
185
204
}
186
205
}
187
- }
188
- decode_stopped ( pid , status )
189
- } else {
190
- assert ! ( continued ( status ) ) ;
191
- WaitStatus :: Continued ( pid )
206
+ return decode_stopped ( pid , status ) ;
207
+ } else {
208
+ assert ! ( continued ( status ) ) ;
209
+ WaitStatus :: Continued ( pid )
210
+ } )
192
211
}
193
212
}
194
213
@@ -210,10 +229,10 @@ pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Re
210
229
)
211
230
} ;
212
231
213
- Ok ( match try!( Errno :: result ( res) ) {
214
- 0 => StillAlive ,
215
- res => decode ( Pid :: from_raw ( res) , status) ,
216
- } )
232
+ match try!( Errno :: result ( res) ) {
233
+ 0 => Ok ( StillAlive ) ,
234
+ res => WaitStatus :: from_raw ( Pid :: from_raw ( res) , status) ,
235
+ }
217
236
}
218
237
219
238
pub fn wait ( ) -> Result < WaitStatus > {
0 commit comments