Skip to content

Commit

Permalink
Auto merge of #332 - kamalmarhubi:fork-enum, r=fiveop
Browse files Browse the repository at this point in the history
unistd: Redesign the enum returned by fork()

This changes the name of the enum returned by `fork()` to `ForkResult`,
and changes the `Parent` variant to be struct-like.

The result can be matched like

    use nix::unistd::ForkResult::*;
    match fork().unwrap() {
        Parent { child } => { ... }
        Child => { ... }
    }

using the shorthand matching syntax for struct-like enum variants.

This is a breaking change.
  • Loading branch information
homu committed Mar 31, 2016
2 parents 3fe0503 + c2f8bb7 commit 4ca407d
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 29 deletions.
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()
}
}

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

0 comments on commit 4ca407d

Please sign in to comment.