Skip to content

Commit

Permalink
Merge pull request #7 from whereskenneth/expose-dlopen-flags
Browse files Browse the repository at this point in the history
Exposes libc::dlopen flags for unix platform.
  • Loading branch information
OpenByteDev committed Feb 6, 2024
2 parents 8580a7c + 8ce21a7 commit c50e261
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 7 deletions.
36 changes: 35 additions & 1 deletion dlopen2/src/raw/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,41 @@ impl Library {
S: AsRef<OsStr>,
{
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<S>(name: S, flags: Option<i32>) -> Result<Library, Error>
where
S: AsRef<OsStr>,
{
Ok(Self {
handle: unsafe { open_lib(name.as_ref(), flags) }?,
})
}

Expand Down
6 changes: 3 additions & 3 deletions dlopen2/src/raw/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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(_) => (),
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions dlopen2/src/raw/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub unsafe fn open_self() -> Result<Handle, Error> {
}

#[inline]
pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {
pub unsafe fn open_lib(name: &OsStr, flags: Option<i32>) -> Result<Handle, Error> {
let mut v: Vec<u8> = Vec::new();
//as_bytes i a unix-specific extension
let cstr = if !name.is_empty() && name.as_bytes()[name.len() - 1] == 0 {
Expand All @@ -77,7 +77,7 @@ pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {
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,
Expand Down
2 changes: 1 addition & 1 deletion dlopen2/src/raw/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub unsafe fn open_self() -> Result<Handle, Error> {
}

#[inline]
pub unsafe fn open_lib(name: &OsStr) -> Result<Handle, Error> {
pub unsafe fn open_lib(name: &OsStr, _flags: Option<i32>) -> Result<Handle, Error> {
let wide_name: Vec<u16> = name.encode_wide().chain(Some(0)).collect();
let _guard = match ErrorModeGuard::new() {
Ok(val) => val,
Expand Down
10 changes: 10 additions & 0 deletions dlopen2/src/wrapper/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<S>(name: S, flags: Option<i32>) -> Result<Container<T>, Error>
where
S: AsRef<OsStr>,
{
let lib = Library::open_with_flags(name, flags)?;
let api = T::load(&lib)?;
Ok(Self { lib, api })
}
}

impl<T> Deref for Container<T>
Expand Down
12 changes: 12 additions & 0 deletions dlopen2/src/wrapper/optional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<S>(name: S, flags: Option<i32>) -> Result<OptionalContainer<Api, Optional>, Error>
where
S: AsRef<OsStr>,
{
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.
///
Expand Down

0 comments on commit c50e261

Please sign in to comment.