1
0
Fork 0
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:
Ben Noordhuis 2021-11-28 00:45:38 +01:00 committed by GitHub
parent 1d3f734e18
commit 993a1dd41a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 57 additions and 3 deletions

View file

@ -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);
}

View file

@ -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
View file

2
cli/tests/testdata/set_exit_code_0.ts vendored Normal file
View 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
View 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
View file

@ -0,0 +1,2 @@
Deno.core.opSync("op_set_exit_code", 42);
// Exits naturally.

View file

@ -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");
}

View file

@ -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);

View file

@ -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)
}