mirror of
https://github.com/nodejs/node.git
synced 2025-12-27 23:41:14 +00:00
util: add convertProcessSignalToExitCode utility
Add convertProcessSignalToExitCode() to convert signal names to POSIX exit codes (128 + signal number). Exposed in public util API. Refs: https://github.com/nodejs/node/pull/60720 PR-URL: https://github.com/nodejs/node/pull/60963 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
This commit is contained in:
parent
180c717714
commit
e705603a6f
@ -1557,6 +1557,10 @@ re-raise the handled signal.
|
||||
|
||||
See waitpid(2).
|
||||
|
||||
When `code` is `null` due to signal termination, you can use
|
||||
[`util.convertProcessSignalToExitCode()`][] to convert the signal to a POSIX
|
||||
exit code.
|
||||
|
||||
### Event: `'message'`
|
||||
|
||||
<!-- YAML
|
||||
@ -1671,6 +1675,11 @@ within the child process to close the IPC channel as well.
|
||||
The `subprocess.exitCode` property indicates the exit code of the child process.
|
||||
If the child process is still running, the field will be `null`.
|
||||
|
||||
When the child process is terminated by a signal, `subprocess.exitCode` will be
|
||||
`null` and [`subprocess.signalCode`][] will be set. To get the corresponding
|
||||
POSIX exit code, use
|
||||
[`util.convertProcessSignalToExitCode(subprocess.signalCode)`][`util.convertProcessSignalToExitCode()`].
|
||||
|
||||
### `subprocess.kill([signal])`
|
||||
|
||||
<!-- YAML
|
||||
@ -2107,6 +2116,10 @@ connection to the child.
|
||||
The `subprocess.signalCode` property indicates the signal received by
|
||||
the child process if any, else `null`.
|
||||
|
||||
When the child process is terminated by a signal, [`subprocess.exitCode`][] will be `null`.
|
||||
To get the corresponding POSIX exit code, use
|
||||
[`util.convertProcessSignalToExitCode(subprocess.signalCode)`][`util.convertProcessSignalToExitCode()`].
|
||||
|
||||
### `subprocess.spawnargs`
|
||||
|
||||
* Type: {Array}
|
||||
@ -2387,12 +2400,15 @@ or [`child_process.fork()`][].
|
||||
[`stdio`]: #optionsstdio
|
||||
[`subprocess.connected`]: #subprocessconnected
|
||||
[`subprocess.disconnect()`]: #subprocessdisconnect
|
||||
[`subprocess.exitCode`]: #subprocessexitcode
|
||||
[`subprocess.kill()`]: #subprocesskillsignal
|
||||
[`subprocess.send()`]: #subprocesssendmessage-sendhandle-options-callback
|
||||
[`subprocess.signalCode`]: #subprocesssignalcode
|
||||
[`subprocess.stderr`]: #subprocessstderr
|
||||
[`subprocess.stdin`]: #subprocessstdin
|
||||
[`subprocess.stdio`]: #subprocessstdio
|
||||
[`subprocess.stdout`]: #subprocessstdout
|
||||
[`util.convertProcessSignalToExitCode()`]: util.md#utilconvertprocesssignaltoexitcodesignalcode
|
||||
[`util.promisify()`]: util.md#utilpromisifyoriginal
|
||||
[synchronous counterparts]: #synchronous-process-creation
|
||||
[v8.serdes]: v8.md#serialization-api
|
||||
|
||||
@ -89,6 +89,38 @@ callbackFunction((err, ret) => {
|
||||
});
|
||||
```
|
||||
|
||||
## `util.convertProcessSignalToExitCode(signalCode)`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
* `signalCode` {string} A signal name (e.g., `'SIGTERM'`, `'SIGKILL'`).
|
||||
* Returns: {number|null} The exit code, or `null` if the signal is invalid.
|
||||
|
||||
The `util.convertProcessSignalToExitCode()` method converts a signal name to its
|
||||
corresponding POSIX exit code. Following the POSIX standard, the exit code
|
||||
for a process terminated by a signal is calculated as `128 + signal number`.
|
||||
|
||||
```mjs
|
||||
import { convertProcessSignalToExitCode } from 'node:util';
|
||||
|
||||
console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15)
|
||||
console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9)
|
||||
console.log(convertProcessSignalToExitCode('INVALID')); // null
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { convertProcessSignalToExitCode } = require('node:util');
|
||||
|
||||
console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15)
|
||||
console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9)
|
||||
console.log(convertProcessSignalToExitCode('INVALID')); // null
|
||||
```
|
||||
|
||||
This is particularly useful when working with processes to determine
|
||||
the exit code based on the signal that terminated the process.
|
||||
|
||||
## `util.debuglog(section[, callback])`
|
||||
|
||||
<!-- YAML
|
||||
|
||||
@ -16,6 +16,7 @@ const {
|
||||
ObjectGetOwnPropertyDescriptor,
|
||||
ObjectGetOwnPropertyDescriptors,
|
||||
ObjectGetPrototypeOf,
|
||||
ObjectKeys,
|
||||
ObjectPrototypeHasOwnProperty,
|
||||
ObjectSetPrototypeOf,
|
||||
ObjectValues,
|
||||
@ -106,6 +107,7 @@ function isError(e) {
|
||||
const codesWarned = new SafeSet();
|
||||
|
||||
let validateString;
|
||||
let validateOneOf;
|
||||
|
||||
function getDeprecationWarningEmitter(
|
||||
code, msg, deprecated, useEmitSync,
|
||||
@ -393,6 +395,17 @@ function convertToValidSignal(signal) {
|
||||
throw new ERR_UNKNOWN_SIGNAL(signal);
|
||||
}
|
||||
|
||||
function convertProcessSignalToExitCode(signalCode) {
|
||||
// Lazy-load to avoid a circular dependency.
|
||||
if (validateOneOf === undefined)
|
||||
({ validateOneOf } = require('internal/validators'));
|
||||
|
||||
validateOneOf(signalCode, 'signalCode', ObjectKeys(signals));
|
||||
|
||||
// POSIX standard: exit code for signal termination is 128 + signal number.
|
||||
return 128 + signals[signalCode];
|
||||
}
|
||||
|
||||
function getConstructorOf(obj) {
|
||||
while (obj) {
|
||||
const descriptor = ObjectGetOwnPropertyDescriptor(obj, 'constructor');
|
||||
@ -956,6 +969,7 @@ module.exports = {
|
||||
assignFunctionName,
|
||||
cachedResult,
|
||||
constructSharedArrayBuffer,
|
||||
convertProcessSignalToExitCode,
|
||||
convertToValidSignal,
|
||||
createClassWrapper,
|
||||
decorateErrorStack,
|
||||
|
||||
@ -84,6 +84,7 @@ const { getOptionValue } = require('internal/options');
|
||||
const binding = internalBinding('util');
|
||||
|
||||
const {
|
||||
convertProcessSignalToExitCode,
|
||||
deprecate: internalDeprecate,
|
||||
getLazy,
|
||||
getSystemErrorMap,
|
||||
@ -472,6 +473,7 @@ module.exports = {
|
||||
'The `util._extend` API is deprecated. Please use Object.assign() instead.',
|
||||
'DEP0060'),
|
||||
callbackify,
|
||||
convertProcessSignalToExitCode,
|
||||
debug: debuglog,
|
||||
debuglog,
|
||||
deprecate,
|
||||
|
||||
61
test/parallel/test-util-convert-signal-to-exit-code.mjs
Normal file
61
test/parallel/test-util-convert-signal-to-exit-code.mjs
Normal file
@ -0,0 +1,61 @@
|
||||
import { mustCall, mustNotCall, isWindows } from '../common/index.mjs';
|
||||
import assert from 'assert';
|
||||
import { convertProcessSignalToExitCode } from 'util';
|
||||
import { spawn } from 'child_process';
|
||||
import { constants } from 'os';
|
||||
const { signals } = constants;
|
||||
|
||||
{
|
||||
|
||||
assert.strictEqual(convertProcessSignalToExitCode('SIGTERM'), 128 + signals.SIGTERM);
|
||||
assert.strictEqual(convertProcessSignalToExitCode('SIGKILL'), 128 + signals.SIGKILL);
|
||||
assert.strictEqual(convertProcessSignalToExitCode('SIGINT'), 128 + signals.SIGINT);
|
||||
assert.strictEqual(convertProcessSignalToExitCode('SIGHUP'), 128 + signals.SIGHUP);
|
||||
assert.strictEqual(convertProcessSignalToExitCode('SIGABRT'), 128 + signals.SIGABRT);
|
||||
}
|
||||
|
||||
{
|
||||
[
|
||||
'INVALID',
|
||||
'',
|
||||
'SIG',
|
||||
undefined,
|
||||
null,
|
||||
123,
|
||||
true,
|
||||
false,
|
||||
{},
|
||||
[],
|
||||
Symbol('test'),
|
||||
() => {},
|
||||
].forEach((value) => {
|
||||
assert.throws(
|
||||
() => convertProcessSignalToExitCode(value),
|
||||
{
|
||||
code: 'ERR_INVALID_ARG_VALUE',
|
||||
name: 'TypeError',
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const cat = spawn(isWindows ? 'cmd' : 'cat');
|
||||
cat.stdout.on('end', mustCall());
|
||||
cat.stderr.on('data', mustNotCall());
|
||||
cat.stderr.on('end', mustCall());
|
||||
|
||||
cat.on('exit', mustCall((code, signal) => {
|
||||
assert.strictEqual(code, null);
|
||||
assert.strictEqual(signal, 'SIGTERM');
|
||||
assert.strictEqual(cat.signalCode, 'SIGTERM');
|
||||
|
||||
const exitCode = convertProcessSignalToExitCode(signal);
|
||||
assert.strictEqual(exitCode, 143);
|
||||
}));
|
||||
|
||||
assert.strictEqual(cat.signalCode, null);
|
||||
assert.strictEqual(cat.killed, false);
|
||||
cat[Symbol.dispose]();
|
||||
assert.strictEqual(cat.killed, true);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user