$
This commit is contained in:
133
node_modules/foreground-child/index.js
generated
vendored
Normal file
133
node_modules/foreground-child/index.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
const signalExit = require('signal-exit')
|
||||
/* istanbul ignore next */
|
||||
const spawn = process.platform === 'win32' ? require('cross-spawn') : require('child_process').spawn
|
||||
|
||||
/**
|
||||
* Normalizes the arguments passed to `foregroundChild`.
|
||||
*
|
||||
* See the signature of `foregroundChild` for the supported arguments.
|
||||
*
|
||||
* @param fgArgs Array of arguments passed to `foregroundChild`.
|
||||
* @return Normalized arguments
|
||||
* @internal
|
||||
*/
|
||||
function normalizeFgArgs(fgArgs) {
|
||||
let program, args, cb;
|
||||
let processArgsEnd = fgArgs.length;
|
||||
const lastFgArg = fgArgs[fgArgs.length - 1];
|
||||
if (typeof lastFgArg === "function") {
|
||||
cb = lastFgArg;
|
||||
processArgsEnd -= 1;
|
||||
} else {
|
||||
cb = (done) => done();
|
||||
}
|
||||
|
||||
if (Array.isArray(fgArgs[0])) {
|
||||
[program, ...args] = fgArgs[0];
|
||||
} else {
|
||||
program = fgArgs[0];
|
||||
args = Array.isArray(fgArgs[1]) ? fgArgs[1] : fgArgs.slice(1, processArgsEnd);
|
||||
}
|
||||
|
||||
return {program, args, cb};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Signatures:
|
||||
* ```
|
||||
* (program: string | string[], cb?: CloseHandler);
|
||||
* (program: string, args: string[], cb?: CloseHandler);
|
||||
* (program: string, ...args: string[], cb?: CloseHandler);
|
||||
* ```
|
||||
*/
|
||||
function foregroundChild (...fgArgs) {
|
||||
const {program, args, cb} = normalizeFgArgs(fgArgs);
|
||||
|
||||
const spawnOpts = { stdio: [0, 1, 2] }
|
||||
|
||||
if (process.send) {
|
||||
spawnOpts.stdio.push('ipc')
|
||||
}
|
||||
|
||||
const child = spawn(program, args, spawnOpts)
|
||||
|
||||
const unproxySignals = proxySignals(process, child)
|
||||
process.on('exit', childHangup)
|
||||
function childHangup () {
|
||||
child.kill('SIGHUP')
|
||||
}
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
// Allow the callback to inspect the child’s exit code and/or modify it.
|
||||
process.exitCode = signal ? 128 + signal : code
|
||||
|
||||
let done = false;
|
||||
const doneCB = () => {
|
||||
if (done) {
|
||||
return
|
||||
}
|
||||
|
||||
done = true
|
||||
unproxySignals()
|
||||
process.removeListener('exit', childHangup)
|
||||
if (signal) {
|
||||
// If there is nothing else keeping the event loop alive,
|
||||
// then there's a race between a graceful exit and getting
|
||||
// the signal to this process. Put this timeout here to
|
||||
// make sure we're still alive to get the signal, and thus
|
||||
// exit with the intended signal code.
|
||||
/* istanbul ignore next */
|
||||
setTimeout(function () {}, 200)
|
||||
process.kill(process.pid, signal)
|
||||
} else {
|
||||
process.exit(process.exitCode)
|
||||
}
|
||||
};
|
||||
|
||||
const result = cb(doneCB);
|
||||
if (result && result.then) {
|
||||
result.then(doneCB);
|
||||
}
|
||||
})
|
||||
|
||||
if (process.send) {
|
||||
process.removeAllListeners('message')
|
||||
|
||||
child.on('message', (message, sendHandle) => {
|
||||
process.send(message, sendHandle)
|
||||
})
|
||||
|
||||
process.on('message', (message, sendHandle) => {
|
||||
child.send(message, sendHandle)
|
||||
})
|
||||
}
|
||||
|
||||
return child
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts forwarding signals to `child` through `parent`.
|
||||
*
|
||||
* @param parent Parent process.
|
||||
* @param child Child Process.
|
||||
* @return `unproxy` function to stop the forwarding.
|
||||
* @internal
|
||||
*/
|
||||
function proxySignals (parent, child) {
|
||||
const listeners = new Map()
|
||||
|
||||
for (const sig of signalExit.signals()) {
|
||||
const listener = () => child.kill(sig)
|
||||
listeners.set(sig, listener)
|
||||
parent.on(sig, listener)
|
||||
}
|
||||
|
||||
return function unproxySignals () {
|
||||
for (const [sig, listener] of listeners) {
|
||||
parent.removeListener(sig, listener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = foregroundChild
|
Reference in New Issue
Block a user