/src/tools/compiletest/src/procsrv.rs

https://github.com/nickdesaulniers/rust · Rust · 112 lines · 87 code · 13 blank · 12 comment · 11 complexity · e9732aa9054f20476506e0adbac2a044 MD5 · raw file

  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. use std::env;
  11. use std::ffi::OsString;
  12. use std::io::prelude::*;
  13. use std::path::PathBuf;
  14. use std::process::{Child, Command, ExitStatus, Output, Stdio};
  15. pub fn dylib_env_var() -> &'static str {
  16. if cfg!(windows) {
  17. "PATH"
  18. } else if cfg!(target_os = "macos") {
  19. "DYLD_LIBRARY_PATH"
  20. } else {
  21. "LD_LIBRARY_PATH"
  22. }
  23. }
  24. fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
  25. // Need to be sure to put both the lib_path and the aux path in the dylib
  26. // search path for the child.
  27. let var = dylib_env_var();
  28. let mut path = env::split_paths(&env::var_os(var).unwrap_or(OsString::new()))
  29. .collect::<Vec<_>>();
  30. if let Some(p) = aux_path {
  31. path.insert(0, PathBuf::from(p))
  32. }
  33. path.insert(0, PathBuf::from(lib_path));
  34. // Add the new dylib search path var
  35. let newpath = env::join_paths(&path).unwrap();
  36. cmd.env(var, newpath);
  37. }
  38. pub struct Result {
  39. pub status: ExitStatus,
  40. pub out: String,
  41. pub err: String,
  42. }
  43. pub fn run(lib_path: &str,
  44. prog: &str,
  45. aux_path: Option<&str>,
  46. args: &[String],
  47. env: Vec<(String, String)>,
  48. input: Option<String>)
  49. -> Option<Result> {
  50. let mut cmd = Command::new(prog);
  51. cmd.args(args)
  52. .stdin(Stdio::piped())
  53. .stdout(Stdio::piped())
  54. .stderr(Stdio::piped());
  55. add_target_env(&mut cmd, lib_path, aux_path);
  56. for (key, val) in env {
  57. cmd.env(&key, &val);
  58. }
  59. match cmd.spawn() {
  60. Ok(mut process) => {
  61. if let Some(input) = input {
  62. process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
  63. }
  64. let Output { status, stdout, stderr } = process.wait_with_output().unwrap();
  65. Some(Result {
  66. status: status,
  67. out: String::from_utf8(stdout).unwrap(),
  68. err: String::from_utf8(stderr).unwrap(),
  69. })
  70. }
  71. Err(..) => None,
  72. }
  73. }
  74. pub fn run_background(lib_path: &str,
  75. prog: &str,
  76. aux_path: Option<&str>,
  77. args: &[String],
  78. env: Vec<(String, String)>,
  79. input: Option<String>)
  80. -> Option<Child> {
  81. let mut cmd = Command::new(prog);
  82. cmd.args(args)
  83. .stdin(Stdio::piped())
  84. .stdout(Stdio::piped())
  85. .stderr(Stdio::piped());
  86. add_target_env(&mut cmd, lib_path, aux_path);
  87. for (key, val) in env {
  88. cmd.env(&key, &val);
  89. }
  90. match cmd.spawn() {
  91. Ok(mut process) => {
  92. if let Some(input) = input {
  93. process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
  94. }
  95. Some(process)
  96. }
  97. Err(..) => None,
  98. }
  99. }