Skip to content

Commit

Permalink
Implemented a ProcessExit enum and helper methods to std::rt::io::pro…
Browse files Browse the repository at this point in the history
…cess for getting process termination status, or the signal that terminated a process.

A test has been added to rtio-processes.rs to ensure signal termination is picked up correctly.
  • Loading branch information
miselin committed Nov 12, 2013
1 parent 88e383e commit f698dec
Show file tree
Hide file tree
Showing 15 changed files with 202 additions and 100 deletions.
3 changes: 2 additions & 1 deletion src/compiletest/procsrv.rs
Expand Up @@ -11,6 +11,7 @@
use std::os;
use std::run;
use std::str;
use std::rt::io::process::ProcessExit;

#[cfg(target_os = "win32")]
fn target_env(lib_path: &str, prog: &str) -> ~[(~str,~str)] {
Expand Down Expand Up @@ -39,7 +40,7 @@ fn target_env(_lib_path: &str, _prog: &str) -> ~[(~str,~str)] {
os::env()
}

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

pub fn run(lib_path: &str,
prog: &str,
Expand Down
58 changes: 32 additions & 26 deletions src/compiletest/runtest.rs
Expand Up @@ -23,6 +23,8 @@ use util::logv;
use std::rt::io;
use std::rt::io::fs;
use std::rt::io::File;
use std::rt::io::process;
use std::rt::io::process::ProcessExit;
use std::os;
use std::str;
use std::vec;
Expand Down Expand Up @@ -60,7 +62,7 @@ pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) {
fn run_cfail_test(config: &config, props: &TestProps, testfile: &Path) {
let ProcRes = compile_test(config, props, testfile);

if ProcRes.status == 0 {
if ProcRes.status.success() {
fatal_ProcRes(~"compile-fail test compiled successfully!", &ProcRes);
}

Expand All @@ -81,7 +83,7 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) {
let ProcRes = if !config.jit {
let ProcRes = compile_test(config, props, testfile);

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}

Expand All @@ -92,7 +94,7 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) {

// The value our Makefile configures valgrind to return on failure
static VALGRIND_ERR: int = 100;
if ProcRes.status == VALGRIND_ERR {
if ProcRes.status.matches_exit_status(VALGRIND_ERR) {
fatal_ProcRes(~"run-fail test isn't valgrind-clean!", &ProcRes);
}

Expand All @@ -115,10 +117,9 @@ fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) {
fn check_correct_failure_status(ProcRes: &ProcRes) {
// The value the rust runtime returns on failure
static RUST_ERR: int = 101;
if ProcRes.status != RUST_ERR {
if !ProcRes.status.matches_exit_status(RUST_ERR) {
fatal_ProcRes(
format!("failure produced the wrong error code: {}",
ProcRes.status),
format!("failure produced the wrong error: {}", ProcRes.status),
ProcRes);
}
}
Expand All @@ -127,19 +128,19 @@ fn run_rpass_test(config: &config, props: &TestProps, testfile: &Path) {
if !config.jit {
let mut ProcRes = compile_test(config, props, testfile);

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}

ProcRes = exec_compiled_test(config, props, testfile);

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"test run failed!", &ProcRes);
}
} else {
let ProcRes = jit_test(config, props, testfile);

if ProcRes.status != 0 { fatal_ProcRes(~"jit failed!", &ProcRes); }
if !ProcRes.status.success() { fatal_ProcRes(~"jit failed!", &ProcRes); }
}
}

Expand All @@ -160,7 +161,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
logv(config, format!("pretty-printing round {}", round));
let ProcRes = print_source(config, testfile, srcs[round].clone());

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(format!("pretty-printing failed in round {}", round),
&ProcRes);
}
Expand Down Expand Up @@ -192,7 +193,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
// Finally, let's make sure it actually appears to remain valid code
let ProcRes = typecheck_source(config, props, testfile, actual);

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"pretty-printed source does not typecheck", &ProcRes);
}

Expand Down Expand Up @@ -264,7 +265,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {

// compile test file (it shoud have 'compile-flags:-g' in the header)
let mut ProcRes = compile_test(config, props, testfile);
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}

Expand Down Expand Up @@ -375,7 +376,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
}
}

if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal(~"gdb failed to execute");
}
let num_check_lines = check_lines.len();
Expand Down Expand Up @@ -431,7 +432,7 @@ fn check_error_patterns(props: &TestProps,
}
}
if ProcRes.status == 0 {
if ProcRes.status.success() {
fatal(~"process did not return an error status");
}

Expand Down Expand Up @@ -473,7 +474,7 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError],
let mut found_flags = vec::from_elem(
expected_errors.len(), false);

if ProcRes.status == 0 {
if ProcRes.status.success() {
fatal(~"process did not return an error status");
}

Expand Down Expand Up @@ -625,7 +626,7 @@ fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool {

struct ProcArgs {prog: ~str, args: ~[~str]}

struct ProcRes {status: int, stdout: ~str, stderr: ~str, cmdline: ~str}
struct ProcRes {status: ProcessExit, stdout: ~str, stderr: ~str, cmdline: ~str}

fn compile_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
Expand Down Expand Up @@ -692,7 +693,7 @@ fn compose_and_run_compiler(
|a,b| make_lib_name(a, b, testfile), &abs_ab);
let auxres = compose_and_run(config, &abs_ab, aux_args, ~[],
config.compile_lib_path, None);
if auxres.status != 0 {
if !auxres.status.success() {
fatal_ProcRes(
format!("auxiliary build of {} failed to compile: ",
abs_ab.display()),
Expand Down Expand Up @@ -966,7 +967,12 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,

dump_output(config, testfile, stdout_out, stderr_out);

ProcRes {status: exitcode, stdout: stdout_out, stderr: stderr_out, cmdline: cmdline }
ProcRes {
status: process::ExitStatus(exitcode),
stdout: stdout_out,
stderr: stderr_out,
cmdline: cmdline
}
}

fn _dummy_exec_compiled_test(config: &config, props: &TestProps,
Expand All @@ -976,9 +982,9 @@ fn _dummy_exec_compiled_test(config: &config, props: &TestProps,
let cmdline = make_cmdline("", args.prog, args.args);

match config.mode {
mode_run_fail => ProcRes {status: 101, stdout: ~"",
mode_run_fail => ProcRes {status: process::ExitStatus(101), stdout: ~"",
stderr: ~"", cmdline: cmdline},
_ => ProcRes {status: 0, stdout: ~"",
_ => ProcRes {status: process::ExitStatus(0), stdout: ~"",
stderr: ~"", cmdline: cmdline}
}
}
Expand Down Expand Up @@ -1099,33 +1105,33 @@ fn run_codegen_test(config: &config, props: &TestProps,
}

let mut ProcRes = compile_test_and_save_bitcode(config, props, testfile);
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}

ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "");
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
}

ProcRes = disassemble_extract(config, props, testfile, "");
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
}


let mut ProcRes = compile_cc_with_clang_and_save_bitcode(config, props, testfile);
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}

ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "clang");
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
}

ProcRes = disassemble_extract(config, props, testfile, "clang");
if ProcRes.status != 0 {
if !ProcRes.status.success() {
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
}

Expand Down
13 changes: 6 additions & 7 deletions src/librustc/back/link.rs
Expand Up @@ -378,9 +378,8 @@ pub mod write {

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

if prog.status != 0 {
sess.err(format!("building with `{}` failed with code {}",
cc_prog, prog.status));
if !prog.status.success() {
sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
sess.note(format!("{} arguments: {}",
cc_prog, cc_args.connect(" ")));
sess.note(str::from_utf8(prog.error + prog.output));
Expand Down Expand Up @@ -947,11 +946,11 @@ pub fn link_binary(sess: Session,

// We run 'cc' here
let prog = run::process_output(cc_prog, cc_args);
if 0 != prog.status {
sess.err(format!("linking with `{}` failed with code {}",
cc_prog, prog.status));

if !prog.status.success() {
sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
sess.note(format!("{} arguments: {}",
cc_prog, cc_args.connect(" ")));
cc_prog, cc_args.connect(" ")));
sess.note(str::from_utf8(prog.error + prog.output));
sess.abort_if_errors();
}
Expand Down
9 changes: 4 additions & 5 deletions src/librustpkg/api.rs
Expand Up @@ -159,17 +159,16 @@ pub fn build_library_in_workspace(exec: &mut workcache::Exec,

let all_args = flags + absolute_paths + cc_args +
~[~"-o", out_name.as_str().unwrap().to_owned()];
let exit_code = run::process_status(tool, all_args);
if exit_code != 0 {
command_failed.raise((tool.to_owned(), all_args, exit_code))
}
else {
let exit_process = run::process_status(tool, all_args);
if exit_process.success() {
let out_name_str = out_name.as_str().unwrap().to_owned();
exec.discover_output("binary",
out_name_str,
digest_only_date(&out_name));
context.add_library_path(out_name.dir_path());
out_name_str
} else {
command_failed.raise((tool.to_owned(), all_args, exit_process))
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustpkg/conditions.rs
Expand Up @@ -13,6 +13,7 @@
pub use std::path::Path;
pub use package_id::PkgId;
pub use std::rt::io::FileStat;
pub use std::rt::io::process::ProcessExit;

condition! {
pub bad_path: (Path, ~str) -> Path;
Expand Down Expand Up @@ -57,5 +58,5 @@ condition! {
condition! {
// str is output of applying the command (first component)
// to the args (second component)
pub command_failed: (~str, ~[~str], int) -> ~str;
pub command_failed: (~str, ~[~str], ProcessExit) -> ~str;
}
9 changes: 5 additions & 4 deletions src/librustpkg/lib.rs
Expand Up @@ -26,6 +26,7 @@ extern mod rustc;
extern mod syntax;

use std::{os, result, run, str, task};
use std::rt::io::process;
use std::hashmap::HashSet;
use std::rt::io;
use std::rt::io::fs;
Expand Down Expand Up @@ -164,14 +165,14 @@ impl<'self> PkgScript<'self> {
/// is the command to pass to it (e.g., "build", "clean", "install")
/// Returns a pair of an exit code and list of configs (obtained by
/// calling the package script's configs() function if it exists
fn run_custom(exe: &Path, sysroot: &Path) -> (~[~str], int) {
fn run_custom(exe: &Path, sysroot: &Path) -> (~[~str], process::ProcessExit) {
debug!("Running program: {} {} {}", exe.as_str().unwrap().to_owned(),
sysroot.display(), "install");
// FIXME #7401 should support commands besides `install`
// FIXME (#9639): This needs to handle non-utf8 paths
let status = run::process_status(exe.as_str().unwrap(),
[sysroot.as_str().unwrap().to_owned(), ~"install"]);
if status != 0 {
if !status.success() {
debug!("run_custom: first pkg command failed with {:?}", status);
(~[], status)
}
Expand Down Expand Up @@ -486,7 +487,7 @@ impl CtxMethods for BuildContext {
// We always *run* the package script
let (cfgs, hook_result) = PkgScript::run_custom(&Path::new(pkg_exe), &sysroot);
debug!("Command return code = {:?}", hook_result);
if hook_result != 0 {
if !hook_result.success() {
fail!("Error running custom build command")
}
custom = true;
Expand Down Expand Up @@ -697,7 +698,7 @@ impl CtxMethods for BuildContext {
debug!("test: test_exec = {}", test_exec.display());
// FIXME (#9639): This needs to handle non-utf8 paths
let status = run::process_status(test_exec.as_str().unwrap(), [~"--test"]);
if status != 0 {
if !status.success() {
fail!("Some tests failed");
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/librustpkg/source_control.rs
Expand Up @@ -36,7 +36,7 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
let outp = run::process_output("git", [~"clone",
source.as_str().unwrap().to_owned(),
target.as_str().unwrap().to_owned()]);
if outp.status != 0 {
if !outp.status.success() {
println(str::from_utf8_owned(outp.output.clone()));
println(str::from_utf8_owned(outp.error));
return DirToUse(target.clone());
Expand All @@ -52,7 +52,7 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
[format!("--work-tree={}", target.as_str().unwrap().to_owned()),
format!("--git-dir={}", git_dir.as_str().unwrap().to_owned()),
~"checkout", format!("{}", *s)]);
if outp.status != 0 {
if !outp.status.success() {
println(str::from_utf8_owned(outp.output.clone()));
println(str::from_utf8_owned(outp.error));
return DirToUse(target.clone());
Expand All @@ -73,7 +73,7 @@ pub fn safe_git_clone(source: &Path, v: &Version, target: &Path) -> CloneResult
format!("--git-dir={}", git_dir.as_str().unwrap().to_owned()),
~"pull", ~"--no-edit", source.as_str().unwrap().to_owned()];
let outp = run::process_output("git", args);
assert!(outp.status == 0);
assert!(outp.status.success());
}
CheckedOutSources
} else {
Expand Down Expand Up @@ -110,7 +110,7 @@ pub fn git_clone_url(source: &str, target: &Path, v: &Version) {
// FIXME (#9639): This needs to handle non-utf8 paths
let outp = run::process_output("git", [~"clone", source.to_owned(),
target.as_str().unwrap().to_owned()]);
if outp.status != 0 {
if !outp.status.success() {
debug!("{}", str::from_utf8_owned(outp.output.clone()));
debug!("{}", str::from_utf8_owned(outp.error));
cond.raise((source.to_owned(), target.clone()))
Expand All @@ -120,7 +120,7 @@ pub fn git_clone_url(source: &str, target: &Path, v: &Version) {
&ExactRevision(ref s) | &Tagged(ref s) => {
let outp = process_output_in_cwd("git", [~"checkout", s.to_owned()],
target);
if outp.status != 0 {
if !outp.status.success() {
debug!("{}", str::from_utf8_owned(outp.output.clone()));
debug!("{}", str::from_utf8_owned(outp.error));
cond.raise((source.to_owned(), target.clone()))
Expand Down

5 comments on commit f698dec

@bors
Copy link
Contributor

@bors bors commented on f698dec Nov 12, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at miselin@f698dec

@bors
Copy link
Contributor

@bors bors commented on f698dec Nov 12, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcmattman/rust/pass-nonzero-exit-status-on-termination-by-signal = f698dec into auto

@bors
Copy link
Contributor

@bors bors commented on f698dec Nov 12, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcmattman/rust/pass-nonzero-exit-status-on-termination-by-signal = f698dec merged ok, testing candidate = 86787f8

@bors
Copy link
Contributor

@bors bors commented on f698dec Nov 12, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on f698dec Nov 12, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 86787f8

Please sign in to comment.