Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

lifecycle: propagate SIGTERM to child #10868

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/utils/lifecycle.js
Expand Up @@ -233,6 +233,7 @@ function runCmd_ (cmd, pkg, env, wd, stage, unsafe, uid, gid, cb_) {
}
procError(er)
})
process.once('SIGTERM', procKill)

function procError (er) {
if (progressEnabled) log.enableProgress()
Expand All @@ -248,8 +249,12 @@ function runCmd_ (cmd, pkg, env, wd, stage, unsafe, uid, gid, cb_) {
er.script = cmd
er.pkgname = pkg.name
}
process.removeListener('SIGTERM', procKill)
return cb(er)
}
function procKill () {
proc.kill()
}
}

function runHookLifecycle (pkg, env, wd, unsafe, cb) {
Expand Down
28 changes: 27 additions & 1 deletion test/tap/lifecycle-signal.js
Expand Up @@ -16,7 +16,8 @@ var json = {
name: 'lifecycle-signal',
version: '1.2.5',
scripts: {
preinstall: 'node -e "process.kill(process.pid,\'SIGSEGV\')"'
preinstall: 'node -e "process.kill(process.pid,\'SIGSEGV\')"',
forever: 'node -e "console.error(process.pid);setInterval(function(){},1000)"'
}
}

Expand Down Expand Up @@ -46,6 +47,31 @@ test('lifecycle signal abort', function (t) {
})
})

test('lifecycle propagate signal term to child', function (t) {
// windows does not use lifecycle signals, abort
if (process.platform === 'win32' || process.env.TRAVIS) return t.end()

var innerChildPid
var child = spawn(npm, ['run', 'forever'], {
cwd: pkg
})
child.stderr.on('data', function (data) {
innerChildPid = Number.parseInt(data.toString(), 10)
t.doesNotThrow(function () {
process.kill(innerChildPid, 0) // inner child should be running
})
child.kill() // send SIGTERM to npm
})
child.on('exit', function (code, signal) {
t.equal(code, null)
t.equal(signal, 'SIGTERM')
t.throws(function () {
process.kill(innerChildPid, 0) // SIGTERM should have reached inner child
})
t.end()
})
})

test('cleanup', function (t) {
cleanup()
t.end()
Expand Down