summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2017-02-14 15:50:49 +0900
committerHomu <homu@barosl.com>2017-02-14 15:50:49 +0900
commit7a91a816c5f8b8ffbf9bc5798f92ecbb8bbd7713 (patch)
tree1944e8d915c9252cfc22682810610f95799e28f3
parent109b0e867757f377029af84499369812e41cc595 (diff)
parente6bfbbb810ee1c86138ebb6ce8610e403cb83945 (diff)
downloadnix-7a91a816c5f8b8ffbf9bc5798f92ecbb8bbd7713.zip
Auto merge of #438 - chaosagent:wait-ptrace, r=kamalmarhubi
wait: Support ptrace events for Linux Adds new WaitStatus value `PtraceEvent`. Implementation of #273 that only affects Linux/Android.
-rw-r--r--src/sys/wait.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/sys/wait.rs b/src/sys/wait.rs
index 259efb70..7e21339d 100644
--- a/src/sys/wait.rs
+++ b/src/sys/wait.rs
@@ -44,6 +44,8 @@ pub enum WaitStatus {
Exited(pid_t, i8),
Signaled(pid_t, Signal, bool),
Stopped(pid_t, Signal),
+ #[cfg(any(target_os = "linux", target_os = "android"))]
+ PtraceEvent(pid_t, Signal, c_int),
Continued(pid_t),
StillAlive
}
@@ -52,6 +54,7 @@ pub enum WaitStatus {
target_os = "android"))]
mod status {
use sys::signal::Signal;
+ use libc::c_int;
pub fn exited(status: i32) -> bool {
(status & 0x7F) == 0
@@ -81,6 +84,10 @@ mod status {
Signal::from_c_int((status & 0xFF00) >> 8).unwrap()
}
+ pub fn stop_additional(status: i32) -> c_int {
+ (status >> 16) as c_int
+ }
+
pub fn continued(status: i32) -> bool {
status == 0xFFFF
}
@@ -184,7 +191,23 @@ fn decode(pid : pid_t, status: i32) -> WaitStatus {
} else if status::signaled(status) {
WaitStatus::Signaled(pid, status::term_signal(status), status::dumped_core(status))
} else if status::stopped(status) {
- WaitStatus::Stopped(pid, status::stop_signal(status))
+ cfg_if! {
+ if #[cfg(any(target_os = "linux", target_os = "android"))] {
+ fn decode_stopped(pid: pid_t, status: i32) -> WaitStatus {
+ let status_additional = status::stop_additional(status);
+ if status_additional == 0 {
+ WaitStatus::Stopped(pid, status::stop_signal(status))
+ } else {
+ WaitStatus::PtraceEvent(pid, status::stop_signal(status), status::stop_additional(status))
+ }
+ }
+ } else {
+ fn decode_stopped(pid: pid_t, status: i32) -> WaitStatus {
+ WaitStatus::Stopped(pid, status::stop_signal(status))
+ }
+ }
+ }
+ decode_stopped(pid, status)
} else {
assert!(status::continued(status));
WaitStatus::Continued(pid)