pax_global_header 0000666 0000000 0000000 00000000064 13020705623 0014510 g ustar 00root root 0000000 0000000 52 comment=9c5ad9809fe6135ef22e2623989deaffe2a4fa8a
signal-exit-3.0.2/ 0000775 0000000 0000000 00000000000 13020705623 0013736 5 ustar 00root root 0000000 0000000 signal-exit-3.0.2/.gitignore 0000664 0000000 0000000 00000000067 13020705623 0015731 0 ustar 00root root 0000000 0000000 node_modules
.DS_Store
nyc_output
coverage
.nyc_output
signal-exit-3.0.2/.travis.yml 0000664 0000000 0000000 00000000102 13020705623 0016040 0 ustar 00root root 0000000 0000000 sudo: false
language: node_js
node_js:
- '0.12'
- '4'
- '5'
signal-exit-3.0.2/CHANGELOG.md 0000664 0000000 0000000 00000002057 13020705623 0015553 0 ustar 00root root 0000000 0000000 # Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [3.0.1](https://github.com/tapjs/signal-exit/compare/v3.0.0...v3.0.1) (2016-09-08)
### Bug Fixes
* do not listen on SIGBUS, SIGFPE, SIGSEGV and SIGILL ([#40](https://github.com/tapjs/signal-exit/issues/40)) ([5b105fb](https://github.com/tapjs/signal-exit/commit/5b105fb))
# [3.0.0](https://github.com/tapjs/signal-exit/compare/v2.1.2...v3.0.0) (2016-06-13)
### Bug Fixes
* get our test suite running on Windows ([#23](https://github.com/tapjs/signal-exit/issues/23)) ([6f3eda8](https://github.com/tapjs/signal-exit/commit/6f3eda8))
* hooking SIGPROF was interfering with profilers see [#21](https://github.com/tapjs/signal-exit/issues/21) ([#24](https://github.com/tapjs/signal-exit/issues/24)) ([1248a4c](https://github.com/tapjs/signal-exit/commit/1248a4c))
### BREAKING CHANGES
* signal-exit no longer wires into SIGPROF
signal-exit-3.0.2/LICENSE.txt 0000664 0000000 0000000 00000001354 13020705623 0015564 0 ustar 00root root 0000000 0000000 The ISC License
Copyright (c) 2015, Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice
appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
signal-exit-3.0.2/README.md 0000664 0000000 0000000 00000002731 13020705623 0015220 0 ustar 00root root 0000000 0000000 # signal-exit
[](https://travis-ci.org/tapjs/signal-exit)
[](https://coveralls.io/r/tapjs/signal-exit?branch=master)
[](https://www.npmjs.com/package/signal-exit)
[](https://ci.appveyor.com/project/bcoe/signal-exit)
[](https://github.com/conventional-changelog/standard-version)
When you want to fire an event no matter how a process exits:
* reaching the end of execution.
* explicitly having `process.exit(code)` called.
* having `process.kill(pid, sig)` called.
* receiving a fatal signal from outside the process
Use `signal-exit`.
```js
var onExit = require('signal-exit')
onExit(function (code, signal) {
console.log('process exited!')
})
```
## API
`var remove = onExit(function (code, signal) {}, options)`
The return value of the function is a function that will remove the
handler.
Note that the function *only* fires for signals if the signal would
cause the proces to exit. That is, there are no other listeners, and
it is a fatal signal.
## Options
* `alwaysLast`: Run this handler after any other signal or exit
handlers. This causes `process.emit` to be monkeypatched.
signal-exit-3.0.2/appveyor.yml 0000664 0000000 0000000 00000000571 13020705623 0016331 0 ustar 00root root 0000000 0000000 environment:
matrix:
- nodejs_version: '5'
- nodejs_version: '4'
- nodejs_version: '0.12'
install:
- ps: Install-Product node $env:nodejs_version
- set CI=true
- npm -g install npm@latest
- set PATH=%APPDATA%\npm;%PATH%
- npm install
matrix:
fast_finish: true
build: off
version: '{build}'
shallow_clone: true
clone_depth: 1
test_script:
- npm test
signal-exit-3.0.2/index.js 0000664 0000000 0000000 00000007505 13020705623 0015412 0 ustar 00root root 0000000 0000000 // Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
var assert = require('assert')
var signals = require('./signals.js')
var EE = require('events')
/* istanbul ignore if */
if (typeof EE !== 'function') {
EE = EE.EventEmitter
}
var emitter
if (process.__signal_exit_emitter__) {
emitter = process.__signal_exit_emitter__
} else {
emitter = process.__signal_exit_emitter__ = new EE()
emitter.count = 0
emitter.emitted = {}
}
// Because this emitter is a global, we have to check to see if a
// previous version of this library failed to enable infinite listeners.
// I know what you're about to say. But literally everything about
// signal-exit is a compromise with evil. Get used to it.
if (!emitter.infinite) {
emitter.setMaxListeners(Infinity)
emitter.infinite = true
}
module.exports = function (cb, opts) {
assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler')
if (loaded === false) {
load()
}
var ev = 'exit'
if (opts && opts.alwaysLast) {
ev = 'afterexit'
}
var remove = function () {
emitter.removeListener(ev, cb)
if (emitter.listeners('exit').length === 0 &&
emitter.listeners('afterexit').length === 0) {
unload()
}
}
emitter.on(ev, cb)
return remove
}
module.exports.unload = unload
function unload () {
if (!loaded) {
return
}
loaded = false
signals.forEach(function (sig) {
try {
process.removeListener(sig, sigListeners[sig])
} catch (er) {}
})
process.emit = originalProcessEmit
process.reallyExit = originalProcessReallyExit
emitter.count -= 1
}
function emit (event, code, signal) {
if (emitter.emitted[event]) {
return
}
emitter.emitted[event] = true
emitter.emit(event, code, signal)
}
// { : , ... }
var sigListeners = {}
signals.forEach(function (sig) {
sigListeners[sig] = function listener () {
// If there are no other listeners, an exit is coming!
// Simplest way: remove us and then re-send the signal.
// We know that this will kill the process, so we can
// safely emit now.
var listeners = process.listeners(sig)
if (listeners.length === emitter.count) {
unload()
emit('exit', null, sig)
/* istanbul ignore next */
emit('afterexit', null, sig)
/* istanbul ignore next */
process.kill(process.pid, sig)
}
}
})
module.exports.signals = function () {
return signals
}
module.exports.load = load
var loaded = false
function load () {
if (loaded) {
return
}
loaded = true
// This is the number of onSignalExit's that are in play.
// It's important so that we can count the correct number of
// listeners on signals, and don't wait for the other one to
// handle it instead of us.
emitter.count += 1
signals = signals.filter(function (sig) {
try {
process.on(sig, sigListeners[sig])
return true
} catch (er) {
return false
}
})
process.emit = processEmit
process.reallyExit = processReallyExit
}
var originalProcessReallyExit = process.reallyExit
function processReallyExit (code) {
process.exitCode = code || 0
emit('exit', process.exitCode, null)
/* istanbul ignore next */
emit('afterexit', process.exitCode, null)
/* istanbul ignore next */
originalProcessReallyExit.call(process, process.exitCode)
}
var originalProcessEmit = process.emit
function processEmit (ev, arg) {
if (ev === 'exit') {
if (arg !== undefined) {
process.exitCode = arg
}
var ret = originalProcessEmit.apply(this, arguments)
emit('exit', process.exitCode, null)
/* istanbul ignore next */
emit('afterexit', process.exitCode, null)
return ret
} else {
return originalProcessEmit.apply(this, arguments)
}
}
signal-exit-3.0.2/package.json 0000664 0000000 0000000 00000001615 13020705623 0016227 0 ustar 00root root 0000000 0000000 {
"name": "signal-exit",
"version": "3.0.2",
"description": "when you want to fire an event no matter how a process exits.",
"main": "index.js",
"scripts": {
"pretest": "standard",
"test": "tap --timeout=240 ./test/*.js --cov",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"release": "standard-version"
},
"files": [
"index.js",
"signals.js"
],
"repository": {
"type": "git",
"url": "https://github.com/tapjs/signal-exit.git"
},
"keywords": [
"signal",
"exit"
],
"author": "Ben Coe ",
"license": "ISC",
"bugs": {
"url": "https://github.com/tapjs/signal-exit/issues"
},
"homepage": "https://github.com/tapjs/signal-exit",
"devDependencies": {
"chai": "^3.5.0",
"coveralls": "^2.11.10",
"nyc": "^8.1.0",
"standard": "^7.1.2",
"standard-version": "^2.3.0",
"tap": "^8.0.1"
}
}
signal-exit-3.0.2/signals.js 0000664 0000000 0000000 00000002417 13020705623 0015740 0 ustar 00root root 0000000 0000000 // This is not the set of all possible signals.
//
// It IS, however, the set of all signals that trigger
// an exit on either Linux or BSD systems. Linux is a
// superset of the signal names supported on BSD, and
// the unknown signals just fail to register, so we can
// catch that easily enough.
//
// Don't bother with SIGKILL. It's uncatchable, which
// means that we can't fire any callbacks anyway.
//
// If a user does happen to register a handler on a non-
// fatal signal like SIGWINCH or something, and then
// exit, it'll end up firing `process.emit('exit')`, so
// the handler will be fired anyway.
//
// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
// artificially, inherently leave the process in a
// state from which it is not safe to try and enter JS
// listeners.
module.exports = [
'SIGABRT',
'SIGALRM',
'SIGHUP',
'SIGINT',
'SIGTERM'
]
if (process.platform !== 'win32') {
module.exports.push(
'SIGVTALRM',
'SIGXCPU',
'SIGXFSZ',
'SIGUSR2',
'SIGTRAP',
'SIGSYS',
'SIGQUIT',
'SIGIOT'
// should detect profiler and enable/disable accordingly.
// see #21
// 'SIGPROF'
)
}
if (process.platform === 'linux') {
module.exports.push(
'SIGIO',
'SIGPOLL',
'SIGPWR',
'SIGSTKFLT',
'SIGUNUSED'
)
}
signal-exit-3.0.2/test/ 0000775 0000000 0000000 00000000000 13020705623 0014715 5 ustar 00root root 0000000 0000000 signal-exit-3.0.2/test/all-integration-test.js 0000664 0000000 0000000 00000005740 13020705623 0021327 0 ustar 00root root 0000000 0000000 /* global describe, it */
var exec = require('child_process').exec
var assert = require('assert')
var isWindows = process.platform === 'win32'
var shell = isWindows ? null : { shell: '/bin/bash' }
var node = isWindows ? '"' + process.execPath + '"' : process.execPath
require('chai').should()
require('tap').mochaGlobals()
var onSignalExit = require('../')
describe('all-signals-integration-test', function () {
// These are signals that are aliases for other signals, so
// the result will sometimes be one of the others. For these,
// we just verify that we GOT a signal, not what it is.
function weirdSignal (sig) {
return sig === 'SIGIOT' ||
sig === 'SIGIO' ||
sig === 'SIGSYS' ||
sig === 'SIGIOT' ||
sig === 'SIGABRT' ||
sig === 'SIGPOLL' ||
sig === 'SIGUNUSED'
}
// Exhaustively test every signal, and a few numbers.
// signal-exit does not currently support process.kill()
// on win32.
var signals = isWindows ? [] : onSignalExit.signals()
signals.concat('', 0, 1, 2, 3, 54).forEach(function (sig) {
var js = require.resolve('./fixtures/exiter.js')
it('exits properly: ' + sig, function (done) {
// issues with SIGUSR1 on Node 0.10.x
if (process.version.match(/^v0\.10\./) && sig === 'SIGUSR1') return done()
var cmd = node + ' ' + js + ' ' + sig
exec(cmd, shell, function (err, stdout, stderr) {
if (sig) {
if (!isWindows) assert(err)
if (!isNaN(sig)) {
if (!isWindows) assert.equal(err.code, sig)
} else if (!weirdSignal(sig)) {
if (!isWindows) err.signal.should.equal(sig)
} else if (sig) {
if (!isWindows) assert(err.signal)
}
} else {
assert.ifError(err)
}
try {
var data = JSON.parse(stdout)
} catch (er) {
console.error('invalid json: %j', stdout, stderr)
throw er
}
if (weirdSignal(sig)) {
data.wanted[1] = true
data.found[1] = !!data.found[1]
}
assert.deepEqual(data.found, data.wanted)
done()
})
})
})
signals.forEach(function (sig) {
var js = require.resolve('./fixtures/parent.js')
it('exits properly: (external sig) ' + sig, function (done) {
// issues with SIGUSR1 on Node 0.10.x
if (process.version.match(/^v0\.10\./) && sig === 'SIGUSR1') return done()
var cmd = node + ' ' + js + ' ' + sig
exec(cmd, shell, function (err, stdout, stderr) {
assert.ifError(err)
try {
var data = JSON.parse(stdout)
} catch (er) {
console.error('invalid json: %j', stdout, stderr)
throw er
}
if (weirdSignal(sig)) {
data.wanted[1] = true
data.found[1] = !!data.found[1]
data.external[1] = !!data.external[1]
}
assert.deepEqual(data.found, data.wanted)
assert.deepEqual(data.external, data.wanted)
done()
})
})
})
})
signal-exit-3.0.2/test/fixtures/ 0000775 0000000 0000000 00000000000 13020705623 0016566 5 ustar 00root root 0000000 0000000 signal-exit-3.0.2/test/fixtures/awaiter.js 0000664 0000000 0000000 00000001261 13020705623 0020560 0 ustar 00root root 0000000 0000000 var expectSignal = process.argv[2]
if (!expectSignal || !isNaN(expectSignal)) {
throw new Error('signal not provided')
}
var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
// some signals don't always get recognized properly, because
// they have the same numeric code.
if (wanted[1] === true) {
signal = !!signal
}
console.log('%j', {
found: [ code, signal ],
wanted: wanted
})
})
var wanted
switch (expectSignal) {
case 'SIGIOT':
case 'SIGUNUSED':
case 'SIGPOLL':
wanted = [ null, true ]
break
default:
wanted = [ null, expectSignal ]
break
}
console.error('want', wanted)
setTimeout(function () {}, 1000)
signal-exit-3.0.2/test/fixtures/change-code-expect.json 0000664 0000000 0000000 00000036221 13020705623 0023110 0 ustar 00root root 0000000 0000000 {
"explicit 0 nochange sigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"explicit 0 nochange nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"explicit 0 change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit 0 change nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit 0 code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"explicit 0 code nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"explicit 0 twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit 0 twice nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit 0 twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"explicit 0 twicecode nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"explicit 2 nochange sigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 2,
"actualSignal": null,
"stderr": [
"first code=2",
"second code=2"
]
},
"explicit 2 nochange nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 2,
"actualSignal": null,
"stderr": [
"first code=2",
"second code=2"
]
},
"explicit 2 change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"explicit 2 change nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"explicit 2 code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"second code=2"
]
},
"explicit 2 code nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"second code=2"
]
},
"explicit 2 twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"explicit 2 twice nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"explicit 2 twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"set code from 5 to 6"
]
},
"explicit 2 twicecode nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"set code from 5 to 6"
]
},
"explicit null nochange sigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"explicit null nochange nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"explicit null change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit null change nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit null code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"explicit null code nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"explicit null twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit null twice nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"explicit null twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"explicit null twicecode nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"code 0 nochange sigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"code 0 nochange nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"code 0 change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code 0 change nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code 0 code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"code 0 code nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"code 0 twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code 0 twice nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code 0 twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"code 0 twicecode nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"code 2 nochange sigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 2,
"actualSignal": null,
"stderr": [
"first code=2",
"second code=2"
]
},
"code 2 nochange nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 2,
"actualSignal": null,
"stderr": [
"first code=2",
"second code=2"
]
},
"code 2 change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"code 2 change nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"code 2 code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"second code=2"
]
},
"code 2 code nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"second code=2"
]
},
"code 2 twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"code 2 twice nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5"
]
},
"code 2 twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"set code from 5 to 6"
]
},
"code 2 twicecode nosigexit": {
"code": 2,
"signal": null,
"exitCode": 2,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=2",
"set code from 2 to 5",
"set code from 5 to 6"
]
},
"code null nochange sigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"code null nochange nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"code null change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code null change nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code null code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"code null code nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"code null twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code null twice nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"code null twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"code null twicecode nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"normal 0 nochange sigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"normal 0 nochange nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 0,
"actualSignal": null,
"stderr": [
"first code=0",
"second code=0"
]
},
"normal 0 change sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"normal 0 change nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"normal 0 code sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"normal 0 code nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"second code=0"
]
},
"normal 0 twice sigexit": {
"code": 5,
"signal": null,
"exitCode": 5,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"normal 0 twice nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 5,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5"
]
},
"normal 0 twicecode sigexit": {
"code": 6,
"signal": null,
"exitCode": 6,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
},
"normal 0 twicecode nosigexit": {
"code": 0,
"signal": null,
"exitCode": 0,
"actualCode": 6,
"actualSignal": null,
"stderr": [
"first code=0",
"set code from 0 to 5",
"set code from 5 to 6"
]
}
}
signal-exit-3.0.2/test/fixtures/change-code.js 0000664 0000000 0000000 00000005037 13020705623 0021266 0 ustar 00root root 0000000 0000000 var join = require('path').join
if (process.argv.length === 2) {
var types = [ 'explicit', 'code', 'normal' ]
var codes = [ 0, 2, 'null' ]
var changes = [ 'nochange', 'change', 'code', 'twice', 'twicecode' ]
var handlers = [ 'sigexit', 'nosigexit' ]
var opts = []
types.forEach(function (type) {
var testCodes = type === 'normal' ? [ 0 ] : codes
testCodes.forEach(function (code) {
changes.forEach(function (change) {
handlers.forEach(function (handler) {
opts.push([type, code, change, handler].join(' '))
})
})
})
})
var results = {}
var exec = require('child_process').exec
run(opts.shift())
} else {
var type = process.argv[2]
var code = +process.argv[3]
var change = process.argv[4]
var sigexit = process.argv[5] !== 'nosigexit'
if (sigexit) {
var onSignalExit = require('../../')
onSignalExit(listener)
} else {
process.on('exit', listener)
}
process.on('exit', function (code) {
console.error('first code=%j', code)
})
if (change !== 'nochange') {
process.once('exit', function (code) {
console.error('set code from %j to %j', code, 5)
if (change === 'code' || change === 'twicecode') {
process.exitCode = 5
} else {
process.exit(5)
}
})
if (change === 'twicecode' || change === 'twice') {
process.once('exit', function (code) {
code = process.exitCode || code
console.error('set code from %j to %j', code, code + 1)
process.exit(code + 1)
})
}
}
process.on('exit', function (code) {
console.error('second code=%j', code)
})
if (type === 'explicit') {
if (code || code === 0) {
process.exit(code)
} else {
process.exit()
}
} else if (type === 'code') {
process.exitCode = +code || 0
}
}
function listener (code, signal) {
signal = signal || null
console.log('%j', { code: code, signal: signal, exitCode: process.exitCode || 0 })
}
function run (opt) {
console.error(opt)
var shell = process.platform === 'win32' ? null : { shell: '/bin/bash' }
exec(join(process.execPath, ' ', __filename, ' ' + opt), shell, function (err, stdout, stderr) {
var res = JSON.parse(stdout)
if (err) {
res.actualCode = err.code
res.actualSignal = err.signal
} else {
res.actualCode = 0
res.actualSignal = null
}
res.stderr = stderr.trim().split('\n')
results[opt] = res
if (opts.length) {
run(opts.shift())
} else {
console.log(JSON.stringify(results, null, 2))
}
})
}
signal-exit-3.0.2/test/fixtures/end-of-execution.js 0000664 0000000 0000000 00000000223 13020705623 0022272 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
console.log('reached end of execution, ' + code + ', ' + signal)
})
signal-exit-3.0.2/test/fixtures/exit-last.js 0000664 0000000 0000000 00000000554 13020705623 0021042 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
var counter = 0
onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
signal-exit-3.0.2/test/fixtures/exit.js 0000664 0000000 0000000 00000000247 13020705623 0020100 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
console.log('exited with process.exit(), ' + code + ', ' + signal)
})
process.exit(32)
signal-exit-3.0.2/test/fixtures/exiter.js 0000664 0000000 0000000 00000001572 13020705623 0020431 0 ustar 00root root 0000000 0000000 var exit = process.argv[2] || 0
var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
// some signals don't always get recognized properly, because
// they have the same numeric code.
if (wanted[1] === true) {
signal = !!signal
}
console.log('%j', {
found: [ code, signal ],
wanted: wanted
})
})
var wanted
if (isNaN(exit)) {
switch (exit) {
case 'SIGIOT':
case 'SIGUNUSED':
case 'SIGPOLL':
wanted = [ null, true ]
break
default:
wanted = [ null, exit ]
break
}
try {
process.kill(process.pid, exit)
setTimeout(function () {}, 1000)
} catch (er) {
wanted = [ 0, null ]
}
} else {
exit = +exit
wanted = [ exit, null ]
// If it's explicitly requested 0, then explicitly call it.
// "no arg" = "exit naturally"
if (exit || process.argv[2]) {
process.exit(exit)
}
}
signal-exit-3.0.2/test/fixtures/load-unload.js 0000664 0000000 0000000 00000000344 13020705623 0021324 0 ustar 00root root 0000000 0000000 // just be silly with calling these functions a bunch
// mostly just to get coverage of the guard branches
var onSignalExit = require('../../')
onSignalExit.load()
onSignalExit.load()
onSignalExit.unload()
onSignalExit.unload()
signal-exit-3.0.2/test/fixtures/multiple-load.js 0000664 0000000 0000000 00000002564 13020705623 0021703 0 ustar 00root root 0000000 0000000 // simulate cases where the module could be loaded from multiple places
var onSignalExit = require('../../')
var counter = 0
onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
delete require('module')._cache[require.resolve('../../')]
onSignalExit = require('../../')
onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
// Lastly, some that should NOT be shown
delete require('module')._cache[require.resolve('../../')]
onSignalExit = require('../../')
var unwrap = onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
unwrap()
unwrap = onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
unwrap()
process.kill(process.pid, 'SIGHUP')
setTimeout(function () {}, 1000)
signal-exit-3.0.2/test/fixtures/parent.js 0000664 0000000 0000000 00000002026 13020705623 0020415 0 ustar 00root root 0000000 0000000 var signal = process.argv[2]
var gens = +process.argv[3] || 0
if (!signal || !isNaN(signal)) {
throw new Error('signal not provided')
}
var spawn = require('child_process').spawn
var file = require.resolve('./awaiter.js')
console.error(process.pid, signal, gens)
if (gens > 0) {
file = __filename
}
var child = spawn(process.execPath, [file, signal, gens - 1], {
stdio: [ 0, 'pipe', 'pipe' ]
})
if (!gens) {
child.stderr.on('data', function () {
child.kill(signal)
})
}
var result = ''
child.stdout.on('data', function (c) {
result += c
})
child.on('close', function (code, sig) {
try {
result = JSON.parse(result)
} catch (er) {
console.log('%j', {
error: 'failed to parse json\n' + er.message,
result: result,
pid: process.pid,
child: child.pid,
gens: gens,
expect: [ null, signal ],
actual: [ code, sig ]
})
return
}
if (result.wanted[1] === true) {
sig = !!sig
}
result.external = result.external || [ code, sig ]
console.log('%j', result)
})
signal-exit-3.0.2/test/fixtures/sigint.js 0000664 0000000 0000000 00000000526 13020705623 0020424 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
console.log('exited with sigint, ' + code + ', ' + signal)
})
// For some reason, signals appear to not always be fast enough
// to come in before the process exits. Just a few ticks needed.
setTimeout(function () {}, 1000)
process.kill(process.pid, 'SIGINT')
signal-exit-3.0.2/test/fixtures/sigkill.js 0000664 0000000 0000000 00000001051 13020705623 0020557 0 ustar 00root root 0000000 0000000 // SIGKILL can't be caught, and in fact, even trying to add the
// listener will throw an error.
// We handle that nicely.
//
// This is just here to get another few more lines of test
// coverage. That's also why it lies about being on a linux
// platform so that we pull in those other event types.
Object.defineProperty(process, 'platform', {
value: 'linux',
writable: false,
enumerable: true,
configurable: true
})
var signals = require('../../signals.js')
signals.push('SIGKILL')
var onSignalExit = require('../../')
onSignalExit.load()
signal-exit-3.0.2/test/fixtures/signal-default.js 0000664 0000000 0000000 00000004143 13020705623 0022025 0 ustar 00root root 0000000 0000000 // This fixture is not used in any tests. It is here merely as a way to
// do research into the various signal behaviors on Linux and Darwin.
// Run with no args to cycle through every signal type. Run with a signal
// arg to learn about how that signal behaves.
if (process.argv[2]) {
child(process.argv[2])
} else {
var signals = [
'SIGABRT',
'SIGALRM',
'SIGBUS',
'SIGCHLD',
'SIGCLD',
'SIGCONT',
'SIGEMT',
'SIGFPE',
'SIGHUP',
'SIGILL',
'SIGINFO',
'SIGINT',
'SIGIO',
'SIGIOT',
'SIGKILL',
'SIGLOST',
'SIGPIPE',
'SIGPOLL',
// 'SIGPROF', see #21
'SIGPWR',
'SIGQUIT',
'SIGSEGV',
'SIGSTKFLT',
'SIGSTOP',
'SIGSYS',
'SIGTERM',
'SIGTRAP',
'SIGTSTP',
'SIGTTIN',
'SIGTTOU',
'SIGUNUSED',
'SIGURG',
'SIGUSR1',
'SIGUSR2',
'SIGVTALRM',
'SIGWINCH',
'SIGXCPU',
'SIGXFSZ'
]
var spawn = require('child_process').spawn
;(function test (signal) {
if (!signal) {
return
}
var child = spawn(process.execPath, [__filename, signal], { stdio: 'inherit' })
var timer = setTimeout(function () {
console.log('requires SIGCONT')
process.kill(child.pid, 'SIGCONT')
}, 750)
child.on('close', function (code, signal) {
console.log('code=%j signal=%j\n', code, signal)
clearTimeout(timer)
test(signals.pop())
})
})(signals.pop())
}
function child (signal) {
console.log('signal=%s', signal)
// set a timeout so we know whether or not the process terminated.
setTimeout(function () {
console.log('not terminated')
}, 200)
process.on('exit', function (code) {
console.log('emit exit code=%j', code)
})
try {
process.on(signal, function fn () {
console.log('signal is catchable', signal)
process.removeListener(signal, fn)
setTimeout(function () {
console.error('signal again')
process.kill(process.pid, signal)
})
})
} catch (er) {
console.log('not listenable')
}
try {
process.kill(process.pid, signal)
} catch (er) {
console.log('not issuable')
}
}
signal-exit-3.0.2/test/fixtures/signal-last.js 0000664 0000000 0000000 00000000662 13020705623 0021346 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
var counter = 0
onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
process.kill(process.pid, 'SIGHUP')
setTimeout(function () {}, 1000)
signal-exit-3.0.2/test/fixtures/signal-listener.js 0000664 0000000 0000000 00000000766 13020705623 0022235 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
setTimeout(function () {})
var calledListener = 0
onSignalExit(function (code, signal) {
console.log('exited calledListener=%j, code=%j, signal=%j',
calledListener, code, signal)
})
process.on('SIGHUP', listener)
process.kill(process.pid, 'SIGHUP')
function listener () {
calledListener++
if (calledListener > 3) {
process.removeListener('SIGHUP', listener)
}
setTimeout(function () {
process.kill(process.pid, 'SIGHUP')
})
}
signal-exit-3.0.2/test/fixtures/sigpipe.js 0000664 0000000 0000000 00000000333 13020705623 0020563 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../..')
onSignalExit(function (code, signal) {
console.error('onSignalExit(%j,%j)', code, signal)
})
setTimeout(function () {
console.log('hello')
})
process.kill(process.pid, 'SIGPIPE')
signal-exit-3.0.2/test/fixtures/sigterm.js 0000664 0000000 0000000 00000000326 13020705623 0020577 0 ustar 00root root 0000000 0000000 var onSignalExit = require('../../')
onSignalExit(function (code, signal) {
console.log('exited with sigterm, ' + code + ', ' + signal)
})
setTimeout(function () {}, 1000)
process.kill(process.pid, 'SIGTERM')
signal-exit-3.0.2/test/fixtures/unwrap.js 0000664 0000000 0000000 00000002052 13020705623 0020437 0 ustar 00root root 0000000 0000000 // simulate cases where the module could be loaded from multiple places
// Need to lie about this a little bit, since nyc uses this module
// for its coverage wrap-up handling
if (process.env.NYC_CWD) {
var emitter = process.__signal_exit_emitter__
var listeners = emitter.listeners('afterexit')
process.removeAllListeners('SIGHUP')
delete process.__signal_exit_emitter__
delete require('module')._cache[require.resolve('../../')]
}
var onSignalExit = require('../../')
var counter = 0
var unwrap = onSignalExit(function (code, signal) {
counter++
console.log('last counter=%j, code=%j, signal=%j',
counter, code, signal)
}, {alwaysLast: true})
unwrap()
unwrap = onSignalExit(function (code, signal) {
counter++
console.log('first counter=%j, code=%j, signal=%j',
counter, code, signal)
})
unwrap()
if (global.__coverage__ && listeners && listeners.length) {
listeners.forEach(function (fn) {
onSignalExit(fn, { alwaysLast: true })
})
}
process.kill(process.pid, 'SIGHUP')
setTimeout(function () {}, 1000)
signal-exit-3.0.2/test/many-handlers.js 0000664 0000000 0000000 00000001352 13020705623 0020016 0 ustar 00root root 0000000 0000000 var onexit = require('../')
var spawn = require('child_process').spawn
var t = require('tap')
var node = process.execPath
var f = __filename
if (process.argv[2] === 'child') {
for (var i = 0; i < 15; i++) {
onexit(function () {
console.log('ok')
})
}
} else {
t.test('parent', function (t) {
var child = spawn(node, [f, 'child'])
var err = ''
var out = ''
var expectOut = new Array(16).join('ok\n')
child.stderr.on('data', function (c) {
err += c
})
child.stdout.on('data', function (c) {
out += c
})
child.on('close', function (code, signal) {
t.equal(code, 0)
t.equal(signal, null)
t.equal(err, '')
t.equal(out, expectOut)
t.end()
})
})
}
signal-exit-3.0.2/test/multi-exit.js 0000664 0000000 0000000 00000003631 13020705623 0017357 0 ustar 00root root 0000000 0000000 var exec = require('child_process').exec
var t = require('tap')
var isWindows = process.platform === 'win32'
var shell = isWindows ? null : { shell: '/bin/bash' }
var node = isWindows ? '"' + process.execPath + '"' : process.execPath
var fixture = require.resolve('./fixtures/change-code.js')
var expect = require('./fixtures/change-code-expect.json')
// process.exitCode has problems prior to:
// https://github.com/joyent/node/commit/c0d81f90996667a658aa4403123e02161262506a
function isZero10 () {
return /^v0\.10\..+$/.test(process.version)
}
// process.exit(code), process.exitCode = code, normal exit
var types = [ 'explicit', 'normal' ]
if (!isZero10()) types.push('code')
// initial code that is set. Note, for 'normal' exit, there's no
// point doing these, because we just exit without modifying code
var codes = [ 0, 2, 'null' ]
// do not change, change to 5 with exit(), change to 5 with exitCode,
// change to 5 and then to 2 with exit(), change twice with exitcode
var changes = [ 'nochange', 'change', 'twice' ]
if (!isZero10()) changes.push('code', 'twicecode')
// use signal-exit, use process.on('exit')
var handlers = [ 'sigexit', 'nosigexit' ]
var opts = []
types.forEach(function (type) {
var testCodes = type === 'normal' ? [0] : codes
testCodes.forEach(function (code) {
changes.forEach(function (change) {
handlers.forEach(function (handler) {
opts.push([type, code, change, handler].join(' '))
})
})
})
})
opts.forEach(function (opt) {
t.test(opt, function (t) {
var cmd = node + ' ' + fixture + ' ' + opt
exec(cmd, shell, function (err, stdout, stderr) {
var res = JSON.parse(stdout)
if (err) {
res.actualCode = err.code
res.actualSignal = err.signal
} else {
res.actualCode = 0
res.actualSignal = null
}
res.stderr = stderr.trim().split('\n')
t.same(res, expect[opt])
t.end()
})
})
})
signal-exit-3.0.2/test/signal-exit-test.js 0000664 0000000 0000000 00000007611 13020705623 0020461 0 ustar 00root root 0000000 0000000 /* global describe, it */
var exec = require('child_process').exec
var expect = require('chai').expect
var assert = require('assert')
var isWindows = process.platform === 'win32'
var shell = isWindows ? null : { shell: '/bin/bash' }
var node = isWindows ? '"' + process.execPath + '"' : process.execPath
require('chai').should()
require('tap').mochaGlobals()
describe('signal-exit', function () {
it('receives an exit event when a process exits normally', function (done) {
exec(node + ' ./test/fixtures/end-of-execution.js', shell, function (err, stdout, stderr) {
expect(err).to.equal(null)
stdout.should.match(/reached end of execution, 0, null/)
done()
})
})
it('receives an exit event when process.exit() is called', function (done) {
exec(node + ' ./test/fixtures/exit.js', shell, function (err, stdout, stderr) {
if (!isWindows) err.code.should.equal(32)
stdout.should.match(/exited with process\.exit\(\), 32, null/)
done()
})
})
it('ensures that if alwaysLast=true, the handler is run last (signal)', function (done) {
exec(node + ' ./test/fixtures/signal-last.js', shell, function (err, stdout, stderr) {
assert(err)
stdout.should.match(/first counter=1/)
stdout.should.match(/last counter=2/)
done()
})
})
it('ensures that if alwaysLast=true, the handler is run last (normal exit)', function (done) {
exec(node + ' ./test/fixtures/exit-last.js', shell, function (err, stdout, stderr) {
assert.ifError(err)
stdout.should.match(/first counter=1/)
stdout.should.match(/last counter=2/)
done()
})
})
it('works when loaded multiple times', function (done) {
exec(node + ' ./test/fixtures/multiple-load.js', shell, function (err, stdout, stderr) {
assert(err)
stdout.should.match(/first counter=1/)
stdout.should.match(/first counter=2/)
stdout.should.match(/last counter=3/)
stdout.should.match(/last counter=4/)
done()
})
})
it('removes handlers when fully unwrapped', function (done) {
exec(node + ' ./test/fixtures/unwrap.js', shell, function (err, stdout, stderr) {
assert(err)
if (!isWindows) err.signal.should.equal('SIGHUP')
if (!isWindows) expect(err.code).to.equal(null)
done()
})
})
it('does not load() or unload() more than once', function (done) {
exec(node + ' ./test/fixtures/load-unload.js', shell, function (err, stdout, stderr) {
assert.ifError(err)
done()
})
})
if (!isWindows) {
it('receives an exit event when a process is terminated with sigint', function (done) {
exec(node + ' ./test/fixtures/sigint.js', shell, function (err, stdout, stderr) {
assert(err)
stdout.should.match(/exited with sigint, null, SIGINT/)
done()
})
})
it('receives an exit event when a process is terminated with sigterm', function (done) {
exec(node + ' ./test/fixtures/sigterm.js', shell, function (err, stdout, stderr) {
assert(err)
stdout.should.match(/exited with sigterm, null, SIGTERM/)
done()
})
})
it('does not exit on sigpipe', function (done) {
exec(node + ' ./test/fixtures/sigpipe.js', shell, function (err, stdout, stderr) {
assert.ifError(err)
stdout.should.match(/hello/)
stderr.should.match(/onSignalExit\(0,null\)/)
done()
})
})
it('handles uncatchable signals with grace and poise', function (done) {
exec(node + ' ./test/fixtures/sigkill.js', shell, function (err, stdout, stderr) {
assert.ifError(err)
done()
})
})
it('does not exit if user handles signal', function (done) {
exec(node + ' ./test/fixtures/signal-listener.js', shell, function (err, stdout, stderr) {
assert(err)
assert.equal(stdout, 'exited calledListener=4, code=null, signal="SIGHUP"\n')
done()
})
})
}
})