diff --git a/dlopen2/src/raw/common.rs b/dlopen2/src/raw/common.rs index add5e28..17e0d77 100644 --- a/dlopen2/src/raw/common.rs +++ b/dlopen2/src/raw/common.rs @@ -65,7 +65,41 @@ impl Library { S: AsRef, { Ok(Self { - handle: unsafe { open_lib(name.as_ref()) }?, + handle: unsafe { open_lib(name.as_ref(), None) }?, + }) + } + + /** + Open a dynamic library with flags + + **Note:** different platforms search for libraries in different directories. + Therefore this function cannot be 100% platform independent. + However it seems that all platforms support the full path and + searching in default os directories if you provide only the file name. + Please refer to your operating system guide for precise information about the directories + where the operating system searches for dynamic link libraries. + + Currently, flags only impact loading of libraries on unix-like platforms. + + # Example + + ```no_run + use dlopen2::raw::Library; + + fn main() { + //use full path + let lib = Library::open_with_flags("/lib/i386-linux-gnu/libm.so.6", None).unwrap(); + //use only file name + let lib = Library::open("libm.so.6").unwrap(); + } + ``` + */ + pub fn open_with_flags(name: S, flags: Option) -> Result + where + S: AsRef, + { + Ok(Self { + handle: unsafe { open_lib(name.as_ref(), flags) }?, }) } diff --git a/dlopen2/src/raw/tests.rs b/dlopen2/src/raw/tests.rs index bff87de..8f16880 100644 --- a/dlopen2/src/raw/tests.rs +++ b/dlopen2/src/raw/tests.rs @@ -24,7 +24,7 @@ const_cstr! {NOT_EXISTING_SYM = "notexisting";} #[test] fn load_get_close() { unsafe { - let handle = open_lib(EXISTING_LIB.as_ref()).expect("Could not open library"); + let handle = open_lib(EXISTING_LIB.as_ref(), None).expect("Could not open library"); let sym = get_sym(handle, EXISTING_SYM.as_cstr()).expect("Could not get symbol"); assert!(!sym.is_null()); assert!(close_lib(handle).is_null()); @@ -34,7 +34,7 @@ fn load_get_close() { #[test] fn open_err() { unsafe { - match open_lib(NOT_EXISTING_LIB.as_ref()) { + match open_lib(NOT_EXISTING_LIB.as_ref(), None) { Ok(_) => panic!("Library should not get opened"), Err(err) => match err { Error::OpeningLibraryError(_) => (), @@ -47,7 +47,7 @@ fn open_err() { #[test] fn get_err() { unsafe { - let handle = open_lib(EXISTING_LIB.as_ref()).expect("Could not open library"); + let handle = open_lib(EXISTING_LIB.as_ref(), None).expect("Could not open library"); match get_sym(handle, NOT_EXISTING_SYM.as_cstr()) { Ok(_) => panic!("Should not get the symbol"), Err(err) => match err { diff --git a/dlopen2/src/raw/unix.rs b/dlopen2/src/raw/unix.rs index 0ed5624..5d68ace 100644 --- a/dlopen2/src/raw/unix.rs +++ b/dlopen2/src/raw/unix.rs @@ -64,7 +64,7 @@ pub unsafe fn open_self() -> Result { } #[inline] -pub unsafe fn open_lib(name: &OsStr) -> Result { +pub unsafe fn open_lib(name: &OsStr, flags: Option) -> Result { let mut v: Vec = Vec::new(); //as_bytes i a unix-specific extension let cstr = if !name.is_empty() && name.as_bytes()[name.len() - 1] == 0 { @@ -77,7 +77,7 @@ pub unsafe fn open_lib(name: &OsStr) -> Result { CStr::from_bytes_with_nul_unchecked(v.as_slice()) }; let _lock = lock_dlerror_mutex(); - let handle = dlopen(cstr.as_ptr(), DEFAULT_FLAGS); + let handle = dlopen(cstr.as_ptr(), flags.unwrap_or(DEFAULT_FLAGS)); if handle.is_null() { Err(Error::OpeningLibraryError(IoError::new( ErrorKind::Other, diff --git a/dlopen2/src/raw/windows.rs b/dlopen2/src/raw/windows.rs index 504daa1..0058c80 100644 --- a/dlopen2/src/raw/windows.rs +++ b/dlopen2/src/raw/windows.rs @@ -154,7 +154,7 @@ pub unsafe fn open_self() -> Result { } #[inline] -pub unsafe fn open_lib(name: &OsStr) -> Result { +pub unsafe fn open_lib(name: &OsStr, _flags: Option) -> Result { let wide_name: Vec = name.encode_wide().chain(Some(0)).collect(); let _guard = match ErrorModeGuard::new() { Ok(val) => val, diff --git a/dlopen2/src/wrapper/container.rs b/dlopen2/src/wrapper/container.rs index 57a97e7..916def3 100644 --- a/dlopen2/src/wrapper/container.rs +++ b/dlopen2/src/wrapper/container.rs @@ -74,6 +74,16 @@ where let api = T::load(&lib)?; Ok(Self { lib, api }) } + + ///Same as load(), except specify flags used by libc::dlopen + pub unsafe fn load_with_flags(name: S, flags: Option) -> Result, Error> + where + S: AsRef, + { + let lib = Library::open_with_flags(name, flags)?; + let api = T::load(&lib)?; + Ok(Self { lib, api }) + } } impl Deref for Container diff --git a/dlopen2/src/wrapper/optional.rs b/dlopen2/src/wrapper/optional.rs index 61b1ff7..8d4e17c 100644 --- a/dlopen2/src/wrapper/optional.rs +++ b/dlopen2/src/wrapper/optional.rs @@ -78,6 +78,18 @@ where Ok(Self { lib, api, optional }) } + ///Opens the library using provided file name or path and flags, and loads all symbols (including optional + ///if it is possible). + pub unsafe fn load_with_flags(name: S, flags: Option) -> Result, Error> + where + S: AsRef, + { + let lib = Library::open_with_flags(name, flags)?; + let api = Api::load(&lib)?; + let optional = Optional::load(&lib).ok(); + Ok(Self { lib, api, optional }) + } + ///Load all symbols (including optional if it is possible) from the ///program itself. ///