diff --git a/lib/child_process.js b/lib/child_process.js index bba860a78fe20e..fd9327c38aa45e 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -171,7 +171,7 @@ function fork(modulePath, args = [], options) { throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio'); } - return spawn(options.execPath, args, options); + return module.exports.spawn(options.execPath, args, options); } function _forkChild(fd, serializationMode) { @@ -346,7 +346,7 @@ function execFile(file, args, options, callback) { options.killSignal = sanitizeKillSignal(options.killSignal); - const child = spawn(file, args, { + const child = module.exports.spawn(file, args, { cwd: options.cwd, env: options.env, gid: options.gid, diff --git a/test/parallel/test-child-process-spawn-module-exports.js b/test/parallel/test-child-process-spawn-module-exports.js new file mode 100644 index 00000000000000..9cf808ef54584a --- /dev/null +++ b/test/parallel/test-child-process-spawn-module-exports.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +// Verify that fork() and execFile() call spawn through module.exports +// so that user-level wrapping of child_process.spawn works correctly. +// This is consistent with exec() which already uses module.exports.execFile(). + +if (process.argv[2] === 'child') { + process.exit(0); +} + +const originalSpawn = cp.spawn; + +// Test that fork() uses module.exports.spawn. +cp.spawn = common.mustCall(function(...args) { + cp.spawn = originalSpawn; + return originalSpawn.apply(this, args); +}); + +const child = cp.fork(__filename, ['child']); +child.on('exit', common.mustCall((code) => { + assert.strictEqual(code, 0); + + // Test that execFile() uses module.exports.spawn. + cp.spawn = common.mustCall(function(...args) { + cp.spawn = originalSpawn; + return originalSpawn.apply(this, args); + }); + + cp.execFile(process.execPath, ['--version'], common.mustSucceed()); +}));