diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-01-12 22:17:21 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-01-12 22:24:27 -0800 |
| commit | 0616cba62be78082f10f6673d45ba4d94da423dc (patch) | |
| tree | 0cd1d0cf9434a751b293b8292da1c153065da491 /src | |
| parent | dcac427795285a46232722a38e8a5f88ae4dc891 (diff) | |
| download | rust-0616cba62be78082f10f6673d45ba4d94da423dc.tar.gz rust-0616cba62be78082f10f6673d45ba4d94da423dc.zip | |
libcore: Add sys::set_exit_status
Sets the process exit code
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/sys.rs | 13 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 6 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 2 | ||||
| -rw-r--r-- | src/rt/rust_kernel.cpp | 12 | ||||
| -rw-r--r-- | src/rt/rust_kernel.h | 4 | ||||
| -rw-r--r-- | src/rt/rust_scheduler.cpp | 2 | ||||
| -rw-r--r-- | src/rt/rustrt.def.in | 1 | ||||
| -rw-r--r-- | src/test/run-fail/rt-set-exit-status-fail.rs | 10 | ||||
| -rw-r--r-- | src/test/run-fail/rt-set-exit-status-fail2.rs | 15 | ||||
| -rw-r--r-- | src/test/run-fail/rt-set-exit-status.rs | 8 |
10 files changed, 68 insertions, 5 deletions
diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 21032e72122..96e5947daf0 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -20,6 +20,7 @@ native mod rustrt { fn do_gc(); fn unsupervise(); fn shape_log_str<T>(t: *sys::type_desc, data: T) -> str; + fn rust_set_exit_status(code: int); } #[abi = "rust-intrinsic"] @@ -92,6 +93,18 @@ fn log_str<T>(t: T) -> str { rustrt::shape_log_str(get_type_desc::<T>(), t) } +#[doc( + brief = "Sets the process exit code", + desc = "Sets the exit code returned by the process if all supervised \ + tasks terminate successfully (without failing). If the current \ + root task fails and is supervised by the scheduler then any \ + user-specified exit status is ignored and the process exits \ + with the default failure status." +)] +fn set_exit_status(code: int) { + rustrt::rust_set_exit_status(code); +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 264e6fdb325..7bd1c76c187 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -561,6 +561,12 @@ port_recv(uintptr_t *dptr, rust_port *port, return; } +extern "C" CDECL void +rust_set_exit_status(intptr_t code) { + rust_task *task = rust_scheduler::get_task(); + task->kernel->set_exit_status((int)code); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index b83d74f6bfe..aa62c22fc8f 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -92,7 +92,7 @@ static size_t const TIME_SLICE_IN_MS = 10; static size_t const BUF_BYTES = 2048; // The error status to use when the process fails -#define PROC_FAIL_CODE 101; +#define PROC_FAIL_CODE 101 // Every reference counted object should use this macro and initialize // ref_count. diff --git a/src/rt/rust_kernel.cpp b/src/rt/rust_kernel.cpp index 3078f6b78c4..a7e4ee2e450 100644 --- a/src/rt/rust_kernel.cpp +++ b/src/rt/rust_kernel.cpp @@ -11,8 +11,8 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) : _log(srv, NULL), srv(srv), max_id(0), - num_threads(num_threads), rval(0), + num_threads(num_threads), live_tasks(0), env(srv->env) { @@ -140,6 +140,7 @@ rust_kernel::fail() { // FIXME: On windows we're getting "Application has requested the // Runtime to terminate it in an unusual way" when trying to shutdown // cleanly. + set_exit_status(PROC_FAIL_CODE); #if defined(__WIN32__) exit(rval); #endif @@ -210,6 +211,15 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) { } #endif +void +rust_kernel::set_exit_status(int code) { + scoped_lock with(_kernel_lock); + // If we've already failed then that's the code we're going to use + if (rval != PROC_FAIL_CODE) { + rval = code; + } +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_kernel.h b/src/rt/rust_kernel.h index 8d59dabdcb9..f60987acae5 100644 --- a/src/rt/rust_kernel.h +++ b/src/rt/rust_kernel.h @@ -34,9 +34,10 @@ private: rust_task_id max_id; hash_map<rust_task_id, rust_task *> task_table; + int rval; + public: const size_t num_threads; - int rval; volatile int live_tasks; struct rust_env *env; @@ -68,6 +69,7 @@ public: rust_task_id create_task(rust_task *spawner, const char *name); rust_task *get_task_by_id(rust_task_id id); void release_task_id(rust_task_id tid); + void set_exit_status(int code); }; #endif /* RUST_KERNEL_H */ diff --git a/src/rt/rust_scheduler.cpp b/src/rt/rust_scheduler.cpp index 1df70306975..0b4e35910ac 100644 --- a/src/rt/rust_scheduler.cpp +++ b/src/rt/rust_scheduler.cpp @@ -82,8 +82,6 @@ void rust_scheduler::fail() { log(NULL, log_err, "domain %s @0x%" PRIxPTR " root task failed", name, this); - I(this, kernel->rval == 0); - kernel->rval = PROC_FAIL_CODE; kernel->fail(); } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 7e57625fac1..e058ad739df 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -41,6 +41,7 @@ rust_port_size rust_process_wait rust_ptr_eq rust_run_program +rust_set_exit_status rust_start rust_getcwd rust_task_is_unwinding diff --git a/src/test/run-fail/rt-set-exit-status-fail.rs b/src/test/run-fail/rt-set-exit-status-fail.rs new file mode 100644 index 00000000000..fd32ff04600 --- /dev/null +++ b/src/test/run-fail/rt-set-exit-status-fail.rs @@ -0,0 +1,10 @@ +// error-pattern:whatever + +fn main() { + log(error, "whatever"); + // Setting the exit status only works when the scheduler terminates + // normally. In this case we're going to fail, so instead of of + // returning 50 the process will return the typical rt failure code. + sys::set_exit_status(50); + fail; +} \ No newline at end of file diff --git a/src/test/run-fail/rt-set-exit-status-fail2.rs b/src/test/run-fail/rt-set-exit-status-fail2.rs new file mode 100644 index 00000000000..5d973d2a9e3 --- /dev/null +++ b/src/test/run-fail/rt-set-exit-status-fail2.rs @@ -0,0 +1,15 @@ +// error-pattern:whatever + +fn main() { + log(error, "whatever"); + task::spawn {|| + resource r(_i: ()) { + // Setting the exit status after the runtime has already + // failed has no effect and the process exits with the + // runtime's exit code + sys::set_exit_status(50); + } + let i = r(()); + }; + fail; +} \ No newline at end of file diff --git a/src/test/run-fail/rt-set-exit-status.rs b/src/test/run-fail/rt-set-exit-status.rs new file mode 100644 index 00000000000..e9e8f239434 --- /dev/null +++ b/src/test/run-fail/rt-set-exit-status.rs @@ -0,0 +1,8 @@ +// error-pattern:whatever + +fn main() { + log(error, "whatever"); + // 101 is the code the runtime uses on task failure and the value + // compiletest expects run-fail tests to return. + sys::set_exit_status(101); +} \ No newline at end of file |
