diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 21ccb2a9989..21209554c16 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -112,6 +112,7 @@ class ProcessWrap : public HandleWrap { object, reinterpret_cast(&process_), AsyncWrap::PROVIDER_PROCESSWRAP) { + process_.pid = 0; MarkAsUninitialized(); } @@ -355,7 +356,10 @@ class ProcessWrap : public HandleWrap { signal = SIGKILL; } #endif - int err = uv_process_kill(&wrap->process_, signal); + // uv_spawn() only assigns a pid when it succeeds, and kill(0, signal) + // signals every process in our own process group. + int err = wrap->process_.pid > 0 ? uv_process_kill(&wrap->process_, signal) + : UV_ESRCH; args.GetReturnValue().Set(err); } diff --git a/test/fixtures/child-process-kill-spawn-error.js b/test/fixtures/child-process-kill-spawn-error.js new file mode 100644 index 00000000000..6dffe5b27ef --- /dev/null +++ b/test/fixtures/child-process-kill-spawn-error.js @@ -0,0 +1,4 @@ +const { spawn } = require('child_process'); +const child = spawn('foo123'); +child.on('error', () => {}); +if (child.kill() !== false || child.killed !== false) process.exit(1); diff --git a/test/parallel/test-child-process-kill-spawn-error.js b/test/parallel/test-child-process-kill-spawn-error.js new file mode 100644 index 00000000000..5889e169492 --- /dev/null +++ b/test/parallel/test-child-process-kill-spawn-error.js @@ -0,0 +1,16 @@ +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const { spawn } = require('child_process'); + +// Killing a child process that never spawned must not signal the process +// group of the caller. The check runs in a detached child so that a +// regression cannot take the test runner down with it. +const childPath = fixtures.path('child-process-kill-spawn-error.js'); +const child = spawn(process.execPath, [childPath], { detached: true }); + +child.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(signal, null); + assert.strictEqual(code, 0); +}));