Skip to content

waitpid() now has target pid as an enum. Resolves #840. #848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/sys/wait.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use libc::{self, c_int};
use std::convert::{From, Into};

use libc::{self, c_int, pid_t};
use Result;
use errno::Errno;
use unistd::Pid;
Expand Down Expand Up @@ -46,6 +48,30 @@ libc_bitflags!(
}
);

/// Possible child targets of`waitpid()`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space here.

///
/// The most common variants for waiting are waiting
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap these comments a little longer so they match the wrapping elsewhere in the file (usually 79 or 99 characters)

/// for a specific child via `WaitPid::Child(pid)` and
/// waiting for any child via `WaitPid::AnyChild`.
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
pub enum WaitTarget {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern with this enum is that constructing it allows for negative values in places where negative values shouldn't be allowed. This should be explicitly disallowed, but I'm not certain what the most Rustic way to do this is.

/// Waiting for a child with `Pid` process id.
Child(Pid),
/// Waiting for a child of the same process group as the calling process.
ThisGroupChild,
/// Waiting for any child.
AnyChild,
/// Waiting for a child of process group `Pid` (NB: do not negate this value,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does NB here mean?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's Nota Bene. I'll replace it with "please, note" since it adds confusion.

/// just use process id of the group leader).
ChildOfGroup(Pid),
}

impl From<Pid> for WaitTarget {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want this to follow the mapping that waitpid uses internally, where only positive PID values are mapped to WaitTarget::Child, the other 3 mappings should also be here. This should make waitpid work safely with current code. Additionally it should make this a backwards-compatible change.

fn from(pid: Pid) -> WaitTarget {
WaitTarget::Child(pid)
}
}

/// Possible return values from `wait()` or `waitpid()`.
///
/// Each status (other than `StillAlive`) describes a state transition
Expand Down Expand Up @@ -207,7 +233,7 @@ impl WaitStatus {
}
}

pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Result<WaitStatus> {
pub fn waitpid<P: Into<WaitTarget>>(who: P, options: Option<WaitPidFlag>) -> Result<WaitStatus> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide docs for waitpid here? I think it's important to note in them that passing a straight Pid translates to WaitTarget::Child(Pid)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can reference #645 so it should be pretty easy.

use self::WaitStatus::*;

let mut status: i32 = 0;
Expand All @@ -217,9 +243,17 @@ pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Re
None => 0,
};

let who: WaitTarget = who.into();
let pid: pid_t = match who {
WaitTarget::Child(pid) => pid.into(),
WaitTarget::ThisGroupChild => 0,
WaitTarget::AnyChild => -1,
WaitTarget::ChildOfGroup(pid) => { let pid: pid_t = pid.into(); -pid },
};

let res = unsafe {
libc::waitpid(
pid.into().unwrap_or(Pid::from_raw(-1)).into(),
pid,
&mut status as *mut c_int,
option_bits,
)
Expand All @@ -232,5 +266,5 @@ pub fn waitpid<P: Into<Option<Pid>>>(pid: P, options: Option<WaitPidFlag>) -> Re
}

pub fn wait() -> Result<WaitStatus> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add docs for this function as well.

waitpid(None, None)
waitpid(WaitTarget::AnyChild, None)
}