63 lines
1.8 KiB
JavaScript
63 lines
1.8 KiB
JavaScript
/**
|
|
* Logical signal delivery for synthetic PIDs (guest has no host signals).
|
|
*/
|
|
import {
|
|
BARE_OS_SIGNAL_EXIT,
|
|
BARE_OS_SESSION_EXIT_SIGNALS
|
|
} from './bare-os-posix-signals.js'
|
|
|
|
/**
|
|
* @param {{
|
|
* dispatchShellTrapSignal: (ctx: Record<string, unknown>, sig: string) => unknown,
|
|
* virtualSignalState: Map<number, { signal: string, atMs: number }>
|
|
* }} deps
|
|
*/
|
|
export function createBareOsVirtualSignalDeliverer(deps) {
|
|
const { dispatchShellTrapSignal, virtualSignalState } = deps
|
|
|
|
/**
|
|
* @param {Record<string, unknown>} ctx
|
|
* @param {number} pid
|
|
* @param {string} sig normalized signal short name (e.g. TERM)
|
|
*/
|
|
return function deliverBareOsVirtualSignalToPid(ctx, pid, sig) {
|
|
const extendedSynthetic = Number.isFinite(pid) && pid >= 4100 && pid < 9000
|
|
if (sig === '0') {
|
|
return { ok: true, delivered: false, exists: true }
|
|
}
|
|
if (
|
|
ctx.bareOsLogicalSigaction &&
|
|
ctx.bareOsLogicalSigaction[sig] === 'IGNORE'
|
|
) {
|
|
return {
|
|
ok: true,
|
|
delivered: false,
|
|
ignored: true,
|
|
atMs: Date.now()
|
|
}
|
|
}
|
|
const atMs = Date.now()
|
|
if (
|
|
pid === 3 &&
|
|
(sig === 'INT' || sig === 'TERM' || sig === 'USR1' || sig === 'USR2')
|
|
) {
|
|
Promise.resolve(dispatchShellTrapSignal(ctx, sig)).catch(() => {})
|
|
}
|
|
virtualSignalState.set(pid, { signal: sig, atMs })
|
|
if (typeof globalThis.process?.emit === 'function') {
|
|
try {
|
|
globalThis.process.emit('bare-os:signal', { pid, signal: sig, atMs })
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
const noSessionExit =
|
|
extendedSynthetic || !BARE_OS_SESSION_EXIT_SIGNALS.has(sig)
|
|
if (!noSessionExit) {
|
|
const signum = BARE_OS_SIGNAL_EXIT[sig] || 15
|
|
ctx.requestBooterExit(128 + signum)
|
|
}
|
|
return { ok: true, delivered: true, atMs }
|
|
}
|
|
}
|