pub mod door_h;
pub mod stropts_h;
use libc;
pub fn errno() -> libc::c_int {
unsafe{ *libc::___errno() }
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use std::path::Path;
use std::ptr;
use std::ffi::{CStr,CString};
#[test]
fn errno_works() {
let badpath = CString::new("<(^_^)>").unwrap();
assert_eq!(unsafe{ libc::open(badpath.as_ptr(), libc::O_RDONLY) }, -1);
assert_eq!(errno(), libc::ENOENT);
}
#[test]
fn can_invoke_own_door() {
extern "C" fn capitalize_string(
_cookie: *const libc::c_void,
argp: *const libc::c_char,
arg_size: libc::size_t,
_dp: *const door_h::door_desc_t,
_n_desc: libc::c_uint,
) {
let original = unsafe { CStr::from_ptr(argp) };
let original = original.to_str().unwrap();
let capitalized = original.to_ascii_uppercase();
let capitalized = CString::new(capitalized).unwrap();
unsafe { door_h::door_return(capitalized.as_ptr(), arg_size, ptr::null(), 0) };
};
let door_path = Path::new("/tmp/relaydoors_test_f431a5");
if door_path.exists() {
fs::remove_file(door_path).unwrap();
}
let door_path_cstring = CString::new(door_path.to_str().unwrap()).unwrap();
unsafe {
let server_door_fd = door_h::door_create(capitalize_string, ptr::null(), 0);
fs::File::create(door_path).unwrap();
stropts_h::fattach(server_door_fd, door_path_cstring.as_ptr());
}
let original = CString::new("hello world").unwrap();
unsafe {
let client_door_fd = libc::open(door_path_cstring.as_ptr(), libc::O_RDONLY);
let data_ptr = original.as_ptr();
let data_size = 12;
let desc_ptr = ptr::null();
let desc_num = 0;
let rbuf = libc::malloc(data_size) as *mut libc::c_char;
let rsize = data_size;
let params = door_h::door_arg_t {
data_ptr,
data_size,
desc_ptr,
desc_num,
rbuf,
rsize
};
door_h::door_call(client_door_fd, ¶ms);
let capitalized = CStr::from_ptr(rbuf);
let capitalized = capitalized.to_str().unwrap();
assert_eq!(capitalized, "HELLO WORLD");
libc::free(rbuf as *mut libc::c_void);
}
fs::remove_file(door_path).unwrap();
}
}