Skip to content

Refactor core::run in order to address many of the issues... #6433

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

Merged
merged 3 commits into from
May 27, 2013
Merged
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
85 changes: 16 additions & 69 deletions src/compiletest/procsrv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

use core::prelude::*;

use core::libc::c_int;
use core::run::spawn_process;
use core::run;

#[cfg(target_os = "win32")]
Expand All @@ -38,86 +36,35 @@ fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] {
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
fn target_env(_lib_path: &str, _prog: &str) -> ~[(~str,~str)] {
~[]
os::env()
}

pub struct Result {status: int, out: ~str, err: ~str}

// FIXME (#2659): This code is duplicated in core::run::program_output
pub fn run(lib_path: &str,
prog: &str,
args: &[~str],
env: ~[(~str, ~str)],
input: Option<~str>) -> Result {
let pipe_in = os::pipe();
let pipe_out = os::pipe();
let pipe_err = os::pipe();
let pid = spawn_process(prog, args,
&Some(env + target_env(lib_path, prog)),
&None, pipe_in.in, pipe_out.out, pipe_err.out);

os::close(pipe_in.in);
os::close(pipe_out.out);
os::close(pipe_err.out);
if pid == -1i32 {
os::close(pipe_in.out);
os::close(pipe_out.in);
os::close(pipe_err.in);
fail!();
}

let env = env + target_env(lib_path, prog);
let mut proc = run::Process::new(prog, args, run::ProcessOptions {
env: Some(env.slice(0, env.len())),
dir: None,
in_fd: None,
out_fd: None,
err_fd: None
});

writeclose(pipe_in.out, input);
let p = comm::PortSet::new();
let ch = p.chan();
do task::spawn_sched(task::SingleThreaded) || {
let errput = readclose(pipe_err.in);
ch.send((2, errput));
for input.each |input| {
proc.input().write_str(*input);
}
let ch = p.chan();
do task::spawn_sched(task::SingleThreaded) || {
let output = readclose(pipe_out.in);
ch.send((1, output));
}
let status = run::waitpid(pid);
let mut errs = ~"";
let mut outs = ~"";
let mut count = 2;
while count > 0 {
match p.recv() {
(1, s) => {
outs = s;
}
(2, s) => {
errs = s;
}
_ => { fail!() }
};
count -= 1;
};
return Result {status: status, out: outs, err: errs};
}
let output = proc.finish_with_output();

fn writeclose(fd: c_int, s: Option<~str>) {
if s.is_some() {
let writer = io::fd_writer(fd, false);
writer.write_str(s.get());
Result {
status: output.status,
out: str::from_bytes(output.output),
err: str::from_bytes(output.error)
}

os::close(fd);
}

fn readclose(fd: c_int) -> ~str {
unsafe {
// Copied from run::program_output
let file = os::fdopen(fd);
let reader = io::FILE_reader(file, false);
let mut buf = ~"";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
str::push_str(&mut buf, str::from_bytes(bytes));
}
os::fclose(file);
return buf;
}
}
2 changes: 1 addition & 1 deletion src/libextra/workcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ fn test() {
prep.declare_input("file", pth.to_str(), digest_file(&pth));
do prep.exec |_exe| {
let out = Path("foo.o");
run::run_program("gcc", [~"foo.c", ~"-o", out.to_str()]);
run::process_status("gcc", [~"foo.c", ~"-o", out.to_str()]);
out.to_str()
}
};
Expand Down
38 changes: 19 additions & 19 deletions src/libfuzzer/fuzzer.rc
Original file line number Diff line number Diff line change
Expand Up @@ -412,20 +412,20 @@ pub fn check_whole_compiler(code: &str,
pub fn removeIfExists(filename: &Path) {
// So sketchy!
assert!(!contains(filename.to_str(), " "));
run::program_output("bash", [~"-c", ~"rm " + filename.to_str()]);
run::process_status("bash", [~"-c", ~"rm " + filename.to_str()]);
}

pub fn removeDirIfExists(filename: &Path) {
// So sketchy!
assert!(!contains(filename.to_str(), " "));
run::program_output("bash", [~"-c", ~"rm -r " + filename.to_str()]);
run::process_status("bash", [~"-c", ~"rm -r " + filename.to_str()]);
}

pub fn check_running(exe_filename: &Path) -> happiness {
let p = run::program_output(
let p = run::process_output(
"/Users/jruderman/scripts/timed_run_rust_program.py",
[exe_filename.to_str()]);
let comb = p.out + ~"\n" + p.err;
let comb = str::from_bytes(p.output) + ~"\n" + str::from_bytes(p.error);
if str::len(comb) > 1u {
error!("comb comb comb: %?", comb);
}
Expand Down Expand Up @@ -461,33 +461,35 @@ pub fn check_running(exe_filename: &Path) -> happiness {
}

pub fn check_compiling(filename: &Path) -> happiness {
let p = run::program_output(
"/Users/jruderman/code/rust/build/x86_64-apple-darwin/\
stage1/bin/rustc",
let p = run::process_output(
"/Users/jruderman/code/rust/build/x86_64-apple-darwin/stage1/bin/rustc",
[filename.to_str()]);

let out = str::from_bytes(p.output);
let err = str::from_bytes(p.error);

//error!("Status: %d", p.status);
if p.status == 0 {
passed
} else if p.err != ~"" {
if contains(p.err, "error:") {
} else if !err.is_empty() {
if err.contains("error:") {
cleanly_rejected(~"rejected with span_error")
} else {
error!("Stderr: %?", p.err);
error!("Stderr: %?", err);
failed(~"Unfamiliar error message")
}
} else if contains(p.out, "Assertion") && contains(p.out, "failed") {
error!("Stdout: %?", p.out);
} else if out.contains("Assertion") && out.contains("failed") {
error!("Stdout: %?", out);
failed(~"Looks like an llvm assertion failure")
} else if contains(p.out, "internal compiler error unimplemented") {
} else if out.contains("internal compiler error unimplemented") {
known_bug(~"Something unimplemented")
} else if contains(p.out, "internal compiler error") {
error!("Stdout: %?", p.out);
} else if out.contains("internal compiler error") {
error!("Stdout: %?", out);
failed(~"internal compiler error")

} else {
error!("%?", p.status);
error!("!Stdout: %?", p.out);
error!("!Stdout: %?", out);
failed(~"What happened?")
}
}
Expand Down Expand Up @@ -608,9 +610,7 @@ pub fn check_roundtrip_convergence(code: @~str, maxIters: uint) {
error!("Did not converge after %u iterations!", i);
write_file(&Path("round-trip-a.rs"), *oldv);
write_file(&Path("round-trip-b.rs"), *newv);
run::run_program("diff",
[~"-w", ~"-u", ~"round-trip-a.rs",
~"round-trip-b.rs"]);
run::process_status("diff", [~"-w", ~"-u", ~"round-trip-a.rs", ~"round-trip-b.rs"]);
fail!("Mismatch");
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librust/rust.rc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ fn cmd_test(args: &[~str]) -> ValidUsage {
let test_exec = Path(filename).filestem().unwrap() + "test~";
invoke("rustc", &[~"--test", filename.to_owned(),
~"-o", test_exec.to_owned()], rustc::main);
let exit_code = run::run_program(~"./" + test_exec, []);
let exit_code = run::process_status(~"./" + test_exec, []);
Valid(exit_code)
}
_ => Invalid
Expand All @@ -176,7 +176,7 @@ fn cmd_run(args: &[~str]) -> ValidUsage {
let exec = Path(filename).filestem().unwrap() + "~";
invoke("rustc", &[filename.to_owned(), ~"-o", exec.to_owned()],
rustc::main);
let exit_code = run::run_program(~"./"+exec, prog_args);
let exit_code = run::process_status(~"./"+exec, prog_args);
Valid(exit_code)
}
_ => Invalid
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,14 @@ pub mod write {
cc_args.push(object.to_str());
cc_args.push(assembly.to_str());

let prog = run::program_output(cc_prog, cc_args);
let prog = run::process_output(cc_prog, cc_args);

if prog.status != 0 {
sess.err(fmt!("building with `%s` failed with code %d",
cc_prog, prog.status));
sess.note(fmt!("%s arguments: %s",
cc_prog, str::connect(cc_args, " ")));
sess.note(prog.err + prog.out);
sess.note(str::from_bytes(prog.error + prog.output));
sess.abort_if_errors();
}
}
Expand Down Expand Up @@ -817,19 +817,19 @@ pub fn link_binary(sess: Session,
let cc_args = link_args(sess, obj_filename, out_filename, lm);
debug!("%s link args: %s", cc_prog, str::connect(cc_args, " "));
// We run 'cc' here
let prog = run::program_output(cc_prog, cc_args);
let prog = run::process_output(cc_prog, cc_args);
if 0 != prog.status {
sess.err(fmt!("linking with `%s` failed with code %d",
cc_prog, prog.status));
sess.note(fmt!("%s arguments: %s",
cc_prog, str::connect(cc_args, " ")));
sess.note(prog.err + prog.out);
sess.note(str::from_bytes(prog.error + prog.output));
sess.abort_if_errors();
}

// Clean up on Darwin
if sess.targ_cfg.os == session::os_macos {
run::run_program("dsymutil", [output.to_str()]);
run::process_status("dsymutil", [output.to_str()]);
}

// Remove the temporary object file if we aren't saving temps
Expand Down
48 changes: 24 additions & 24 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::prelude::*;

use core::cell::Cell;
use core::run;
use core::run::ProgramOutput;
use core::run::ProcessOutput;
use core::result::Result;
use extra::getopts;

Expand Down Expand Up @@ -89,35 +89,35 @@ pub fn default_config(input_crate: &Path) -> Config {
}
}

type Process = ~fn((&str), (&[~str])) -> ProgramOutput;
type Process = ~fn((&str), (&[~str])) -> ProcessOutput;

pub fn mock_program_output(_prog: &str, _args: &[~str]) -> ProgramOutput {
ProgramOutput {
pub fn mock_process_output(_prog: &str, _args: &[~str]) -> ProcessOutput {
ProcessOutput {
status: 0,
out: ~"",
err: ~""
output: ~[],
error: ~[]
}
}

pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput {
run::program_output(prog, args)
pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
run::process_output(prog, args)
}

pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
parse_config_(args, program_output)
parse_config_(args, process_output)
}

pub fn parse_config_(
args: &[~str],
program_output: Process
process_output: Process
) -> Result<Config, ~str> {
let args = args.tail();
let opts = vec::unzip(opts()).first();
match getopts::getopts(args, opts) {
Ok(matches) => {
if matches.free.len() == 1 {
let input_crate = Path(*matches.free.head());
config_from_opts(&input_crate, &matches, program_output)
config_from_opts(&input_crate, &matches, process_output)
} else if matches.free.is_empty() {
Err(~"no crates specified")
} else {
Expand All @@ -133,7 +133,7 @@ pub fn parse_config_(
fn config_from_opts(
input_crate: &Path,
matches: &getopts::Matches,
program_output: Process
process_output: Process
) -> Result<Config, ~str> {

let config = default_config(input_crate);
Expand Down Expand Up @@ -175,11 +175,11 @@ fn config_from_opts(
}
}
};
let program_output = Cell(program_output);
let process_output = Cell(process_output);
let result = do result::chain(result) |config| {
let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
let pandoc_cmd = maybe_find_pandoc(
&config, pandoc_cmd, program_output.take());
&config, pandoc_cmd, process_output.take());
do result::chain(pandoc_cmd) |pandoc_cmd| {
result::Ok(Config {
pandoc_cmd: pandoc_cmd,
Expand Down Expand Up @@ -209,7 +209,7 @@ fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
pub fn maybe_find_pandoc(
config: &Config,
maybe_pandoc_cmd: Option<~str>,
program_output: Process
process_output: Process
) -> Result<Option<~str>, ~str> {
if config.output_format != PandocHtml {
return result::Ok(maybe_pandoc_cmd);
Expand All @@ -228,7 +228,7 @@ pub fn maybe_find_pandoc(
};

let pandoc = do vec::find(possible_pandocs) |pandoc| {
let output = program_output(*pandoc, [~"--version"]);
let output = process_output(*pandoc, [~"--version"]);
debug!("testing pandoc cmd %s: %?", *pandoc, output);
output.status == 0
};
Expand All @@ -244,10 +244,10 @@ pub fn maybe_find_pandoc(
mod test {
use core::prelude::*;
use config::*;
use core::run::ProgramOutput;
use core::run::ProcessOutput;

fn parse_config(args: &[~str]) -> Result<Config, ~str> {
parse_config_(args, mock_program_output)
parse_config_(args, mock_process_output)
}

#[test]
Expand All @@ -256,10 +256,10 @@ mod test {
output_format: PandocHtml,
.. default_config(&Path("test"))
};
let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
ProgramOutput { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" }
let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
ProcessOutput { status: 0, output: "pandoc 1.8.2.1".to_bytes(), error: ~[] }
};
let result = maybe_find_pandoc(&config, None, mock_program_output);
let result = maybe_find_pandoc(&config, None, mock_process_output);
assert!(result == result::Ok(Some(~"pandoc")));
}

Expand All @@ -269,10 +269,10 @@ mod test {
output_format: PandocHtml,
.. default_config(&Path("test"))
};
let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
ProgramOutput { status: 1, out: ~"", err: ~"" }
let mock_process_output: ~fn(&str, &[~str]) -> ProcessOutput = |_, _| {
ProcessOutput { status: 1, output: ~[], error: ~[] }
};
let result = maybe_find_pandoc(&config, None, mock_program_output);
let result = maybe_find_pandoc(&config, None, mock_process_output);
assert!(result == result::Err(~"couldn't find pandoc"));
}

Expand Down
Loading