about summary refs log tree commit diff
path: root/src/compiletest
diff options
context:
space:
mode:
authorAaron Turon <aturon@mozilla.com>2014-07-02 13:50:45 -0700
committerAaron Turon <aturon@mozilla.com>2014-07-10 12:16:16 -0700
commitbfa853f8ed45d1908c98ec350f52c7a6790661da (patch)
tree96c101298ae0503bd64bb51201e2154eeb88d905 /src/compiletest
parentf9fe251777e9f1cc557a6d5b82b45403935d0a10 (diff)
downloadrust-bfa853f8ed45d1908c98ec350f52c7a6790661da.tar.gz
rust-bfa853f8ed45d1908c98ec350f52c7a6790661da.zip
io::process::Command: add fine-grained env builder
This commit changes the `io::process::Command` API to provide
fine-grained control over the environment:

* The `env` method now inserts/updates a key/value pair.
* The `env_remove` method removes a key from the environment.
* The old `env` method, which sets the entire environment in one shot,
  is renamed to `env_set_all`. It can be used in conjunction with the
  finer-grained methods. This renaming is a breaking change.

To support these new methods, the internal `env` representation for
`Command` has been changed to an optional `HashMap` holding owned
`CString`s (to support non-utf8 data). The `HashMap` is only
materialized if the environment is updated. The implementation does not
try hard to avoid allocation, since the cost of launching a process will
dwarf any allocation cost.

This patch also adds `PartialOrd`, `Eq`, and `Hash` implementations for
`CString`.

[breaking-change]
Diffstat (limited to 'src/compiletest')
-rw-r--r--src/compiletest/procsrv.rs35
-rw-r--r--src/compiletest/runtest.rs2
2 files changed, 20 insertions, 17 deletions
diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs
index 797477d2920..1ee6f2b500c 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/compiletest/procsrv.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::os;
 use std::str;
 use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
 use std::dynamic_lib::DynamicLibrary;
 
-fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
+fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
     // Need to be sure to put both the lib_path and the aux path in the dylib
     // search path for the child.
     let mut path = DynamicLibrary::search_path();
@@ -23,19 +22,11 @@ fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
     }
     path.insert(0, Path::new(lib_path));
 
-    // Remove the previous dylib search path var
-    let var = DynamicLibrary::envvar();
-    let mut env: Vec<(String,String)> = os::env();
-    match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
-        Some(i) => { env.remove(i); }
-        None => {}
-    }
-
     // Add the new dylib search path var
+    let var = DynamicLibrary::envvar();
     let newpath = DynamicLibrary::create_path(path.as_slice());
     let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
-    env.push((var.to_string(), newpath));
-    return env;
+    cmd.env(var.to_string(), newpath);
 }
 
 pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
@@ -47,8 +38,14 @@ pub fn run(lib_path: &str,
            env: Vec<(String, String)> ,
            input: Option<String>) -> Option<Result> {
 
-    let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
-    match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+    let mut cmd = Command::new(prog);
+    cmd.args(args);
+    add_target_env(&mut cmd, lib_path, aux_path);
+    for (key, val) in env.move_iter() {
+        cmd.env(key, val);
+    }
+
+    match cmd.spawn() {
         Ok(mut process) => {
             for input in input.iter() {
                 process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
@@ -73,8 +70,14 @@ pub fn run_background(lib_path: &str,
            env: Vec<(String, String)> ,
            input: Option<String>) -> Option<Process> {
 
-    let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
-    match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+    let mut cmd = Command::new(prog);
+    cmd.args(args);
+    add_target_env(&mut cmd, lib_path, aux_path);
+    for (key, val) in env.move_iter() {
+        cmd.env(key, val);
+    }
+
+    match cmd.spawn() {
         Ok(mut process) => {
             for input in input.iter() {
                 process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index 7c8e7e85e46..f28604908e0 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -574,7 +574,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
         cmd.arg("./src/etc/lldb_batchmode.py")
            .arg(test_executable)
            .arg(debugger_script)
-           .env([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
+           .env_set_all([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
 
         let (status, out, err) = match cmd.spawn() {
             Ok(process) => {