1const runningProcs = new Set() 2let handlersInstalled = false 3 4const forwardedSignals = [ 5 'SIGINT', 6 'SIGTERM', 7] 8 9// no-op, this is so receiving the signal doesn't cause us to exit immediately 10// instead, we exit after all children have exited when we re-send the signal 11// to ourselves. see the catch handler at the bottom of run-script-pkg.js 12const handleSignal = signal => { 13 for (const proc of runningProcs) { 14 proc.kill(signal) 15 } 16} 17 18const setupListeners = () => { 19 for (const signal of forwardedSignals) { 20 process.on(signal, handleSignal) 21 } 22 handlersInstalled = true 23} 24 25const cleanupListeners = () => { 26 if (runningProcs.size === 0) { 27 for (const signal of forwardedSignals) { 28 process.removeListener(signal, handleSignal) 29 } 30 handlersInstalled = false 31 } 32} 33 34const add = proc => { 35 runningProcs.add(proc) 36 if (!handlersInstalled) { 37 setupListeners() 38 } 39 40 proc.once('exit', () => { 41 runningProcs.delete(proc) 42 cleanupListeners() 43 }) 44} 45 46module.exports = { 47 add, 48 handleSignal, 49 forwardedSignals, 50} 51