Skip to content

Refactoring std os setenv #14736

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,12 @@ pub fn run_tests(config: &Config) {
//arm-linux-androideabi debug-info test uses remote debugger
//so, we test 1 task at once.
// also trying to isolate problems with adb_run_wrapper.sh ilooping
os::setenv("RUST_TEST_TASKS","1");
match os::setenv("RUST_TEST_TASKS","1") {
Ok(()) => {},
Err(e) => {
fail!("`setenv` failed: {}", e);
}
}
}

let opts = test_opts(config);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/metadata/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ impl<'a> FileSearch<'a> {
}
}

// FIXME: # It's a dirty hack.
// A better error handling is needed here.
#[allow(unused_must_use)]
pub fn add_dylib_search_paths(&self) {
self.for_each_lib_search_path(|lib_search_path| {
DynamicLibrary::prepend_search_path(lib_search_path);
Expand Down
75 changes: 60 additions & 15 deletions src/libstd/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use str;
use string::String;
use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
use vec::Vec;
use io::{IoResult, IoError};

#[cfg(unix)]
use c_str::ToCStr;
Expand Down Expand Up @@ -380,13 +381,34 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
///
/// # Failure
///
/// Fails if `n` or `v` have any interior NULs.
pub fn setenv(n: &str, v: &str) {
/// Return Err if:
/// * `n` has length 0, or contain '=' character.
/// * There is no memory for adding to a new variable to the environment.
///
/// # Example
///
/// ```rust
/// let key = "KEY";
/// let value = "VALUE";
/// match std::os::setenv(key.as_slice(), value.as_slice()) {
/// Ok(()) => {},
/// Err(e) => fail!("setenv failed: {}", e)
/// }
/// match std::os::getenv(key.as_slice()) {
/// Some(ref val) => println!("{}: {}", key, val),
/// None => println!("{} is not defined in the environment.", key)
/// }
/// ```
pub fn setenv(n: &str, v: &str) -> IoResult<()> {
unsafe {
with_env_lock(|| {
n.with_c_str(|nbuf| {
v.with_c_str(|vbuf| {
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
if libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1) == 0 {
Ok(())
} else {
Err(IoError::last_error())
}
})
})
})
Expand All @@ -397,13 +419,17 @@ pub fn setenv(n: &str, v: &str) {
#[cfg(windows)]
/// Sets the environment variable `n` to the value `v` for the currently running
/// process
pub fn setenv(n: &str, v: &str) {
pub fn setenv(n: &str, v: &str) -> IoResult<()> {
unsafe {
with_env_lock(|| {
use os::win32::as_utf16_p;
as_utf16_p(n, |nbuf| {
as_utf16_p(v, |vbuf| {
libc::SetEnvironmentVariableW(nbuf, vbuf);
if libc::SetEnvironmentVariableW(nbuf, vbuf) != 0 {
Ok(())
} else {
Err(IoError::last_error())
}
})
})
})
Expand Down Expand Up @@ -1608,11 +1634,7 @@ mod tests {
use os;
use rand::Rng;
use rand;

#[test]
pub fn last_os_error() {
debug!("{}", os::last_os_error());
}
use libc;

fn make_rand_name() -> String {
let mut rng = rand::task_rng();
Expand All @@ -1622,10 +1644,33 @@ mod tests {
n
}

#[test]
pub fn last_os_error() {
debug!("{}", os::last_os_error());
}

#[test]
#[cfg(unix)]
fn test_setenv_with_name_containing_equal() {
let n = format!("a={}", make_rand_name());
let ret = setenv(n.as_slice(), "VALUE");
assert!(ret.is_err());
assert_eq!(ret.err().unwrap().kind, libc::EINVAL);
}

#[test]
#[cfg(windows)]
fn test_setenv_with_name_containing_equal() {
let n = format!("a={}", make_rand_name());
let ret = setenv(n.as_slice(), "VALUE");
assert!(ret.is_err());
assert_eq!(ret.err().unwrap().kind, libc::WSAEINVAL);
}

#[test]
fn test_setenv() {
let n = make_rand_name();
setenv(n.as_slice(), "VALUE");
assert!(setenv(n.as_slice(), "VALUE").is_ok());
assert_eq!(getenv(n.as_slice()), option::Some("VALUE".to_string()));
}

Expand Down Expand Up @@ -1742,13 +1787,13 @@ mod tests {
let oldhome = getenv("HOME");

setenv("HOME", "/home/MountainView");
assert!(os::homedir() == Some(Path::new("/home/MountainView")));
assert_eq!(os::homedir(), Some(Path::new("/home/MountainView")));

setenv("HOME", "");
assert!(os::homedir().is_none());

for s in oldhome.iter() {
setenv("HOME", s.as_slice())
setenv("HOME", s.as_slice());
}
}

Expand Down Expand Up @@ -1777,10 +1822,10 @@ mod tests {
assert!(os::homedir() == Some(Path::new("/home/MountainView")));

for s in oldhome.iter() {
setenv("HOME", s.as_slice())
setenv("HOME", s.as_slice());
}
for s in olduserprofile.iter() {
setenv("USERPROFILE", s.as_slice())
setenv("USERPROFILE", s.as_slice());
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/libstd/unstable/dynamic_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use os;
use path::{Path,GenericPath};
use result::*;
use slice::{Vector,ImmutableVector};
use io::{IoResult};
use str;
use string::String;
use vec::Vec;
Expand Down Expand Up @@ -78,12 +79,12 @@ impl DynamicLibrary {
}

/// Prepends a path to this process's search path for dynamic libraries
pub fn prepend_search_path(path: &Path) {
pub fn prepend_search_path(path: &Path) -> IoResult<()> {
let mut search_path = DynamicLibrary::search_path();
search_path.insert(0, path.clone());
let newval = DynamicLibrary::create_path(search_path.as_slice());
os::setenv(DynamicLibrary::envvar(),
str::from_utf8(newval.as_slice()).unwrap());
str::from_utf8(newval.as_slice()).unwrap())
}

/// From a slice of paths, create a new vector which is suitable to be an
Expand Down