replace procsrv functions with Command

This commit is contained in:
Andy Russell 2017-08-10 13:30:41 -04:00
parent c88624682d
commit 6601ffca07
No known key found for this signature in database
GPG key ID: 78B13E28497AF2DF
2 changed files with 69 additions and 181 deletions

View file

@ -10,10 +10,8 @@
use std::env;
use std::ffi::OsString;
use std::io::prelude::*;
use std::io;
use std::path::PathBuf;
use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::process::Command;
/// Get the name of the environment variable that holds dynamic library
/// locations
@ -31,7 +29,7 @@ pub fn dylib_env_var() -> &'static str {
/// Add `lib_path` and `aux_path` (if it is `Some`) to the dynamic library
/// env var
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
pub 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 var = dylib_env_var();
@ -46,89 +44,3 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
let newpath = env::join_paths(&path).unwrap();
cmd.env(var, newpath);
}
/// Represents exit status, stdout and stderr of a completed process
pub struct Result {
pub status: ExitStatus,
pub out: String,
pub err: String,
}
/// Runs a test program
///
/// # Params
/// - `lib_path` Path to search for required library
/// - `prog` command to run
/// - `aux_path` Optional extra path to search for required
/// auxiliary libraries
/// - `args` List of arguments to pass to `prog`
/// - `env` List of environment variables to set, `.0` is variable name,
/// `.1` is value
/// - `input` String to be fed as stdin
/// - `current_dir` Optional working dir to run command in
///
pub fn run(lib_path: &str,
prog: &str,
aux_path: Option<&str>,
args: &[String],
env: Vec<(String, String)>,
input: Option<String>,
current_dir: Option<String>)
-> io::Result<Result> {
let mut cmd = Command::new(prog);
cmd.args(args)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.stdin(Stdio::piped());
add_target_env(&mut cmd, lib_path, aux_path);
for (key, val) in env {
cmd.env(&key, &val);
}
if let Some(cwd) = current_dir {
cmd.current_dir(cwd);
}
let mut process = cmd.spawn()?;
if let Some(input) = input {
process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
}
let Output { status, stdout, stderr } = process.wait_with_output().unwrap();
Ok(Result {
status,
out: String::from_utf8(stdout).unwrap(),
err: String::from_utf8(stderr).unwrap(),
})
}
/// Same as `run`, but return process rather than waiting on completion
pub fn run_background(lib_path: &str,
prog: &str,
aux_path: Option<&str>,
args: &[String],
env: Vec<(String, String)>,
input: Option<String>,
current_dir: Option<String>)
-> io::Result<Child> {
let mut cmd = Command::new(prog);
cmd.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped());
add_target_env(&mut cmd, lib_path, aux_path);
for (key, val) in env {
cmd.env(&key, &val);
}
if let Some(cwd) = current_dir {
cmd.current_dir(cwd);
}
let mut process = cmd.spawn()?;
if let Some(input) = input {
process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
}
Ok(process)
}

View file

@ -27,7 +27,7 @@ use std::fs::{self, File, create_dir_all};
use std::io::prelude::*;
use std::io::{self, BufReader};
use std::path::{Path, PathBuf};
use std::process::{Command, Output, ExitStatus};
use std::process::{Command, Output, ExitStatus, Stdio};
use std::str;
use std::collections::HashMap;
@ -500,32 +500,19 @@ actual:\n\
debug!("script_str = {}", script_str);
self.dump_output_file(&script_str, "debugger.script");
let adb_path = &self.config.adb_path;
procsrv::run("",
&self.config.adb_path,
None,
&[
"push".to_owned(),
exe_file.to_str().unwrap().to_owned(),
self.config.adb_test_dir.clone()
],
Vec::new(),
None,
None)
.expect(&format!("failed to exec `{:?}`", self.config.adb_path));
Command::new(adb_path)
.arg("push")
.arg(&exe_file)
.arg(&self.config.adb_test_dir)
.status()
.expect(&format!("failed to exec `{:?}`", adb_path));
procsrv::run("",
&self.config.adb_path,
None,
&[
"forward".to_owned(),
"tcp:5039".to_owned(),
"tcp:5039".to_owned()
],
Vec::new(),
None,
None)
.expect(&format!("failed to exec `{:?}`", self.config.adb_path));
Command::new(adb_path)
.args(&["forward", "tcp:5039", "tcp:5039"])
.status()
.expect(&format!("failed to exec `{:?}`", adb_path));
let adb_arg = format!("export LD_LIBRARY_PATH={}; \
gdbserver{} :5039 {}/{}",
@ -537,23 +524,15 @@ actual:\n\
.unwrap());
debug!("adb arg: {}", adb_arg);
let mut process = procsrv::run_background("",
&self.config.adb_path
,
None,
&[
"shell".to_owned(),
adb_arg.clone()
],
Vec::new(),
None,
None)
.expect(&format!("failed to exec `{:?}`", self.config.adb_path));
let mut adb = Command::new(adb_path)
.args(&["shell", &adb_arg])
.spawn()
.expect(&format!("failed to exec `{:?}`", adb_path));
// Wait for the gdbserver to print out "Listening on port ..."
// at which point we know that it's started and then we can
// execute the debugger below.
let mut stdout = BufReader::new(process.stdout.take().unwrap());
let mut stdout = BufReader::new(adb.stdout.take().unwrap());
let mut line = String::new();
loop {
line.truncate(0);
@ -574,17 +553,13 @@ actual:\n\
let mut gdb_path = tool_path;
gdb_path.push_str("/bin/gdb");
let procsrv::Result {
out,
err,
status
} = procsrv::run("",
&gdb_path,
None,
&debugger_opts,
Vec::new(),
None,
None)
let Output {
status,
stdout,
stderr
} = Command::new(&gdb_path)
.args(&debugger_opts)
.output()
.expect(&format!("failed to exec `{:?}`", gdb_path));
let cmdline = {
let cmdline = self.make_cmdline("",
@ -596,11 +571,11 @@ actual:\n\
debugger_run_result = ProcRes {
status,
stdout: out,
stderr: err,
stdout: String::from_utf8(stdout).unwrap(),
stderr: String::from_utf8(stderr).unwrap(),
cmdline,
};
if process.kill().is_err() {
if adb.kill().is_err() {
println!("Adb process is already finished.");
}
}
@ -1367,7 +1342,46 @@ actual:\n\
aux_path: Option<&str>,
input: Option<String>,
working_dir: Option<String>) -> ProcRes {
self.program_output(lib_path, prog, aux_path, args, procenv, input, working_dir)
let cmdline =
{
let cmdline = self.make_cmdline(lib_path,
&prog,
&args);
logv(self.config, format!("executing {}", cmdline));
cmdline
};
let mut process = Command::new(&prog);
process
.args(&args)
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.stdin(Stdio::piped());
procsrv::add_target_env(&mut process, lib_path, aux_path);
for (key, val) in procenv {
process.env(&key, &val);
}
if let Some(cwd) = working_dir {
process.current_dir(cwd);
}
let mut child = process.spawn().expect(&format!("failed to exec `{}`", prog));
if let Some(input) = input {
child.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
}
let Output { status, stdout, stderr } = child.wait_with_output().unwrap();
let result = ProcRes {
status,
stdout: String::from_utf8(stdout).unwrap(),
stderr: String::from_utf8(stderr).unwrap(),
cmdline,
};
self.dump_output(&result.stdout, &result.stderr);
result
}
fn make_compile_args(&self,
@ -1554,44 +1568,6 @@ actual:\n\
}
}
fn program_output(&self,
lib_path: &str,
prog: String,
aux_path: Option<&str>,
args: Vec<String>,
env: Vec<(String, String)>,
input: Option<String>,
working_dir: Option<String>)
-> ProcRes {
let cmdline =
{
let cmdline = self.make_cmdline(lib_path,
&prog,
&args);
logv(self.config, format!("executing {}", cmdline));
cmdline
};
let procsrv::Result {
out,
err,
status
} = procsrv::run(lib_path,
&prog,
aux_path,
&args,
env,
input,
working_dir).expect(&format!("failed to exec `{}`", prog));
self.dump_output(&out, &err);
ProcRes {
status,
stdout: out,
stderr: err,
cmdline,
}
}
fn make_cmdline(&self, libpath: &str, prog: &str, args: &[String]) -> String {
use util;