mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
feat(runtime): add op_set_exit_code (#12911)
Set the exit code to use if none is provided to Deno.exit(), or when Deno exits naturally. Needed for process.exitCode Node compat. Paves the way for #12888.
This commit is contained in:
parent
1d3f734e18
commit
993a1dd41a
9 changed files with 57 additions and 3 deletions
|
@ -93,6 +93,7 @@ use std::iter::once;
|
|||
use std::path::PathBuf;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn create_web_worker_callback(ps: ProcState) -> Arc<CreateWebWorkerCb> {
|
||||
|
@ -1475,4 +1476,7 @@ pub fn main() {
|
|||
logger::init(flags.log_level);
|
||||
|
||||
unwrap_or_exit(run_basic(get_subcommand(flags)));
|
||||
|
||||
let code = deno_runtime::EXIT_CODE.load(Relaxed);
|
||||
std::process::exit(code);
|
||||
}
|
||||
|
|
|
@ -859,6 +859,24 @@ itest!(exit_error42 {
|
|||
output: "exit_error42.ts.out",
|
||||
});
|
||||
|
||||
itest!(set_exit_code_0 {
|
||||
args: "run --no-check --unstable set_exit_code_0.ts",
|
||||
output: "empty.out",
|
||||
exit_code: 0,
|
||||
});
|
||||
|
||||
itest!(set_exit_code_1 {
|
||||
args: "run --no-check --unstable set_exit_code_1.ts",
|
||||
output: "empty.out",
|
||||
exit_code: 42,
|
||||
});
|
||||
|
||||
itest!(set_exit_code_2 {
|
||||
args: "run --no-check --unstable set_exit_code_2.ts",
|
||||
output: "empty.out",
|
||||
exit_code: 42,
|
||||
});
|
||||
|
||||
itest!(heapstats {
|
||||
args: "run --quiet --unstable --v8-flags=--expose-gc heapstats.js",
|
||||
output: "heapstats.js.out",
|
||||
|
|
0
cli/tests/testdata/empty.out
vendored
Normal file
0
cli/tests/testdata/empty.out
vendored
Normal file
2
cli/tests/testdata/set_exit_code_0.ts
vendored
Normal file
2
cli/tests/testdata/set_exit_code_0.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Deno.core.opSync("op_set_exit_code", 42);
|
||||
Deno.exit(0); // Takes precedence.
|
2
cli/tests/testdata/set_exit_code_1.ts
vendored
Normal file
2
cli/tests/testdata/set_exit_code_1.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Deno.core.opSync("op_set_exit_code", 42);
|
||||
Deno.exit();
|
2
cli/tests/testdata/set_exit_code_2.ts
vendored
Normal file
2
cli/tests/testdata/set_exit_code_2.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Deno.core.opSync("op_set_exit_code", 42);
|
||||
// Exits naturally.
|
|
@ -31,7 +31,14 @@
|
|||
exitHandler = fn;
|
||||
}
|
||||
|
||||
function exit(code = 0) {
|
||||
function exit(code) {
|
||||
// Set exit code first so unload event listeners can override it.
|
||||
if (typeof code === "number") {
|
||||
core.opSync("op_set_exit_code", code);
|
||||
} else {
|
||||
code = 0;
|
||||
}
|
||||
|
||||
// Dispatches `unload` only when it's not dispatched yet.
|
||||
if (!window[SymbolFor("isUnloadDispatched")]) {
|
||||
// Invokes the `unload` hooks before exiting
|
||||
|
@ -44,7 +51,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
core.opSync("op_exit", code);
|
||||
core.opSync("op_exit");
|
||||
throw new Error("Code not reachable");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::sync::atomic::AtomicI32;
|
||||
|
||||
pub use deno_broadcast_channel;
|
||||
pub use deno_console;
|
||||
pub use deno_crypto;
|
||||
|
@ -29,3 +31,12 @@ pub mod worker;
|
|||
|
||||
mod worker_bootstrap;
|
||||
pub use worker_bootstrap::BootstrapOptions;
|
||||
|
||||
// The global may not be very elegant but:
|
||||
//
|
||||
// 1. op_exit() calls std::process::exit() so there is not much point storing
|
||||
// the exit code in runtime state
|
||||
//
|
||||
// 2. storing it in runtime state makes retrieving it again in cli/main.rs
|
||||
// unduly complicated
|
||||
pub static EXIT_CODE: AtomicI32 = AtomicI32::new(0);
|
||||
|
|
|
@ -10,6 +10,7 @@ use deno_core::OpState;
|
|||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
|
||||
pub fn init() -> Extension {
|
||||
Extension::builder()
|
||||
|
@ -23,6 +24,7 @@ pub fn init() -> Extension {
|
|||
("op_hostname", op_sync(op_hostname)),
|
||||
("op_loadavg", op_sync(op_loadavg)),
|
||||
("op_os_release", op_sync(op_os_release)),
|
||||
("op_set_exit_code", op_sync(op_set_exit_code)),
|
||||
("op_system_memory_info", op_sync(op_system_memory_info)),
|
||||
])
|
||||
.build()
|
||||
|
@ -95,7 +97,13 @@ fn op_delete_env(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn op_exit(_state: &mut OpState, code: i32, _: ()) -> Result<(), AnyError> {
|
||||
fn op_set_exit_code(_: &mut OpState, code: i32, _: ()) -> Result<(), AnyError> {
|
||||
crate::EXIT_CODE.store(code, Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_exit(_: &mut OpState, _: (), _: ()) -> Result<(), AnyError> {
|
||||
let code = crate::EXIT_CODE.load(Relaxed);
|
||||
std::process::exit(code)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue