diff --git a/Cargo.toml b/Cargo.toml index 6987c7f..cacc948 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,8 @@ description = "An API to POSIX IPC primitives" repository = "http://github.com/codius/rust-posix-ipc" license = "MIT" readme = "README.md" + +[dependencies] +enum_primitive = "0.0.2" +num = "0.1.24" +libc = "0.1.7" diff --git a/src/lib.rs b/src/lib.rs index d14adcb..4d86e95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,12 @@ -#![feature(trace_macros)] +#![feature(trace_macros,alloc)] +#[macro_use] extern crate enum_primitive; pub mod signals { extern crate libc; - use std::os; + use std::io; use std::mem; - #[derive(Hash, Eq, PartialEq, Copy, Debug, FromPrimitive)] + enum_from_primitive! { + #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)] pub enum Signal { None = 0, Hup, @@ -39,25 +41,26 @@ pub mod signals { Pwr, Sys } + } impl Signal { - pub fn raise(self) -> Result<(), usize> { + pub fn raise(self) -> Result<(), libc::c_int> { match unsafe { raise(self as libc::c_int) } { 0 => Result::Ok(()), - _ => Result::Err(os::errno()) + _ => Result::Err(io::Error::last_os_error().raw_os_error().unwrap()) } } - pub fn kill(self, pid: libc::pid_t) -> Result<(), usize> { + pub fn kill(self, pid: libc::pid_t) -> Result<(), libc::c_int> { match unsafe { kill(pid, self as libc::c_int) } { 0 => Result::Ok(()), - _ => Result::Err(os::errno()) + _ => Result::Err(io::Error::last_os_error().raw_os_error().unwrap()) } } - pub unsafe fn handle(self, handler: Box) -> Result<(), usize> { - match unsafe { signal (self as libc::c_int, mem::transmute(glue::rust_signal_handler)) } { - -1 => Result::Err(os::errno()), + pub unsafe fn handle(self, handler: Box) -> Result<(), libc::c_int> { + match signal (self as libc::c_int, mem::transmute(glue::rust_signal_handler)) { + -1 => Result::Err(io::Error::last_os_error().raw_os_error().unwrap()), _ => { glue::set_handler(self, handler); Result::Ok(()) } } } @@ -66,14 +69,12 @@ pub mod signals { mod glue { extern crate libc; extern crate alloc; + extern crate num; + use self::num::FromPrimitive; use super::Signal; - use std::num::FromPrimitive; - use self::alloc::arc::Arc; - use std::rc::Rc; use std::mem; - use std::ptr; - #[derive(Copy,Debug)] + #[derive(Copy, Clone, Debug)] struct FnPtr { foo: usize, bar: usize @@ -104,13 +105,11 @@ pub mod signals { handlers[sig as usize] = mem::transmute(f); } - fn null_handler(s: Signal) {} - pub unsafe extern "C" fn rust_signal_handler(sig: libc::c_int) { let f: *mut FnMut(Signal) = mem::transmute(handlers[sig as usize]); let p: FnPtr = mem::transmute(f); if p.foo != 0 && p.bar != 0 { - match FromPrimitive::from_i32(sig) { + match Signal::from_i32(sig) { Some(s) => (*f)(s), None => panic!("Unknown signal {}", sig) } diff --git a/tests/tests.rs b/tests/tests.rs index 0c35ca0..bfe471e 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,18 +1,28 @@ -extern crate "posix-ipc" as ipc; +#![feature(std_misc)] +extern crate posix_ipc as ipc; use ipc::signals; +use std::thread; +use std::sync::{Arc, Semaphore, Mutex}; #[test] fn raise_and_catch_with_closure() { - let mut caught = false; + let mut caught: Arc> = Arc::new(Mutex::new(false)); + let mut sem: Arc = Arc::new(Semaphore::new(1)); + sem.acquire(); { - let f = |Signal| {caught = true;println!("Caught!")}; + let sem = sem.clone(); + let caught = caught.clone(); + let f = move |s: signals::Signal| { + *caught.lock().unwrap() = true; sem.release() + }; unsafe { - signals::Signal::Usr1.handle(Box::new(f)); + signals::Signal::Usr1.handle(Box::new(f)).unwrap(); } } - signals::Signal::Usr1.raise(); - assert!(unsafe { caught }); + signals::Signal::Usr1.raise().unwrap(); + sem.acquire(); + assert!(*caught.lock().unwrap()); } #[test] @@ -21,9 +31,10 @@ fn raise_and_catch_with_func() { { fn f(s: signals::Signal) {unsafe { caught = true }} unsafe { - signals::Signal::Usr1.handle(Box::new(f)); + signals::Signal::Usr1.handle(Box::new(f)).unwrap(); } } - signals::Signal::Usr1.raise(); + signals::Signal::Usr1.raise().unwrap(); + thread::sleep_ms(500); // this is really racy :( assert!(unsafe { caught }); }