Skip to content

Commit b7058a7

Browse files
committed
Change dynamic_library::open_external to take ToCStr
`std::unstable::dynamic_library::open_external` currently takes a `Path`, but because `Paths` produce normalized strings, this can change the semantics of lookups in a given environment. This patch generalizes the function to take a `ToCStr`-bounded type, which includes both `Path`s and `str`s. Closes rust-lang#11650.
1 parent bf58bfe commit b7058a7

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/libstd/unstable/dynamic_lib.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,22 @@ impl Drop for DynamicLibrary {
4242
}
4343

4444
impl DynamicLibrary {
45+
// FIXME (#12938): Until DST lands, we cannot decompose &str into
46+
// & and str, so we cannot usefully take ToCStr arguments by
47+
// reference (without forcing an additional & around &str). So we
48+
// are instead temporarily adding an instance for &Path, so that
49+
// we can take ToCStr as owned. When DST lands, the &Path instance
50+
// should be removed, and arguments bound by ToCStr should be
51+
// passed by reference. (Here: in the `open` method.)
52+
4553
/// Lazily open a dynamic library. When passed None it gives a
4654
/// handle to the calling process
47-
pub fn open(filename: Option<&path::Path>) -> Result<DynamicLibrary, ~str> {
55+
pub fn open<T: ToCStr>(filename: Option<T>)
56+
-> Result<DynamicLibrary, ~str> {
4857
unsafe {
58+
let mut filename = filename;
4959
let maybe_library = dl::check_for_errors_in(|| {
50-
match filename {
60+
match filename.take() {
5161
Some(name) => dl::open_external(name),
5262
None => dl::open_internal()
5363
}
@@ -109,7 +119,8 @@ mod test {
109119
fn test_loading_cosine() {
110120
// The math library does not need to be loaded since it is already
111121
// statically linked in
112-
let libm = match DynamicLibrary::open(None) {
122+
let none: Option<Path> = None; // appease the typechecker
123+
let libm = match DynamicLibrary::open(none) {
113124
Err(error) => fail!("Could not load self as module: {}", error),
114125
Ok(libm) => libm
115126
};
@@ -137,7 +148,7 @@ mod test {
137148
fn test_errors_do_not_crash() {
138149
// Open /dev/null as a library to get an error, and make sure
139150
// that only causes an error, and not a crash.
140-
let path = GenericPath::new("/dev/null");
151+
let path = Path::new("/dev/null");
141152
match DynamicLibrary::open(Some(&path)) {
142153
Err(_) => {}
143154
Ok(_) => fail!("Successfully opened the empty library.")
@@ -152,12 +163,11 @@ mod test {
152163
pub mod dl {
153164
use c_str::ToCStr;
154165
use libc;
155-
use path;
156166
use ptr;
157167
use str;
158168
use result::*;
159169

160-
pub unsafe fn open_external(filename: &path::Path) -> *u8 {
170+
pub unsafe fn open_external<T: ToCStr>(filename: T) -> *u8 {
161171
filename.with_c_str(|raw_name| {
162172
dlopen(raw_name, Lazy as libc::c_int) as *u8
163173
})

0 commit comments

Comments
 (0)