diff --git a/src/header/dlfcn/mod.rs b/src/header/dlfcn/mod.rs index 712ae590facba927f9d1faf5bcfd1dd65adf8dac..19089c423e35445f79733e19066a664b45d6067f 100644 --- a/src/header/dlfcn/mod.rs +++ b/src/header/dlfcn/mod.rs @@ -1,6 +1,7 @@ //! dlfcn implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/dlfcn.h.html use core::{ptr, str}; +use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use c_str::CStr; use platform::types::*; @@ -10,6 +11,11 @@ pub const RTLD_NOW: c_int = 0x0002; pub const RTLD_GLOBAL: c_int = 0x0100; pub const RTLD_LOCAL: c_int = 0x0000; +static ERROR_NOT_SUPPORTED: &'static CStr = c_str!("dlfcn not supported"); + +#[thread_local] +static ERROR: AtomicUsize = ATOMIC_USIZE_INIT; + #[repr(C)] pub struct Dl_info { dli_fname: *const c_char, @@ -29,14 +35,32 @@ pub unsafe extern "C" fn dladdr(addr: *mut c_void, info: *mut Dl_info) -> c_int #[no_mangle] pub unsafe extern "C" fn dlopen(filename: *const c_char, flags: c_int) -> *mut c_void { - let filename_cstr = CStr::from_ptr(filename); - let filename_str = str::from_utf8_unchecked(filename_cstr.to_bytes()); - eprintln!("dlopen({}, {:#>04X})", filename_str, flags); - ptr::null_mut() + let filename_opt = if filename.is_null() { + None + } else { + Some(str::from_utf8_unchecked(CStr::from_ptr(filename).to_bytes())) + }; + + eprintln!("dlopen({:?}, {:#>04x})", filename_opt, flags); + + if let Some(filename) = filename_opt { + ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst); + ptr::null_mut() + } else { + 1 as *mut c_void + } } #[no_mangle] -pub extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void { +pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void { + let symbol_opt = if symbol.is_null() { + None + } else { + Some(str::from_utf8_unchecked(CStr::from_ptr(symbol).to_bytes())) + }; + + eprintln!("dlsym({:p}, {:?})", handle, symbol_opt); + ptr::null_mut() } @@ -47,5 +71,5 @@ pub extern "C" fn dlclose(handle: *mut c_void) -> c_int { #[no_mangle] pub extern "C" fn dlerror() -> *mut c_char { - ptr::null_mut() + ERROR.swap(0, Ordering::SeqCst) as *mut c_char }