| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d2e6dff commit 5051d90
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1557,6 +1557,10 @@ re-raise the handled signal. | |||
| 1557 | 1557 | ||
| 1558 | 1558 | See waitpid(2). | |
| 1559 | 1559 | ||
| 1560 | + When `code` is `null` due to signal termination, you can use | ||
| 1561 | + [`util.convertProcessSignalToExitCode()`][] to convert the signal to a POSIX | ||
| 1562 | + exit code. | ||
| 1563 | + | ||
| 1560 | 1564 | ### Event: `'message'` | |
| 1561 | 1565 | ||
| 1562 | 1566 | <!-- YAML | |
@@ -1671,6 +1675,11 @@ within the child process to close the IPC channel as well. | |||
| 1671 | 1675 | The `subprocess.exitCode` property indicates the exit code of the child process. | |
| 1672 | 1676 | If the child process is still running, the field will be `null`. | |
| 1673 | 1677 | ||
| 1678 | + When the child process is terminated by a signal, `subprocess.exitCode` will be | ||
| 1679 | + `null` and [`subprocess.signalCode`][] will be set. To get the corresponding | ||
| 1680 | + POSIX exit code, use | ||
| 1681 | + [`util.convertProcessSignalToExitCode(subprocess.signalCode)`][`util.convertProcessSignalToExitCode()`]. | ||
| 1682 | + | ||
| 1674 | 1683 | ### `subprocess.kill([signal])` | |
| 1675 | 1684 | ||
| 1676 | 1685 | <!-- YAML | |
@@ -2107,6 +2116,10 @@ connection to the child. | |||
| 2107 | 2116 | The `subprocess.signalCode` property indicates the signal received by | |
| 2108 | 2117 | the child process if any, else `null`. | |
| 2109 | 2118 | ||
| 2119 | + When the child process is terminated by a signal, [`subprocess.exitCode`][] will be `null`. | ||
| 2120 | + To get the corresponding POSIX exit code, use | ||
| 2121 | + [`util.convertProcessSignalToExitCode(subprocess.signalCode)`][`util.convertProcessSignalToExitCode()`]. | ||
| 2122 | + | ||
| 2110 | 2123 | ### `subprocess.spawnargs` | |
| 2111 | 2124 | ||
| 2112 | 2125 | * Type: {Array} | |
@@ -2387,12 +2400,15 @@ or [`child_process.fork()`][]. | |||
| 2387 | 2400 | [`stdio`]: #optionsstdio | |
| 2388 | 2401 | [`subprocess.connected`]: #subprocessconnected | |
| 2389 | 2402 | [`subprocess.disconnect()`]: #subprocessdisconnect | |
| 2403 | + [`subprocess.exitCode`]: #subprocessexitcode | ||
| 2390 | 2404 | [`subprocess.kill()`]: #subprocesskillsignal | |
| 2391 | 2405 | [`subprocess.send()`]: #subprocesssendmessage-sendhandle-options-callback | |
| 2406 | + [`subprocess.signalCode`]: #subprocesssignalcode | ||
| 2392 | 2407 | [`subprocess.stderr`]: #subprocessstderr | |
| 2393 | 2408 | [`subprocess.stdin`]: #subprocessstdin | |
| 2394 | 2409 | [`subprocess.stdio`]: #subprocessstdio | |
| 2395 | 2410 | [`subprocess.stdout`]: #subprocessstdout | |
| 2411 | + [`util.convertProcessSignalToExitCode()`]: util.md#utilconvertprocesssignaltoexitcodesignalcode | ||
| 2396 | 2412 | [`util.promisify()`]: util.md#utilpromisifyoriginal | |
| 2397 | 2413 | [synchronous counterparts]: #synchronous-process-creation | |
| 2398 | 2414 | [v8.serdes]: v8.md#serialization-api | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -89,6 +89,38 @@ callbackFunction((err, ret) => { | |||
| 89 | 89 | }); | |
| 90 | 90 | ``` | |
| 91 | 91 | ||
| 92 | + ## `util.convertProcessSignalToExitCode(signalCode)` | ||
| 93 | + | ||
| 94 | + <!-- YAML | ||
| 95 | + added: REPLACEME | ||
| 96 | + --> | ||
| 97 | + | ||
| 98 | + * `signalCode` {string} A signal name (e.g., `'SIGTERM'`, `'SIGKILL'`). | ||
| 99 | + * Returns: {number|null} The exit code, or `null` if the signal is invalid. | ||
| 100 | + | ||
| 101 | + The `util.convertProcessSignalToExitCode()` method converts a signal name to its | ||
| 102 | + corresponding POSIX exit code. Following the POSIX standard, the exit code | ||
| 103 | + for a process terminated by a signal is calculated as `128 + signal number`. | ||
| 104 | + | ||
| 105 | + ```mjs | ||
| 106 | + import { convertProcessSignalToExitCode } from 'node:util'; | ||
| 107 | + | ||
| 108 | + console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15) | ||
| 109 | + console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9) | ||
| 110 | + console.log(convertProcessSignalToExitCode('INVALID')); // null | ||
| 111 | + ``` | ||
| 112 | + | ||
| 113 | + ```cjs | ||
| 114 | + const { convertProcessSignalToExitCode } = require('node:util'); | ||
| 115 | + | ||
| 116 | + console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15) | ||
| 117 | + console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9) | ||
| 118 | + console.log(convertProcessSignalToExitCode('INVALID')); // null | ||
| 119 | + ``` | ||
| 120 | + | ||
| 121 | + This is particularly useful when working with processes to determine | ||
| 122 | + the exit code based on the signal that terminated the process. | ||
| 123 | + | ||
| 92 | 124 | ## `util.debuglog(section[, callback])` | |
| 93 | 125 | ||
| 94 | 126 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -16,6 +16,7 @@ const { | |||
| 16 | 16 | ObjectGetOwnPropertyDescriptor, | |
| 17 | 17 | ObjectGetOwnPropertyDescriptors, | |
| 18 | 18 | ObjectGetPrototypeOf, | |
| 19 | + ObjectKeys, | ||
| 19 | 20 | ObjectPrototypeHasOwnProperty, | |
| 20 | 21 | ObjectSetPrototypeOf, | |
| 21 | 22 | ObjectValues, | |
@@ -106,6 +107,7 @@ function isError(e) { | |||
| 106 | 107 | const codesWarned = new SafeSet(); | |
| 107 | 108 | ||
| 108 | 109 | let validateString; | |
| 110 | + let validateOneOf; | ||
| 109 | 111 | ||
| 110 | 112 | function getDeprecationWarningEmitter( | |
| 111 | 113 | code, msg, deprecated, useEmitSync, | |
@@ -393,6 +395,17 @@ function convertToValidSignal(signal) { | |||
| 393 | 395 | throw new ERR_UNKNOWN_SIGNAL(signal); | |
| 394 | 396 | } | |
| 395 | 397 | ||
| 398 | + function convertProcessSignalToExitCode(signalCode) { | ||
| 399 | + // Lazy-load to avoid a circular dependency. | ||
| 400 | + if (validateOneOf === undefined) | ||
| 401 | + ({ validateOneOf } = require('internal/validators')); | ||
| 402 | + | ||
| 403 | + validateOneOf(signalCode, 'signalCode', ObjectKeys(signals)); | ||
| 404 | + | ||
| 405 | + // POSIX standard: exit code for signal termination is 128 + signal number. | ||
| 406 | + return 128 + signals[signalCode]; | ||
| 407 | + } | ||
| 408 | + | ||
| 396 | 409 | function getConstructorOf(obj) { | |
| 397 | 410 | while (obj) { | |
| 398 | 411 | const descriptor = ObjectGetOwnPropertyDescriptor(obj, 'constructor'); | |
@@ -956,6 +969,7 @@ module.exports = { | |||
| 956 | 969 | assignFunctionName, | |
| 957 | 970 | cachedResult, | |
| 958 | 971 | constructSharedArrayBuffer, | |
| 972 | + convertProcessSignalToExitCode, | ||
| 959 | 973 | convertToValidSignal, | |
| 960 | 974 | createClassWrapper, | |
| 961 | 975 | decorateErrorStack, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -84,6 +84,7 @@ const { getOptionValue } = require('internal/options'); | |||
| 84 | 84 | const binding = internalBinding('util'); | |
| 85 | 85 | ||
| 86 | 86 | const { | |
| 87 | + convertProcessSignalToExitCode, | ||
| 87 | 88 | deprecate: internalDeprecate, | |
| 88 | 89 | getLazy, | |
| 89 | 90 | getSystemErrorMap, | |
@@ -472,6 +473,7 @@ module.exports = { | |||
| 472 | 473 | 'The `util._extend` API is deprecated. Please use Object.assign() instead.', | |
| 473 | 474 | 'DEP0060'), | |
| 474 | 475 | callbackify, | |
| 476 | + convertProcessSignalToExitCode, | ||
| 475 | 477 | debug: debuglog, | |
| 476 | 478 | debuglog, | |
| 477 | 479 | deprecate, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,61 @@ | |||
| 1 | + import { mustCall, mustNotCall, isWindows } from '../common/index.mjs'; | ||
| 2 | + import assert from 'assert'; | ||
| 3 | + import { convertProcessSignalToExitCode } from 'util'; | ||
| 4 | + import { spawn } from 'child_process'; | ||
| 5 | + import { constants } from 'os'; | ||
| 6 | + const { signals } = constants; | ||
| 7 | + | ||
| 8 | + { | ||
| 9 | + | ||
| 10 | + assert.strictEqual(convertProcessSignalToExitCode('SIGTERM'), 128 + signals.SIGTERM); | ||
| 11 | + assert.strictEqual(convertProcessSignalToExitCode('SIGKILL'), 128 + signals.SIGKILL); | ||
| 12 | + assert.strictEqual(convertProcessSignalToExitCode('SIGINT'), 128 + signals.SIGINT); | ||
| 13 | + assert.strictEqual(convertProcessSignalToExitCode('SIGHUP'), 128 + signals.SIGHUP); | ||
| 14 | + assert.strictEqual(convertProcessSignalToExitCode('SIGABRT'), 128 + signals.SIGABRT); | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + { | ||
| 18 | + [ | ||
| 19 | + 'INVALID', | ||
| 20 | + '', | ||
| 21 | + 'SIG', | ||
| 22 | + undefined, | ||
| 23 | + null, | ||
| 24 | + 123, | ||
| 25 | + true, | ||
| 26 | + false, | ||
| 27 | + {}, | ||
| 28 | + [], | ||
| 29 | + Symbol('test'), | ||
| 30 | + () => {}, | ||
| 31 | + ].forEach((value) => { | ||
| 32 | + assert.throws( | ||
| 33 | + () => convertProcessSignalToExitCode(value), | ||
| 34 | + { | ||
| 35 | + code: 'ERR_INVALID_ARG_VALUE', | ||
| 36 | + name: 'TypeError', | ||
| 37 | + } | ||
| 38 | + ); | ||
| 39 | + }); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + { | ||
| 43 | + const cat = spawn(isWindows ? 'cmd' : 'cat'); | ||
| 44 | + cat.stdout.on('end', mustCall()); | ||
| 45 | + cat.stderr.on('data', mustNotCall()); | ||
| 46 | + cat.stderr.on('end', mustCall()); | ||
| 47 | + | ||
| 48 | + cat.on('exit', mustCall((code, signal) => { | ||
| 49 | + assert.strictEqual(code, null); | ||
| 50 | + assert.strictEqual(signal, 'SIGTERM'); | ||
| 51 | + assert.strictEqual(cat.signalCode, 'SIGTERM'); | ||
| 52 | + | ||
| 53 | + const exitCode = convertProcessSignalToExitCode(signal); | ||
| 54 | + assert.strictEqual(exitCode, 143); | ||
| 55 | + })); | ||
| 56 | + | ||
| 57 | + assert.strictEqual(cat.signalCode, null); | ||
| 58 | + assert.strictEqual(cat.killed, false); | ||
| 59 | + cat[Symbol.dispose](); | ||
| 60 | + assert.strictEqual(cat.killed, true); | ||
| 61 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments