Skip to content
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

unistd: Redesign the enum returned by fork() #332

Merged
merged 2 commits into from
Mar 31, 2016
Merged
Show file tree
Hide file tree
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
25 changes: 14 additions & 11 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,36 @@ use std::os::unix::io::RawFd;
pub use self::linux::*;

#[derive(Clone, Copy)]
pub enum Fork {
Parent(pid_t),
pub enum ForkResult {
Parent {
child: pid_t
},
Child
}

impl Fork {
impl ForkResult {
#[inline]
pub fn is_child(&self) -> bool {
match *self {
Fork::Child => true,
ForkResult::Child => true,
_ => false
}
}

#[inline]
pub fn is_parent(&self) -> bool {
match *self {
Fork::Parent(_) => true,
_ => false
}
!self.is_child()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

pub fn is_parent(&self) -> bool {
    !is_child(self)
}

while you're at it? :)

}

pub fn fork() -> Result<Fork> {
#[inline]
pub fn fork() -> Result<ForkResult> {
use self::ForkResult::*;
let res = unsafe { libc::fork() };

Errno::result(res).map(|res| match res {
0 => Fork::Child,
res => Fork::Parent(res)
0 => Child,
res => Parent { child: res }
})
}

Expand Down
12 changes: 6 additions & 6 deletions test/sys/test_wait.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use nix::unistd::*;
use nix::unistd::Fork::*;
use nix::unistd::ForkResult::*;
use nix::sys::signal::*;
use nix::sys::wait::*;
use libc::exit;
Expand All @@ -8,9 +8,9 @@ use libc::exit;
fn test_wait_signal() {
match fork() {
Ok(Child) => pause().unwrap_or(()),
Ok(Parent(child_pid)) => {
kill(child_pid, SIGKILL).ok().expect("Error: Kill Failed");
assert_eq!(waitpid(child_pid, None), Ok(WaitStatus::Signaled(child_pid, SIGKILL, false)));
Ok(Parent { child }) => {
kill(child, SIGKILL).ok().expect("Error: Kill Failed");
assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, SIGKILL, false)));
},
// panic, fork should never fail unless there is a serious problem with the OS
Err(_) => panic!("Error: Fork Failed")
Expand All @@ -21,8 +21,8 @@ fn test_wait_signal() {
fn test_wait_exit() {
match fork() {
Ok(Child) => unsafe { exit(12); },
Ok(Parent(child_pid)) => {
assert_eq!(waitpid(child_pid, None), Ok(WaitStatus::Exited(child_pid, 12)));
Ok(Parent { child }) => {
assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
},
// panic, fork should never fail unless there is a serious problem with the OS
Err(_) => panic!("Error: Fork Failed")
Expand Down
6 changes: 3 additions & 3 deletions test/test_mq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::str;
use libc::c_long;

use nix::unistd::{fork, read, write, pipe};
use nix::unistd::Fork::{Child, Parent};
use nix::unistd::ForkResult::*;
use nix::sys::wait::*;
use nix::errno::Errno::*;
use nix::Error::Sys;
Expand Down Expand Up @@ -37,11 +37,11 @@ fn test_mq_send_and_receive() {
write(writer, &buf).unwrap(); // pipe result to parent process. Otherwise cargo does not report test failures correctly
mq_close(mqd_in_child).unwrap();
}
Ok(Parent(child_pid)) => {
Ok(Parent { child }) => {
mq_close(mqd_in_parent).unwrap();

// Wait for the child to exit.
waitpid(child_pid, None).unwrap();
waitpid(child, None).unwrap();
// Read 1024 bytes.
let mut read_buf = [0u8; 32];
read(reader, &mut read_buf).unwrap();
Expand Down
18 changes: 9 additions & 9 deletions test/test_unistd.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use nix::unistd::*;
use nix::unistd::Fork::*;
use nix::unistd::ForkResult::*;
use nix::sys::wait::*;
use std::ffi::CString;

Expand All @@ -8,13 +8,13 @@ fn test_fork_and_waitpid() {
let pid = fork();
match pid {
Ok(Child) => {} // ignore child here
Ok(Parent(child_pid)) => {
Ok(Parent { child }) => {
// assert that child was created and pid > 0
assert!(child_pid > 0);
let wait_status = waitpid(child_pid, None);
assert!(child > 0);
let wait_status = waitpid(child, None);
match wait_status {
// assert that waitpid returned correct status and the pid is the one of the child
Ok(WaitStatus::Exited(pid_t, _)) => assert!(pid_t == child_pid),
Ok(WaitStatus::Exited(pid_t, _)) => assert!(pid_t == child),

// panic, must never happen
Ok(_) => panic!("Child still alive, should never happen"),
Expand All @@ -34,11 +34,11 @@ fn test_wait() {
let pid = fork();
match pid {
Ok(Child) => {} // ignore child here
Ok(Parent(child_pid)) => {
Ok(Parent { child }) => {
let wait_status = wait();

// just assert that (any) one child returns with WaitStatus::Exited
assert_eq!(wait_status, Ok(WaitStatus::Exited(child_pid, 0)));
assert_eq!(wait_status, Ok(WaitStatus::Exited(child, 0)));
},
// panic, fork should never fail unless there is a serious problem with the OS
Err(_) => panic!("Error: Fork Failed")
Expand Down Expand Up @@ -95,9 +95,9 @@ macro_rules! execve_test_factory(
&[CString::new(b"foo=bar".as_ref()).unwrap(),
CString::new(b"baz=quux".as_ref()).unwrap()]).unwrap();
},
Parent(child_pid) => {
Parent { child } => {
// Wait for the child to exit.
waitpid(child_pid, None).unwrap();
waitpid(child, None).unwrap();
// Read 1024 bytes.
let mut buf = [0u8; 1024];
read(reader, &mut buf).unwrap();
Expand Down