| 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 | |
|---|---|---|---|
@@ -45,15 +45,24 @@ let debug = require('internal/util/debuglog').debuglog( | |||
| 45 | 45 | ); | |
| 46 | 46 | const { Buffer } = require('buffer'); | |
| 47 | 47 | const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap'); | |
| 48 | + | ||
| 49 | + const { | ||
| 50 | + AbortError, | ||
| 51 | + codes: errorCodes, | ||
| 52 | + } = require('internal/errors'); | ||
| 48 | 53 | const { | |
| 49 | 54 | ERR_INVALID_ARG_VALUE, | |
| 50 | 55 | ERR_CHILD_PROCESS_IPC_REQUIRED, | |
| 51 | 56 | ERR_CHILD_PROCESS_STDIO_MAXBUFFER, | |
| 52 | 57 | ERR_INVALID_ARG_TYPE, | |
| 53 | - ERR_OUT_OF_RANGE | ||
| 54 | - } = require('internal/errors').codes; | ||
| 58 | + ERR_OUT_OF_RANGE, | ||
| 59 | + } = errorCodes; | ||
| 55 | 60 | const { clearTimeout, setTimeout } = require('timers'); | |
| 56 | - const { validateString, isInt32 } = require('internal/validators'); | ||
| 61 | + const { | ||
| 62 | + validateString, | ||
| 63 | + isInt32, | ||
| 64 | + validateAbortSignal, | ||
| 65 | + } = require('internal/validators'); | ||
| 57 | 66 | const child_process = require('internal/child_process'); | |
| 58 | 67 | const { | |
| 59 | 68 | getValidStdio, | |
@@ -232,6 +241,9 @@ function execFile(file /* , args, options, callback */) { | |||
| 232 | 241 | // Validate maxBuffer, if present. | |
| 233 | 242 | validateMaxBuffer(options.maxBuffer); | |
| 234 | 243 | ||
| 244 | + // Validate signal, if present | ||
| 245 | + validateAbortSignal(options.signal, 'options.signal'); | ||
| 246 | + | ||
| 235 | 247 | options.killSignal = sanitizeKillSignal(options.killSignal); | |
| 236 | 248 | ||
| 237 | 249 | const child = spawn(file, args, { | |
@@ -349,6 +361,20 @@ function execFile(file /* , args, options, callback */) { | |||
| 349 | 361 | timeoutId = null; | |
| 350 | 362 | }, options.timeout); | |
| 351 | 363 | } | |
| 364 | + if (options.signal) { | ||
| 365 | + if (options.signal.aborted) { | ||
| 366 | + process.nextTick(() => kill()); | ||
| 367 | + } else { | ||
| 368 | + options.signal.addEventListener('abort', () => { | ||
| 369 | + if (!ex) { | ||
| 370 | + ex = new AbortError(); | ||
| 371 | + } | ||
| 372 | + kill(); | ||
| 373 | + }); | ||
| 374 | + const remove = () => options.signal.removeEventListener('abort', kill); | ||
| 375 | + child.once('close', remove); | ||
| 376 | + } | ||
| 377 | + } | ||
| 352 | 378 | ||
| 353 | 379 | if (child.stdout) { | |
| 354 | 380 | if (encoding) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + // Flags: --experimental-abortcontroller | ||
| 1 | 2 | 'use strict'; | |
| 2 | 3 | ||
| 3 | 4 | const common = require('../common'); | |
@@ -7,6 +8,7 @@ const { getSystemErrorName } = require('util'); | |||
| 7 | 8 | const fixtures = require('../common/fixtures'); | |
| 8 | 9 | ||
| 9 | 10 | const fixture = fixtures.path('exit.js'); | |
| 11 | + const echoFixture = fixtures.path('echo.js'); | ||
| 10 | 12 | const execOpts = { encoding: 'utf8', shell: true }; | |
| 11 | 13 | ||
| 12 | 14 | { | |
@@ -45,3 +47,16 @@ const execOpts = { encoding: 'utf8', shell: true }; | |||
| 45 | 47 | // Verify the shell option works properly | |
| 46 | 48 | execFile(process.execPath, [fixture, 0], execOpts, common.mustSucceed()); | |
| 47 | 49 | } | |
| 50 | + | ||
| 51 | + { | ||
| 52 | + // Verify that the signal option works properly | ||
| 53 | + const ac = new AbortController(); | ||
| 54 | + const { signal } = ac; | ||
| 55 | + | ||
| 56 | + const callback = common.mustCall((err) => { | ||
| 57 | + assert.strictEqual(err.code, 'ABORT_ERR'); | ||
| 58 | + assert.strictEqual(err.name, 'AbortError'); | ||
| 59 | + }); | ||
| 60 | + execFile(process.execPath, [echoFixture, 0], { signal }, callback); | ||
| 61 | + ac.abort(); | ||
| 62 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments