diff --git a/regar.ts b/regar.ts index 74a0ff0..d30b5c4 100755 --- a/regar.ts +++ b/regar.ts @@ -2,7 +2,7 @@ import { exists } from "https://deno.land/std@0.224.0/fs/exists.ts"; import { Command } from "https://deno.land/x/cliffy@v1.0.0-rc.4/command/mod.ts"; -import { Channel } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/mod.ts"; +import { Channel, Constructible, InstanceOf } from "https://git.barnulf.net/mb/barnulf_ts/raw/branch/master/mod.ts"; async function main() { const { do_clear, command, extensions, files, strategy } = await parse_args(); @@ -121,7 +121,7 @@ class WaitStrategy implements ShutdownStrategy { class SoftStrategy implements ShutdownStrategy { async shutdown(process_: Deno.ChildProcess) { - Deno.kill(process_.pid, "SIGINT"); + try_signal(process_.pid, "SIGINT"); await process_.output(); return true; } @@ -129,7 +129,7 @@ class SoftStrategy implements ShutdownStrategy { class HardStrategy implements ShutdownStrategy { async shutdown(process_: Deno.ChildProcess) { - Deno.kill(process_.pid, "SIGKILL"); + try_signal(process_.pid, "SIGKILL"); return await true; } } @@ -145,6 +145,32 @@ async function process_exists(pid: number) { return await exists(`/proc/${pid}`); } +function try_signal(pid: number, sig: Deno.Signal) { + catch_( + () => Deno.kill(pid, sig), + [Deno.errors.NotFound, "ignore"], + ); +} + +// deno-lint-ignore no-explicit-any +type Catching, R = void> = [ + exception: C, + strategy: ((exc: InstanceOf) => R) | "ignore", +]; + +// deno-lint-ignore no-explicit-any +function catch_[]>(op: () => T, ...catchings: Cs) { + try { + return op(); + } catch (exception) { + for (const [kind, strategy] of catchings) { + if (!(exception instanceof kind)) continue; + if (strategy === "ignore") return; + return strategy(exception); + } + } +} + function log(verb: string, value: unknown) { const yellow = "\x1b[0;33m"; const bold = "\x1b[1m";