| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -250,6 +250,9 @@ lsExample(); | |||
| 250 | 250 | <!-- YAML | |
| 251 | 251 | added: v0.1.91 | |
| 252 | 252 | changes: | |
| 253 | + - version: REPLACEME | ||
| 254 | + pr-url: https://github.com/nodejs/node/pull/36308 | ||
| 255 | + description: AbortSignal support was added. | ||
| 253 | 256 | - version: v8.8.0 | |
| 254 | 257 | pr-url: https://github.com/nodejs/node/pull/15380 | |
| 255 | 258 | description: The `windowsHide` option is supported now. | |
@@ -277,6 +280,7 @@ changes: | |||
| 277 | 280 | `'/bin/sh'` on Unix, and `process.env.ComSpec` on Windows. A different | |
| 278 | 281 | shell can be specified as a string. See [Shell requirements][] and | |
| 279 | 282 | [Default Windows shell][]. **Default:** `false` (no shell). | |
| 283 | + * `signal` {AbortSignal} allows aborting the execFile using an AbortSignal | ||
| 280 | 284 | * `callback` {Function} Called with the output when process terminates. | |
| 281 | 285 | * `error` {Error} | |
| 282 | 286 | * `stdout` {string|Buffer} | |
@@ -330,6 +334,19 @@ getVersion(); | |||
| 330 | 334 | function. Any input containing shell metacharacters may be used to trigger | |
| 331 | 335 | arbitrary command execution.** | |
| 332 | 336 | ||
| 337 | + If the `signal` option is enabled, calling `.abort()` on the corresponding | ||
| 338 | + `AbortController` is similar to calling `.kill()` on the child process except | ||
| 339 | + the error passed to the callback will be an `AbortError`: | ||
| 340 | + | ||
| 341 | + ```js | ||
| 342 | + const controller = new AbortController(); | ||
| 343 | + const { signal } = controller; | ||
| 344 | + const child = execFile('node', ['--version'], { signal }, (error) => { | ||
| 345 | + console.log(error); // an AbortError | ||
| 346 | + }); | ||
| 347 | + signal.abort(); | ||
| 348 | + ``` | ||
| 349 | + | ||
| 333 | 350 | ### `child_process.fork(modulePath[, args][, options])` | |
| 334 | 351 | <!-- YAML | |
| 335 | 352 | added: v0.5.0 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -58,15 +58,24 @@ let debug = require('internal/util/debuglog').debuglog( | |||
| 58 | 58 | ); | |
| 59 | 59 | const { Buffer } = require('buffer'); | |
| 60 | 60 | const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap'); | |
| 61 | + | ||
| 62 | + const { | ||
| 63 | + AbortError, | ||
| 64 | + codes: errorCodes, | ||
| 65 | + } = require('internal/errors'); | ||
| 61 | 66 | const { | |
| 62 | 67 | ERR_INVALID_ARG_VALUE, | |
| 63 | 68 | ERR_CHILD_PROCESS_IPC_REQUIRED, | |
| 64 | 69 | ERR_CHILD_PROCESS_STDIO_MAXBUFFER, | |
| 65 | 70 | ERR_INVALID_ARG_TYPE, | |
| 66 | - ERR_OUT_OF_RANGE | ||
| 67 | - } = require('internal/errors').codes; | ||
| 71 | + ERR_OUT_OF_RANGE, | ||
| 72 | + } = errorCodes; | ||
| 68 | 73 | const { clearTimeout, setTimeout } = require('timers'); | |
| 69 | - const { validateString, isInt32 } = require('internal/validators'); | ||
| 74 | + const { | ||
| 75 | + validateString, | ||
| 76 | + isInt32, | ||
| 77 | + validateAbortSignal, | ||
| 78 | + } = require('internal/validators'); | ||
| 70 | 79 | const child_process = require('internal/child_process'); | |
| 71 | 80 | const { | |
| 72 | 81 | getValidStdio, | |
@@ -245,6 +254,9 @@ function execFile(file /* , args, options, callback */) { | |||
| 245 | 254 | // Validate maxBuffer, if present. | |
| 246 | 255 | validateMaxBuffer(options.maxBuffer); | |
| 247 | 256 | ||
| 257 | + // Validate signal, if present | ||
| 258 | + validateAbortSignal(options.signal, 'options.signal'); | ||
| 259 | + | ||
| 248 | 260 | options.killSignal = sanitizeKillSignal(options.killSignal); | |
| 249 | 261 | ||
| 250 | 262 | const child = spawn(file, args, { | |
@@ -362,6 +374,20 @@ function execFile(file /* , args, options, callback */) { | |||
| 362 | 374 | timeoutId = null; | |
| 363 | 375 | }, options.timeout); | |
| 364 | 376 | } | |
| 377 | + if (options.signal) { | ||
| 378 | + if (options.signal.aborted) { | ||
| 379 | + process.nextTick(() => kill()); | ||
| 380 | + } else { | ||
| 381 | + options.signal.addEventListener('abort', () => { | ||
| 382 | + if (!ex) { | ||
| 383 | + ex = new AbortError(); | ||
| 384 | + } | ||
| 385 | + kill(); | ||
| 386 | + }); | ||
| 387 | + const remove = () => options.signal.removeEventListener('abort', kill); | ||
| 388 | + child.once('close', remove); | ||
| 389 | + } | ||
| 390 | + } | ||
| 365 | 391 | ||
| 366 | 392 | if (child.stdout) { | |
| 367 | 393 | if (encoding) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -114,6 +114,7 @@ if (!common.isMainThread) { | |||
| 114 | 114 | 'Internal Binding performance', | |
| 115 | 115 | 'Internal Binding symbols', | |
| 116 | 116 | 'Internal Binding worker', | |
| 117 | + 'NativeModule internal/streams/add-abort-signal', | ||
| 117 | 118 | 'NativeModule internal/streams/duplex', | |
| 118 | 119 | 'NativeModule internal/streams/passthrough', | |
| 119 | 120 | 'NativeModule internal/streams/readable', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ const { getSystemErrorName } = require('util'); | |||
| 7 | 7 | const fixtures = require('../common/fixtures'); | |
| 8 | 8 | ||
| 9 | 9 | const fixture = fixtures.path('exit.js'); | |
| 10 | + const echoFixture = fixtures.path('echo.js'); | ||
| 10 | 11 | const execOpts = { encoding: 'utf8', shell: true }; | |
| 11 | 12 | ||
| 12 | 13 | { | |
@@ -45,3 +46,16 @@ const execOpts = { encoding: 'utf8', shell: true }; | |||
| 45 | 46 | // Verify the shell option works properly | |
| 46 | 47 | execFile(process.execPath, [fixture, 0], execOpts, common.mustSucceed()); | |
| 47 | 48 | } | |
| 49 | + | ||
| 50 | + { | ||
| 51 | + // Verify that the signal option works properly | ||
| 52 | + const ac = new AbortController(); | ||
| 53 | + const { signal } = ac; | ||
| 54 | + | ||
| 55 | + const callback = common.mustCall((err) => { | ||
| 56 | + assert.strictEqual(err.code, 'ABORT_ERR'); | ||
| 57 | + assert.strictEqual(err.name, 'AbortError'); | ||
| 58 | + }); | ||
| 59 | + execFile(process.execPath, [echoFixture, 0], { signal }, callback); | ||
| 60 | + ac.abort(); | ||
| 61 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments