| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7d67940 commit afb7270
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1412,6 +1412,28 @@ added: v16.18.0 | |||
| 1412 | 1412 | ||
| 1413 | 1413 | Emitted when a new process is created. | |
| 1414 | 1414 | ||
| 1415 | + `tracing:child_process.spawn:start` | ||
| 1416 | + | ||
| 1417 | + * `process` {ChildProcess} | ||
| 1418 | + * `options` {Object} | ||
| 1419 | + | ||
| 1420 | + Emitted when [`child_process.spawn()`][] is invoked, before the process is | ||
| 1421 | + actually spawned. | ||
| 1422 | + | ||
| 1423 | + `tracing:child_process.spawn:end` | ||
| 1424 | + | ||
| 1425 | + * `process` {ChildProcess} | ||
| 1426 | + | ||
| 1427 | + Emitted when [`child_process.spawn()`][] has completed successfully and the | ||
| 1428 | + process has been created. | ||
| 1429 | + | ||
| 1430 | + `tracing:child_process.spawn:error` | ||
| 1431 | + | ||
| 1432 | + * `process` {ChildProcess} | ||
| 1433 | + * `error` {Error} | ||
| 1434 | + | ||
| 1435 | + Emitted when [`child_process.spawn()`][] encounters an error. | ||
| 1436 | + | ||
| 1415 | 1437 | ##### Event: `'execve'` | |
| 1416 | 1438 | ||
| 1417 | 1439 | * `execPath` {string} | |
@@ -1443,6 +1465,7 @@ Emitted when a new thread is created. | |||
| 1443 | 1465 | [`channel.runStores(context, ...)`]: #channelrunstorescontext-fn-thisarg-args | |
| 1444 | 1466 | [`channel.subscribe(onMessage)`]: #channelsubscribeonmessage | |
| 1445 | 1467 | [`channel.unsubscribe(onMessage)`]: #channelunsubscribeonmessage | |
| 1468 | + [`child_process.spawn()`]: child_process.md#child_processspawncommand-args-options | ||
| 1446 | 1469 | [`diagnostics_channel.channel(name)`]: #diagnostics_channelchannelname | |
| 1447 | 1470 | [`diagnostics_channel.subscribe(name, onMessage)`]: #diagnostics_channelsubscribename-onmessage | |
| 1448 | 1471 | [`diagnostics_channel.tracingChannel()`]: #diagnostics_channeltracingchannelnameorchannels | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,7 @@ const spawn_sync = internalBinding('spawn_sync'); | |||
| 61 | 61 | const { kStateSymbol } = require('internal/dgram'); | |
| 62 | 62 | const dc = require('diagnostics_channel'); | |
| 63 | 63 | const childProcessChannel = dc.channel('child_process'); | |
| 64 | + const childProcessSpawn = dc.tracingChannel('child_process.spawn'); | ||
| 64 | 65 | ||
| 65 | 66 | const { | |
| 66 | 67 | UV_EACCES, | |
@@ -392,6 +393,10 @@ ChildProcess.prototype.spawn = function spawn(options) { | |||
| 392 | 393 | this.spawnargs = options.args; | |
| 393 | 394 | } | |
| 394 | 395 | ||
| 396 | + if (childProcessSpawn.hasSubscribers) { | ||
| 397 | + childProcessSpawn.start.publish({ process: this, options }); | ||
| 398 | + } | ||
| 399 | + | ||
| 395 | 400 | const err = this._handle.spawn(options); | |
| 396 | 401 | ||
| 397 | 402 | // Run-time errors should emit an error, not throw an exception. | |
@@ -400,6 +405,13 @@ ChildProcess.prototype.spawn = function spawn(options) { | |||
| 400 | 405 | err === UV_EMFILE || | |
| 401 | 406 | err === UV_ENFILE || | |
| 402 | 407 | err === UV_ENOENT) { | |
| 408 | + if (childProcessSpawn.hasSubscribers) { | ||
| 409 | + childProcessSpawn.error.publish({ | ||
| 410 | + process: this, | ||
| 411 | + error: new ErrnoException(err, 'spawn'), | ||
| 412 | + }); | ||
| 413 | + } | ||
| 414 | + | ||
| 403 | 415 | process.nextTick(onErrorNT, this, err); | |
| 404 | 416 | ||
| 405 | 417 | // There is no point in continuing when we've hit EMFILE or ENFILE | |
@@ -417,8 +429,20 @@ ChildProcess.prototype.spawn = function spawn(options) { | |||
| 417 | 429 | ||
| 418 | 430 | this._handle.close(); | |
| 419 | 431 | this._handle = null; | |
| 432 | + | ||
| 433 | + if (childProcessSpawn.hasSubscribers) { | ||
| 434 | + childProcessSpawn.error.publish({ | ||
| 435 | + process: this, | ||
| 436 | + error: new ErrnoException(err, 'spawn'), | ||
| 437 | + }); | ||
| 438 | + } | ||
| 439 | + | ||
| 420 | 440 | throw new ErrnoException(err, 'spawn'); | |
| 421 | 441 | } else { | |
| 442 | + if (childProcessSpawn.hasSubscribers) { | ||
| 443 | + childProcessSpawn.end.publish({ process: this }); | ||
| 444 | + } | ||
| 445 | + | ||
| 422 | 446 | process.nextTick(onSpawnNT, this); | |
| 423 | 447 | } | |
| 424 | 448 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,94 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common'); | ||
| 3 | + const assert = require('assert'); | ||
| 4 | + const { spawn, ChildProcess } = require('child_process'); | ||
| 5 | + const dc = require('diagnostics_channel'); | ||
| 6 | + const path = require('path'); | ||
| 7 | + const fs = require('fs'); | ||
| 8 | + const tmpdir = require('../common/tmpdir'); | ||
| 9 | + | ||
| 10 | + const isChildProcess = (process) => process instanceof ChildProcess; | ||
| 11 | + | ||
| 12 | + function testDiagnosticChannel(subscribers, test, after) { | ||
| 13 | + dc.tracingChannel('child_process.spawn').subscribe(subscribers); | ||
| 14 | + | ||
| 15 | + test(common.mustCall(() => { | ||
| 16 | + dc.tracingChannel('child_process.spawn').unsubscribe(subscribers); | ||
| 17 | + after?.(); | ||
| 18 | + })); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + const testSuccessfulSpawn = common.mustCall(() => { | ||
| 22 | + let cb; | ||
| 23 | + | ||
| 24 | + testDiagnosticChannel( | ||
| 25 | + { | ||
| 26 | + start: common.mustCall(({ process: childProcess, options }) => { | ||
| 27 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 28 | + assert.strictEqual(options.file, process.execPath); | ||
| 29 | + }), | ||
| 30 | + end: common.mustCall(({ process: childProcess }) => { | ||
| 31 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 32 | + }), | ||
| 33 | + error: common.mustNotCall(), | ||
| 34 | + }, | ||
| 35 | + common.mustCall((callback) => { | ||
| 36 | + cb = callback; | ||
| 37 | + const child = spawn(process.execPath, ['-e', 'process.exit(0)']); | ||
| 38 | + child.on('close', () => { | ||
| 39 | + cb(); | ||
| 40 | + }); | ||
| 41 | + }), | ||
| 42 | + testFailingSpawnENOENT | ||
| 43 | + ); | ||
| 44 | + }); | ||
| 45 | + | ||
| 46 | + const testFailingSpawnENOENT = common.mustCall(() => { | ||
| 47 | + testDiagnosticChannel( | ||
| 48 | + { | ||
| 49 | + start: common.mustCall(({ process: childProcess, options }) => { | ||
| 50 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 51 | + assert.strictEqual(options.file, 'does-not-exist'); | ||
| 52 | + }), | ||
| 53 | + end: common.mustNotCall(), | ||
| 54 | + error: common.mustCall(({ process: childProcess, error }) => { | ||
| 55 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 56 | + assert.strictEqual(error.code, 'ENOENT'); | ||
| 57 | + }), | ||
| 58 | + }, | ||
| 59 | + common.mustCall((callback) => { | ||
| 60 | + const child = spawn('does-not-exist'); | ||
| 61 | + child.on('error', () => {}); | ||
| 62 | + callback(); | ||
| 63 | + }), | ||
| 64 | + common.isWindows ? undefined : testFailingSpawnEACCES, | ||
| 65 | + ); | ||
| 66 | + }); | ||
| 67 | + | ||
| 68 | + const testFailingSpawnEACCES = !common.isWindows ? common.mustCall(() => { | ||
| 69 | + tmpdir.refresh(); | ||
| 70 | + const noExecFile = path.join(tmpdir.path, 'no-exec'); | ||
| 71 | + fs.writeFileSync(noExecFile, ''); | ||
| 72 | + fs.chmodSync(noExecFile, 0o644); | ||
| 73 | + | ||
| 74 | + testDiagnosticChannel( | ||
| 75 | + { | ||
| 76 | + start: common.mustCall(({ process: childProcess, options }) => { | ||
| 77 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 78 | + assert.strictEqual(options.file, noExecFile); | ||
| 79 | + }), | ||
| 80 | + end: common.mustNotCall(), | ||
| 81 | + error: common.mustCall(({ process: childProcess, error }) => { | ||
| 82 | + assert.strictEqual(isChildProcess(childProcess), true); | ||
| 83 | + assert.strictEqual(error.code, 'EACCES'); | ||
| 84 | + }), | ||
| 85 | + }, | ||
| 86 | + common.mustCall((callback) => { | ||
| 87 | + const child = spawn(noExecFile); | ||
| 88 | + child.on('error', () => {}); | ||
| 89 | + callback(); | ||
| 90 | + }), | ||
| 91 | + ); | ||
| 92 | + }) : undefined; | ||
| 93 | + | ||
| 94 | + testSuccessfulSpawn(); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments