Files
bare-operating-system/packages/bare-os-booter/lib/posix/bare-os-virtual-signal.js
T
2026-08-18 18:11:28 -04:00

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