]> git.lizzy.rs Git - rust.git/blob - src/tools/compiletest/src/procsrv.rs
Auto merge of #41433 - estebank:constructor, r=michaelwoerister
[rust.git] / src / tools / compiletest / src / procsrv.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::env;
12 use std::ffi::OsString;
13 use std::io::prelude::*;
14 use std::io;
15 use std::path::PathBuf;
16 use std::process::{Child, Command, ExitStatus, Output, Stdio};
17
18 pub fn dylib_env_var() -> &'static str {
19     if cfg!(windows) {
20         "PATH"
21     } else if cfg!(target_os = "macos") {
22         "DYLD_LIBRARY_PATH"
23     } else if cfg!(target_os = "haiku") {
24         "LIBRARY_PATH"
25     } else {
26         "LD_LIBRARY_PATH"
27     }
28 }
29
30 fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
31     // Need to be sure to put both the lib_path and the aux path in the dylib
32     // search path for the child.
33     let var = dylib_env_var();
34     let mut path = env::split_paths(&env::var_os(var).unwrap_or(OsString::new()))
35         .collect::<Vec<_>>();
36     if let Some(p) = aux_path {
37         path.insert(0, PathBuf::from(p))
38     }
39     path.insert(0, PathBuf::from(lib_path));
40
41     // Add the new dylib search path var
42     let newpath = env::join_paths(&path).unwrap();
43     cmd.env(var, newpath);
44 }
45
46 pub struct Result {
47     pub status: ExitStatus,
48     pub out: String,
49     pub err: String,
50 }
51
52 pub fn run(lib_path: &str,
53            prog: &str,
54            aux_path: Option<&str>,
55            args: &[String],
56            env: Vec<(String, String)>,
57            input: Option<String>)
58            -> io::Result<Result> {
59
60     let mut cmd = Command::new(prog);
61     cmd.args(args)
62         .stdout(Stdio::piped())
63         .stderr(Stdio::piped())
64         .stdin(Stdio::piped());
65
66     add_target_env(&mut cmd, lib_path, aux_path);
67     for (key, val) in env {
68         cmd.env(&key, &val);
69     }
70
71     let mut process = cmd.spawn()?;
72     if let Some(input) = input {
73         process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
74     }
75     let Output { status, stdout, stderr } = process.wait_with_output().unwrap();
76
77     Ok(Result {
78         status: status,
79         out: String::from_utf8(stdout).unwrap(),
80         err: String::from_utf8(stderr).unwrap(),
81     })
82 }
83
84 pub fn run_background(lib_path: &str,
85                       prog: &str,
86                       aux_path: Option<&str>,
87                       args: &[String],
88                       env: Vec<(String, String)>,
89                       input: Option<String>)
90                       -> io::Result<Child> {
91
92     let mut cmd = Command::new(prog);
93     cmd.args(args)
94        .stdin(Stdio::piped())
95        .stdout(Stdio::piped());
96     add_target_env(&mut cmd, lib_path, aux_path);
97     for (key, val) in env {
98         cmd.env(&key, &val);
99     }
100
101     let mut process = cmd.spawn()?;
102     if let Some(input) = input {
103         process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
104     }
105
106     Ok(process)
107 }