Don't use libc::exit. #9473
This can cause unexpected errors in the runtime when done while scheduler threads are still initializing. Required some restructuring of the main_args functions in our libraries.
This commit is contained in:
parent
7535479633
commit
6d03897376
6 changed files with 45 additions and 45 deletions
|
@ -30,7 +30,6 @@ use treemap::TreeMap;
|
||||||
|
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::comm::{stream, SharedChan, GenericPort, GenericChan};
|
use std::comm::{stream, SharedChan, GenericPort, GenericChan};
|
||||||
use std::libc;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::task;
|
use std::task;
|
||||||
|
@ -125,8 +124,9 @@ pub type MetricDiff = TreeMap<~str,MetricChange>;
|
||||||
pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
|
pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
|
||||||
let opts =
|
let opts =
|
||||||
match parse_opts(args) {
|
match parse_opts(args) {
|
||||||
Ok(o) => o,
|
Some(Ok(o)) => o,
|
||||||
Err(msg) => fail!(msg)
|
Some(Err(msg)) => fail!(msg),
|
||||||
|
None => return
|
||||||
};
|
};
|
||||||
if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
|
if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
|
||||||
"A.B")]
|
"A.B")]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(binary: &str, helpstr: &str) -> ! {
|
fn usage(binary: &str, helpstr: &str) {
|
||||||
#[fixed_stack_segment]; #[inline(never)];
|
#[fixed_stack_segment]; #[inline(never)];
|
||||||
|
|
||||||
let message = fmt!("Usage: %s [OPTIONS] [FILTER]", binary);
|
let message = fmt!("Usage: %s [OPTIONS] [FILTER]", binary);
|
||||||
|
@ -217,20 +217,19 @@ Test Attributes:
|
||||||
tests. This may also be written as #[ignore(cfg(...))] to
|
tests. This may also be written as #[ignore(cfg(...))] to
|
||||||
ignore the test on certain configurations.");
|
ignore the test on certain configurations.");
|
||||||
}
|
}
|
||||||
unsafe { libc::exit(0) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses command line arguments into test options
|
// Parses command line arguments into test options
|
||||||
pub fn parse_opts(args: &[~str]) -> OptRes {
|
pub fn parse_opts(args: &[~str]) -> Option<OptRes> {
|
||||||
let args_ = args.tail();
|
let args_ = args.tail();
|
||||||
let matches =
|
let matches =
|
||||||
match groups::getopts(args_, optgroups()) {
|
match groups::getopts(args_, optgroups()) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(f) => return Err(f.to_err_msg())
|
Err(f) => return Some(Err(f.to_err_msg()))
|
||||||
};
|
};
|
||||||
|
|
||||||
if matches.opt_present("h") { usage(args[0], "h"); }
|
if matches.opt_present("h") { usage(args[0], "h"); return None; }
|
||||||
if matches.opt_present("help") { usage(args[0], "help"); }
|
if matches.opt_present("help") { usage(args[0], "help"); return None; }
|
||||||
|
|
||||||
let filter =
|
let filter =
|
||||||
if matches.free.len() > 0 {
|
if matches.free.len() > 0 {
|
||||||
|
@ -272,7 +271,7 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
|
||||||
logfile: logfile
|
logfile: logfile
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(test_opts)
|
Some(Ok(test_opts))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
|
pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
|
||||||
|
@ -1228,7 +1227,7 @@ mod tests {
|
||||||
fn first_free_arg_should_be_a_filter() {
|
fn first_free_arg_should_be_a_filter() {
|
||||||
let args = ~[~"progname", ~"filter"];
|
let args = ~[~"progname", ~"filter"];
|
||||||
let opts = match parse_opts(args) {
|
let opts = match parse_opts(args) {
|
||||||
Ok(o) => o,
|
Some(Ok(o)) => o,
|
||||||
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
|
_ => fail!("Malformed arg in first_free_arg_should_be_a_filter")
|
||||||
};
|
};
|
||||||
assert!("filter" == opts.filter.clone().unwrap());
|
assert!("filter" == opts.filter.clone().unwrap());
|
||||||
|
@ -1238,7 +1237,7 @@ mod tests {
|
||||||
fn parse_ignored_flag() {
|
fn parse_ignored_flag() {
|
||||||
let args = ~[~"progname", ~"filter", ~"--ignored"];
|
let args = ~[~"progname", ~"filter", ~"--ignored"];
|
||||||
let opts = match parse_opts(args) {
|
let opts = match parse_opts(args) {
|
||||||
Ok(o) => o,
|
Some(Ok(o)) => o,
|
||||||
_ => fail!("Malformed arg in parse_ignored_flag")
|
_ => fail!("Malformed arg in parse_ignored_flag")
|
||||||
};
|
};
|
||||||
assert!((opts.run_ignored));
|
assert!((opts.run_ignored));
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl ValidUsage {
|
||||||
|
|
||||||
enum Action {
|
enum Action {
|
||||||
Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
|
Call(extern "Rust" fn(args: &[~str]) -> ValidUsage),
|
||||||
CallMain(&'static str, extern "Rust" fn(&[~str])),
|
CallMain(&'static str, extern "Rust" fn(&[~str]) -> int),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum UsageSource<'self> {
|
enum UsageSource<'self> {
|
||||||
|
@ -186,18 +186,17 @@ fn cmd_run(args: &[~str]) -> ValidUsage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invoke(prog: &str, args: &[~str], f: &fn(&[~str])) {
|
fn invoke(prog: &str, args: &[~str], f: &fn(&[~str]) -> int) -> int {
|
||||||
let mut osargs = ~[prog.to_owned()];
|
let mut osargs = ~[prog.to_owned()];
|
||||||
osargs.push_all_move(args.to_owned());
|
osargs.push_all_move(args.to_owned());
|
||||||
f(osargs);
|
f(osargs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
|
fn do_command(command: &Command, args: &[~str]) -> ValidUsage {
|
||||||
match command.action {
|
match command.action {
|
||||||
Call(f) => f(args),
|
Call(f) => f(args),
|
||||||
CallMain(prog, f) => {
|
CallMain(prog, f) => {
|
||||||
invoke(prog, args, f);
|
Valid(invoke(prog, args, f))
|
||||||
Valid(0)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -394,13 +394,14 @@ pub fn monitor(f: ~fn(@diagnostic::Emitter)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let args = os::args();
|
std::os::set_exit_status(main_args(std::os::args()));
|
||||||
main_args(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_args(args: &[~str]) {
|
pub fn main_args(args: &[~str]) -> int {
|
||||||
let owned_args = args.to_owned();
|
let owned_args = args.to_owned();
|
||||||
do monitor |demitter| {
|
do monitor |demitter| {
|
||||||
run_compiler(owned_args, demitter);
|
run_compiler(owned_args, demitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ enum OutputFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
main_args(std::os::args());
|
std::os::set_exit_status(main_args(std::os::args()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opts() -> ~[groups::OptGroup] {
|
pub fn opts() -> ~[groups::OptGroup] {
|
||||||
|
@ -76,14 +76,14 @@ pub fn usage(argv0: &str) {
|
||||||
argv0), opts()));
|
argv0), opts()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_args(args: &[~str]) {
|
pub fn main_args(args: &[~str]) -> int {
|
||||||
//use extra::getopts::groups::*;
|
//use extra::getopts::groups::*;
|
||||||
|
|
||||||
let matches = groups::getopts(args.tail(), opts()).unwrap();
|
let matches = groups::getopts(args.tail(), opts()).unwrap();
|
||||||
|
|
||||||
if matches.opt_present("h") || matches.opt_present("help") {
|
if matches.opt_present("h") || matches.opt_present("help") {
|
||||||
usage(args[0]);
|
usage(args[0]);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (format, cratefile) = match matches.free.clone() {
|
let (format, cratefile) = match matches.free.clone() {
|
||||||
|
@ -92,17 +92,17 @@ pub fn main_args(args: &[~str]) {
|
||||||
[s, _] => {
|
[s, _] => {
|
||||||
println!("Unknown output format: `{}`", s);
|
println!("Unknown output format: `{}`", s);
|
||||||
usage(args[0]);
|
usage(args[0]);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
[_, .._] => {
|
[_, .._] => {
|
||||||
println!("Expected exactly one crate to process");
|
println!("Expected exactly one crate to process");
|
||||||
usage(args[0]);
|
usage(args[0]);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Expected an output format and then one crate");
|
println!("Expected an output format and then one crate");
|
||||||
usage(args[0]);
|
usage(args[0]);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,6 +179,8 @@ pub fn main_args(args: &[~str]) {
|
||||||
}
|
}
|
||||||
let ended = time::precise_time_ns();
|
let ended = time::precise_time_ns();
|
||||||
info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
|
info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
|
fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
|
||||||
|
@ -208,9 +210,3 @@ fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
|
||||||
let output = extra::json::Object(json).to_str();
|
let output = extra::json::Object(json).to_str();
|
||||||
file.write(output.as_bytes());
|
file.write(output.as_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit(status: int) -> ! {
|
|
||||||
#[fixed_stack_segment]; #[inline(never)];
|
|
||||||
use std::libc;
|
|
||||||
unsafe { libc::exit(status as libc::c_int) }
|
|
||||||
}
|
|
||||||
|
|
|
@ -517,8 +517,7 @@ pub fn run_line(repl: &mut Repl, input: @io::Reader, out: @io::Writer, line: ~st
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let args = os::args();
|
os::set_exit_status(main_args(os::args()));
|
||||||
main_args(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Completer;
|
struct Completer;
|
||||||
|
@ -534,7 +533,7 @@ impl CompletionCb for Completer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_args(args: &[~str]) {
|
pub fn main_args(args: &[~str]) -> int {
|
||||||
#[fixed_stack_segment]; #[inline(never)];
|
#[fixed_stack_segment]; #[inline(never)];
|
||||||
|
|
||||||
let input = io::stdin();
|
let input = io::stdin();
|
||||||
|
@ -576,6 +575,8 @@ pub fn main_args(args: &[~str]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -615,11 +615,10 @@ impl CtxMethods for BuildContext {
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
io::println("WARNING: The Rust package manager is experimental and may be unstable");
|
io::println("WARNING: The Rust package manager is experimental and may be unstable");
|
||||||
let args = os::args();
|
os::set_exit_status(main_args(os::args()));
|
||||||
main_args(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_args(args: &[~str]) {
|
pub fn main_args(args: &[~str]) -> int {
|
||||||
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
let opts = ~[getopts::optflag("h"), getopts::optflag("help"),
|
||||||
getopts::optflag("no-link"),
|
getopts::optflag("no-link"),
|
||||||
getopts::optflag("no-trans"),
|
getopts::optflag("no-trans"),
|
||||||
|
@ -645,7 +644,7 @@ pub fn main_args(args: &[~str]) {
|
||||||
result::Err(f) => {
|
result::Err(f) => {
|
||||||
error(fmt!("%s", f.to_err_msg()));
|
error(fmt!("%s", f.to_err_msg()));
|
||||||
|
|
||||||
return;
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut help = matches.opt_present("h") ||
|
let mut help = matches.opt_present("h") ||
|
||||||
|
@ -662,7 +661,7 @@ pub fn main_args(args: &[~str]) {
|
||||||
if matches.opt_present("v") ||
|
if matches.opt_present("v") ||
|
||||||
matches.opt_present("version") {
|
matches.opt_present("version") {
|
||||||
rustc::version(args[0]);
|
rustc::version(args[0]);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let use_rust_path_hack = matches.opt_present("r") ||
|
let use_rust_path_hack = matches.opt_present("r") ||
|
||||||
|
@ -701,7 +700,8 @@ pub fn main_args(args: &[~str]) {
|
||||||
args.shift();
|
args.shift();
|
||||||
|
|
||||||
if (args.len() < 1) {
|
if (args.len() < 1) {
|
||||||
return usage::general();
|
usage::general();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let rustc_flags = RustcFlags {
|
let rustc_flags = RustcFlags {
|
||||||
|
@ -739,11 +739,14 @@ pub fn main_args(args: &[~str]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let cmd = match cmd_opt {
|
let cmd = match cmd_opt {
|
||||||
None => return usage::general(),
|
None => {
|
||||||
|
usage::general();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Some(cmd) => {
|
Some(cmd) => {
|
||||||
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
|
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
|
||||||
if help {
|
if help {
|
||||||
return match *cmd {
|
match *cmd {
|
||||||
~"build" => usage::build(),
|
~"build" => usage::build(),
|
||||||
~"clean" => usage::clean(),
|
~"clean" => usage::clean(),
|
||||||
~"do" => usage::do_cmd(),
|
~"do" => usage::do_cmd(),
|
||||||
|
@ -757,6 +760,7 @@ pub fn main_args(args: &[~str]) {
|
||||||
~"unprefer" => usage::unprefer(),
|
~"unprefer" => usage::unprefer(),
|
||||||
_ => usage::general()
|
_ => usage::general()
|
||||||
};
|
};
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
@ -794,8 +798,8 @@ pub fn main_args(args: &[~str]) {
|
||||||
// and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
|
// and at least one test case succeeds if rustpkg returns COPY_FAILED_CODE,
|
||||||
// when actually, it might set the exit code for that even if a different
|
// when actually, it might set the exit code for that even if a different
|
||||||
// unhandled condition got raised.
|
// unhandled condition got raised.
|
||||||
if result.is_err() { os::set_exit_status(COPY_FAILED_CODE); }
|
if result.is_err() { return COPY_FAILED_CODE; }
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue