Skip to content

Make process exit status more flexible to allow for handling when a child is terminated by signal #10109

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
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
3 changes: 2 additions & 1 deletion src/compiletest/procsrv.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading