Skip to content

Commit 0616cba

Browse files
committed
libcore: Add sys::set_exit_status
Sets the process exit code
1 parent dcac427 commit 0616cba

10 files changed

+68
-5
lines changed

src/libcore/sys.rs

+13
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ native mod rustrt {
2020
fn do_gc();
2121
fn unsupervise();
2222
fn shape_log_str<T>(t: *sys::type_desc, data: T) -> str;
23+
fn rust_set_exit_status(code: int);
2324
}
2425

2526
#[abi = "rust-intrinsic"]
@@ -92,6 +93,18 @@ fn log_str<T>(t: T) -> str {
9293
rustrt::shape_log_str(get_type_desc::<T>(), t)
9394
}
9495

96+
#[doc(
97+
brief = "Sets the process exit code",
98+
desc = "Sets the exit code returned by the process if all supervised \
99+
tasks terminate successfully (without failing). If the current \
100+
root task fails and is supervised by the scheduler then any \
101+
user-specified exit status is ignored and the process exits \
102+
with the default failure status."
103+
)]
104+
fn set_exit_status(code: int) {
105+
rustrt::rust_set_exit_status(code);
106+
}
107+
95108
// Local Variables:
96109
// mode: rust;
97110
// fill-column: 78;

src/rt/rust_builtin.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,12 @@ port_recv(uintptr_t *dptr, rust_port *port,
561561
return;
562562
}
563563

564+
extern "C" CDECL void
565+
rust_set_exit_status(intptr_t code) {
566+
rust_task *task = rust_scheduler::get_task();
567+
task->kernel->set_exit_status((int)code);
568+
}
569+
564570
//
565571
// Local Variables:
566572
// mode: C++

src/rt/rust_internal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static size_t const TIME_SLICE_IN_MS = 10;
9292
static size_t const BUF_BYTES = 2048;
9393

9494
// The error status to use when the process fails
95-
#define PROC_FAIL_CODE 101;
95+
#define PROC_FAIL_CODE 101
9696

9797
// Every reference counted object should use this macro and initialize
9898
// ref_count.

src/rt/rust_kernel.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
1111
_log(srv, NULL),
1212
srv(srv),
1313
max_id(0),
14-
num_threads(num_threads),
1514
rval(0),
15+
num_threads(num_threads),
1616
live_tasks(0),
1717
env(srv->env)
1818
{
@@ -140,6 +140,7 @@ rust_kernel::fail() {
140140
// FIXME: On windows we're getting "Application has requested the
141141
// Runtime to terminate it in an unusual way" when trying to shutdown
142142
// cleanly.
143+
set_exit_status(PROC_FAIL_CODE);
143144
#if defined(__WIN32__)
144145
exit(rval);
145146
#endif
@@ -210,6 +211,15 @@ rust_kernel::win32_require(LPCTSTR fn, BOOL ok) {
210211
}
211212
#endif
212213

214+
void
215+
rust_kernel::set_exit_status(int code) {
216+
scoped_lock with(_kernel_lock);
217+
// If we've already failed then that's the code we're going to use
218+
if (rval != PROC_FAIL_CODE) {
219+
rval = code;
220+
}
221+
}
222+
213223
//
214224
// Local Variables:
215225
// mode: C++

src/rt/rust_kernel.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class rust_kernel {
3434
rust_task_id max_id;
3535
hash_map<rust_task_id, rust_task *> task_table;
3636

37+
int rval;
38+
3739
public:
3840
const size_t num_threads;
39-
int rval;
4041

4142
volatile int live_tasks;
4243
struct rust_env *env;
@@ -68,6 +69,7 @@ class rust_kernel {
6869
rust_task_id create_task(rust_task *spawner, const char *name);
6970
rust_task *get_task_by_id(rust_task_id id);
7071
void release_task_id(rust_task_id tid);
72+
void set_exit_status(int code);
7173
};
7274

7375
#endif /* RUST_KERNEL_H */

src/rt/rust_scheduler.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ void
8282
rust_scheduler::fail() {
8383
log(NULL, log_err, "domain %s @0x%" PRIxPTR " root task failed",
8484
name, this);
85-
I(this, kernel->rval == 0);
86-
kernel->rval = PROC_FAIL_CODE;
8785
kernel->fail();
8886
}
8987

src/rt/rustrt.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ rust_port_size
4141
rust_process_wait
4242
rust_ptr_eq
4343
rust_run_program
44+
rust_set_exit_status
4445
rust_start
4546
rust_getcwd
4647
rust_task_is_unwinding
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern:whatever
2+
3+
fn main() {
4+
log(error, "whatever");
5+
// Setting the exit status only works when the scheduler terminates
6+
// normally. In this case we're going to fail, so instead of of
7+
// returning 50 the process will return the typical rt failure code.
8+
sys::set_exit_status(50);
9+
fail;
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// error-pattern:whatever
2+
3+
fn main() {
4+
log(error, "whatever");
5+
task::spawn {||
6+
resource r(_i: ()) {
7+
// Setting the exit status after the runtime has already
8+
// failed has no effect and the process exits with the
9+
// runtime's exit code
10+
sys::set_exit_status(50);
11+
}
12+
let i = r(());
13+
};
14+
fail;
15+
}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// error-pattern:whatever
2+
3+
fn main() {
4+
log(error, "whatever");
5+
// 101 is the code the runtime uses on task failure and the value
6+
// compiletest expects run-fail tests to return.
7+
sys::set_exit_status(101);
8+
}

0 commit comments

Comments
 (0)