#![cfg(unix)] use minidl::*; use std::fmt::{self, Debug, Formatter}; use std::io::Result; use std::os::raw::*; #[allow(dead_code)] struct Example { puts: unsafe extern "C" fn (_: *const c_char) -> c_int, invalid_optional: Option c_int>, invalid_required: unsafe extern "C" fn (_: *const c_char) -> c_int, } impl Debug for Example { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { write!(fmt, "Example {{ ... }}") } } impl Example { pub fn new() -> Result { Self::from(Library::load("/lib/x86_64-linux-gnu/libc.so.6")?) } pub fn from(lib: Library) -> Result { unsafe{Ok(Self{ puts: lib.sym("puts\0")?, invalid_optional: lib.sym_opt("invalid_optional\0"), invalid_required: lib.sym("invalid_required\0")?, })} } } #[test] fn bad_load() { let e = Library::load("libdoes_not_exist_invalid.so").expect_err("Invalid SO should've failed to load"); let e = format!("{}", e); assert!(e.contains("does_not_exist_invalid"), "{}", e); } #[test] fn load_unload() { if !std::env::var_os("CI").is_some() { let lib = Library::load("/lib/x86_64-linux-gnu/libc.so.6").expect("loading libc.so.6"); unsafe { lib.close_unsafe_unsound_possible_noop_do_not_use_in_production() }.expect("unloading libc.so.6"); } } #[test] fn bad_sym() { let e = Example::new().expect_err("Example should've failed to load invalid_required"); let e = format!("{}", e); assert!(!e.contains("invalid_optional"), "{}", e); assert!( e.contains("invalid_required"), "{}", e); } #[test] fn ok_sym() { unsafe { let puts : unsafe extern "C" fn (_: *const c_char) -> c_int = Library::load("/lib/x86_64-linux-gnu/libc.so.6").unwrap() .sym("puts\0").unwrap(); puts(b"Hello, world!\0".as_ptr() as _); } }