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