| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9dc3f93 commit 448c4c6
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,13 +28,11 @@ const { createPromise, | |||
| 28 | 28 | const debug = util.debuglog('child_process'); | |
| 29 | 29 | ||
| 30 | 30 | const uv = process.binding('uv'); | |
| 31 | - const spawn_sync = process.binding('spawn_sync'); | ||
| 32 | 31 | const Buffer = require('buffer').Buffer; | |
| 33 | 32 | const Pipe = process.binding('pipe_wrap').Pipe; | |
| 34 | 33 | const { isUint8Array } = process.binding('util'); | |
| 35 | 34 | const child_process = require('internal/child_process'); | |
| 36 | 35 | ||
| 37 | - const errnoException = util._errnoException; | ||
| 38 | 36 | const _validateStdio = child_process._validateStdio; | |
| 39 | 37 | const setupChannel = child_process.setupChannel; | |
| 40 | 38 | const ChildProcess = exports.ChildProcess = child_process.ChildProcess; | |
@@ -508,8 +506,6 @@ function spawnSync(/*file, args, options*/) { | |||
| 508 | 506 | ||
| 509 | 507 | var options = opts.options; | |
| 510 | 508 | ||
| 511 | - var i; | ||
| 512 | - | ||
| 513 | 509 | debug('spawnSync', opts.args, options); | |
| 514 | 510 | ||
| 515 | 511 | // Validate the timeout, if present. | |
@@ -533,7 +529,7 @@ function spawnSync(/*file, args, options*/) { | |||
| 533 | 529 | } | |
| 534 | 530 | ||
| 535 | 531 | // We may want to pass data in on any given fd, ensure it is a valid buffer | |
| 536 | - for (i = 0; i < options.stdio.length; i++) { | ||
| 532 | + for (var i = 0; i < options.stdio.length; i++) { | ||
| 537 | 533 | var input = options.stdio[i] && options.stdio[i].input; | |
| 538 | 534 | if (input != null) { | |
| 539 | 535 | var pipe = options.stdio[i] = util._extend({}, options.stdio[i]); | |
@@ -549,50 +545,27 @@ function spawnSync(/*file, args, options*/) { | |||
| 549 | 545 | } | |
| 550 | 546 | } | |
| 551 | 547 | ||
| 552 | - var result = spawn_sync.spawn(options); | ||
| 553 | - | ||
| 554 | - if (result.output && options.encoding && options.encoding !== 'buffer') { | ||
| 555 | - for (i = 0; i < result.output.length; i++) { | ||
| 556 | - if (!result.output[i]) | ||
| 557 | - continue; | ||
| 558 | - result.output[i] = result.output[i].toString(options.encoding); | ||
| 559 | - } | ||
| 560 | - } | ||
| 561 | - | ||
| 562 | - result.stdout = result.output && result.output[1]; | ||
| 563 | - result.stderr = result.output && result.output[2]; | ||
| 564 | - | ||
| 565 | - if (result.error) { | ||
| 566 | - result.error = errnoException(result.error, 'spawnSync ' + opts.file); | ||
| 567 | - result.error.path = opts.file; | ||
| 568 | - result.error.spawnargs = opts.args.slice(1); | ||
| 569 | - } | ||
| 570 | - | ||
| 571 | - util._extend(result, opts); | ||
| 572 | - | ||
| 573 | - return result; | ||
| 548 | + return child_process.spawnSync(opts); | ||
| 574 | 549 | } | |
| 575 | 550 | exports.spawnSync = spawnSync; | |
| 576 | 551 | ||
| 577 | 552 | ||
| 578 | - function checkExecSyncError(ret) { | ||
| 579 | - if (ret.error || ret.status !== 0) { | ||
| 580 | - var err = ret.error; | ||
| 581 | - ret.error = null; | ||
| 582 | - | ||
| 583 | - if (!err) { | ||
| 584 | - var msg = 'Command failed: '; | ||
| 585 | - msg += ret.cmd || ret.args.join(' '); | ||
| 586 | - if (ret.stderr && ret.stderr.length > 0) | ||
| 587 | - msg += '\n' + ret.stderr.toString(); | ||
| 588 | - err = new Error(msg); | ||
| 589 | - } | ||
| 590 | - | ||
| 591 | - util._extend(err, ret); | ||
| 592 | - return err; | ||
| 553 | + function checkExecSyncError(ret, args, cmd) { | ||
| 554 | + var err; | ||
| 555 | + if (ret.error) { | ||
| 556 | + err = ret.error; | ||
| 557 | + } else if (ret.status !== 0) { | ||
| 558 | + var msg = 'Command failed: '; | ||
| 559 | + msg += cmd || args.join(' '); | ||
| 560 | + if (ret.stderr && ret.stderr.length > 0) | ||
| 561 | + msg += '\n' + ret.stderr.toString(); | ||
| 562 | + err = new Error(msg); | ||
| 593 | 563 | } | |
| 594 | - | ||
| 595 | - return false; | ||
| 564 | + if (err) { | ||
| 565 | + err.status = ret.status < 0 ? uv.errname(ret.status) : ret.status; | ||
| 566 | + err.signal = ret.signal; | ||
| 567 | + } | ||
| 568 | + return err; | ||
| 596 | 569 | } | |
| 597 | 570 | ||
| 598 | 571 | ||
@@ -605,7 +578,7 @@ function execFileSync(/*command, args, options*/) { | |||
| 605 | 578 | if (inheritStderr && ret.stderr) | |
| 606 | 579 | process.stderr.write(ret.stderr); | |
| 607 | 580 | ||
| 608 | - var err = checkExecSyncError(ret); | ||
| 581 | + var err = checkExecSyncError(ret, opts.args, undefined); | ||
| 609 | 582 | ||
| 610 | 583 | if (err) | |
| 611 | 584 | throw err; | |
@@ -620,12 +593,11 @@ function execSync(command /*, options*/) { | |||
| 620 | 593 | var inheritStderr = !opts.options.stdio; | |
| 621 | 594 | ||
| 622 | 595 | var ret = spawnSync(opts.file, opts.options); | |
| 623 | - ret.cmd = command; | ||
| 624 | 596 | ||
| 625 | 597 | if (inheritStderr && ret.stderr) | |
| 626 | 598 | process.stderr.write(ret.stderr); | |
| 627 | 599 | ||
| 628 | - var err = checkExecSyncError(ret); | ||
| 600 | + var err = checkExecSyncError(ret, opts.args, command); | ||
| 629 | 601 | ||
| 630 | 602 | if (err) | |
| 631 | 603 | throw err; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,7 @@ const UDP = process.binding('udp_wrap').UDP; | |||
| 18 | 18 | const SocketList = require('internal/socket_list'); | |
| 19 | 19 | const { isUint8Array } = process.binding('util'); | |
| 20 | 20 | const { convertToValidSignal } = require('internal/util'); | |
| 21 | + const spawn_sync = process.binding('spawn_sync'); | ||
| 21 | 22 | ||
| 22 | 23 | const errnoException = util._errnoException; | |
| 23 | 24 | const SocketListSend = SocketList.SocketListSend; | |
@@ -898,9 +899,34 @@ function maybeClose(subprocess) { | |||
| 898 | 899 | } | |
| 899 | 900 | } | |
| 900 | 901 | ||
| 902 | + function spawnSync(opts) { | ||
| 903 | + var options = opts.options; | ||
| 904 | + var result = spawn_sync.spawn(options); | ||
| 905 | + | ||
| 906 | + if (result.output && options.encoding && options.encoding !== 'buffer') { | ||
| 907 | + for (var i = 0; i < result.output.length; i++) { | ||
| 908 | + if (!result.output[i]) | ||
| 909 | + continue; | ||
| 910 | + result.output[i] = result.output[i].toString(options.encoding); | ||
| 911 | + } | ||
| 912 | + } | ||
| 913 | + | ||
| 914 | + result.stdout = result.output && result.output[1]; | ||
| 915 | + result.stderr = result.output && result.output[2]; | ||
| 916 | + | ||
| 917 | + if (result.error) { | ||
| 918 | + result.error = errnoException(result.error, 'spawnSync ' + opts.file); | ||
| 919 | + result.error.path = opts.file; | ||
| 920 | + result.error.spawnargs = opts.args.slice(1); | ||
| 921 | + } | ||
| 922 | + | ||
| 923 | + return result; | ||
| 924 | + } | ||
| 925 | + | ||
| 901 | 926 | module.exports = { | |
| 902 | 927 | ChildProcess, | |
| 903 | 928 | setupChannel, | |
| 904 | 929 | _validateStdio, | |
| 905 | - getSocketList | ||
| 930 | + getSocketList, | ||
| 931 | + spawnSync | ||
| 906 | 932 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,9 @@ | |||
| 1 | + // Flags: --expose_internals | ||
| 1 | 2 | 'use strict'; | |
| 2 | 3 | const common = require('../common'); | |
| 3 | 4 | const assert = require('assert'); | |
| 5 | + const internalCp = require('internal/child_process'); | ||
| 6 | + const oldSpawnSync = internalCp.spawnSync; | ||
| 4 | 7 | ||
| 5 | 8 | // Verify that customFds is used if stdio is not provided. | |
| 6 | 9 | { | |
@@ -9,25 +12,29 @@ const assert = require('assert'); | |||
| 9 | 12 | common.expectWarning('DeprecationWarning', msg); | |
| 10 | 13 | ||
| 11 | 14 | const customFds = [-1, process.stdout.fd, process.stderr.fd]; | |
| 12 | - const child = common.spawnSyncPwd({ customFds }); | ||
| 13 | - | ||
| 14 | - assert.deepStrictEqual(child.options.customFds, customFds); | ||
| 15 | - assert.deepStrictEqual(child.options.stdio, [ | ||
| 16 | - { type: 'pipe', readable: true, writable: false }, | ||
| 17 | - { type: 'fd', fd: process.stdout.fd }, | ||
| 18 | - { type: 'fd', fd: process.stderr.fd } | ||
| 19 | - ]); | ||
| 15 | + internalCp.spawnSync = common.mustCall(function(opts) { | ||
| 16 | + assert.deepStrictEqual(opts.options.customFds, customFds); | ||
| 17 | + assert.deepStrictEqual(opts.options.stdio, [ | ||
| 18 | + { type: 'pipe', readable: true, writable: false }, | ||
| 19 | + { type: 'fd', fd: process.stdout.fd }, | ||
| 20 | + { type: 'fd', fd: process.stderr.fd } | ||
| 21 | + ]); | ||
| 22 | + }); | ||
| 23 | + common.spawnSyncPwd({ customFds }); | ||
| 24 | + internalCp.spawnSync = oldSpawnSync; | ||
| 20 | 25 | } | |
| 21 | 26 | ||
| 22 | 27 | // Verify that customFds is ignored when stdio is present. | |
| 23 | 28 | { | |
| 24 | 29 | const customFds = [0, 1, 2]; | |
| 25 | - const child = common.spawnSyncPwd({ customFds, stdio: 'pipe' }); | ||
| 26 | - | ||
| 27 | - assert.deepStrictEqual(child.options.customFds, customFds); | ||
| 28 | - assert.deepStrictEqual(child.options.stdio, [ | ||
| 29 | - { type: 'pipe', readable: true, writable: false }, | ||
| 30 | - { type: 'pipe', readable: false, writable: true }, | ||
| 31 | - { type: 'pipe', readable: false, writable: true } | ||
| 32 | - ]); | ||
| 30 | + internalCp.spawnSync = common.mustCall(function(opts) { | ||
| 31 | + assert.deepStrictEqual(opts.options.customFds, customFds); | ||
| 32 | + assert.deepStrictEqual(opts.options.stdio, [ | ||
| 33 | + { type: 'pipe', readable: true, writable: false }, | ||
| 34 | + { type: 'pipe', readable: false, writable: true }, | ||
| 35 | + { type: 'pipe', readable: false, writable: true } | ||
| 36 | + ]); | ||
| 37 | + }); | ||
| 38 | + common.spawnSyncPwd({ customFds, stdio: 'pipe' }); | ||
| 39 | + internalCp.spawnSync = oldSpawnSync; | ||
| 33 | 40 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + // Flags: --expose_internals | ||
| 1 | 2 | 'use strict'; | |
| 2 | 3 | const common = require('../common'); | |
| 3 | 4 | const assert = require('assert'); | |
@@ -6,13 +7,22 @@ const cp = require('child_process'); | |||
| 6 | 7 | if (process.argv[2] === 'child') { | |
| 7 | 8 | setInterval(common.noop, 1000); | |
| 8 | 9 | } else { | |
| 10 | + const internalCp = require('internal/child_process'); | ||
| 11 | + const oldSpawnSync = internalCp.spawnSync; | ||
| 9 | 12 | const { SIGKILL } = process.binding('constants').os.signals; | |
| 10 | 13 | ||
| 11 | - function spawn(killSignal) { | ||
| 14 | + function spawn(killSignal, beforeSpawn) { | ||
| 15 | + if (beforeSpawn) { | ||
| 16 | + internalCp.spawnSync = common.mustCall(function(opts) { | ||
| 17 | + beforeSpawn(opts); | ||
| 18 | + return oldSpawnSync(opts); | ||
| 19 | + }); | ||
| 20 | + } | ||
| 12 | 21 | const child = cp.spawnSync(process.execPath, | |
| 13 | 22 | [__filename, 'child'], | |
| 14 | 23 | {killSignal, timeout: 100}); | |
| 15 | - | ||
| 24 | + if (beforeSpawn) | ||
| 25 | + internalCp.spawnSync = oldSpawnSync; | ||
| 16 | 26 | assert.strictEqual(child.status, null); | |
| 17 | 27 | assert.strictEqual(child.error.code, 'ETIMEDOUT'); | |
| 18 | 28 | return child; | |
@@ -25,26 +35,30 @@ if (process.argv[2] === 'child') { | |||
| 25 | 35 | ||
| 26 | 36 | // Verify that the default kill signal is SIGTERM. | |
| 27 | 37 | { | |
| 28 | - const child = spawn(); | ||
| 38 | + const child = spawn(undefined, (opts) => { | ||
| 39 | + assert.strictEqual(opts.options.killSignal, undefined); | ||
| 40 | + }); | ||
| 29 | 41 | ||
| 30 | 42 | assert.strictEqual(child.signal, 'SIGTERM'); | |
| 31 | - assert.strictEqual(child.options.killSignal, undefined); | ||
| 32 | 43 | } | |
| 33 | 44 | ||
| 34 | 45 | // Verify that a string signal name is handled properly. | |
| 35 | 46 | { | |
| 36 | - const child = spawn('SIGKILL'); | ||
| 47 | + const child = spawn('SIGKILL', (opts) => { | ||
| 48 | + assert.strictEqual(opts.options.killSignal, SIGKILL); | ||
| 49 | + }); | ||
| 37 | 50 | ||
| 38 | 51 | assert.strictEqual(child.signal, 'SIGKILL'); | |
| 39 | - assert.strictEqual(child.options.killSignal, SIGKILL); | ||
| 40 | 52 | } | |
| 41 | 53 | ||
| 42 | 54 | // Verify that a numeric signal is handled properly. | |
| 43 | 55 | { | |
| 44 | - const child = spawn(SIGKILL); | ||
| 45 | - | ||
| 46 | 56 | assert.strictEqual(typeof SIGKILL, 'number'); | |
| 57 | + | ||
| 58 | + const child = spawn(SIGKILL, (opts) => { | ||
| 59 | + assert.strictEqual(opts.options.killSignal, SIGKILL); | ||
| 60 | + }); | ||
| 61 | + | ||
| 47 | 62 | assert.strictEqual(child.signal, 'SIGKILL'); | |
| 48 | - assert.strictEqual(child.options.killSignal, SIGKILL); | ||
| 49 | 63 | } | |
| 50 | 64 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,10 @@ | |||
| 1 | + // Flags: --expose_internals | ||
| 1 | 2 | 'use strict'; | |
| 2 | 3 | const common = require('../common'); | |
| 3 | 4 | const assert = require('assert'); | |
| 4 | 5 | const cp = require('child_process'); | |
| 6 | + const internalCp = require('internal/child_process'); | ||
| 7 | + const oldSpawnSync = internalCp.spawnSync; | ||
| 5 | 8 | ||
| 6 | 9 | // Verify that a shell is, in fact, executed | |
| 7 | 10 | const doesNotExist = cp.spawnSync('does-not-exist', {shell: true}); | |
@@ -16,10 +19,14 @@ else | |||
| 16 | 19 | assert.strictEqual(doesNotExist.status, 127); // Exit code of /bin/sh | |
| 17 | 20 | ||
| 18 | 21 | // Verify that passing arguments works | |
| 22 | + internalCp.spawnSync = common.mustCall(function(opts) { | ||
| 23 | + assert.strictEqual(opts.args[opts.args.length - 1].replace(/"/g, ''), | ||
| 24 | + 'echo foo'); | ||
| 25 | + return oldSpawnSync(opts); | ||
| 26 | + }); | ||
| 19 | 27 | const echo = cp.spawnSync('echo', ['foo'], {shell: true}); | |
| 28 | + internalCp.spawnSync = oldSpawnSync; | ||
| 20 | 29 | ||
| 21 | - assert.strictEqual(echo.args[echo.args.length - 1].replace(/"/g, ''), | ||
| 22 | - 'echo foo'); | ||
| 23 | 30 | assert.strictEqual(echo.stdout.toString().trim(), 'foo'); | |
| 24 | 31 | ||
| 25 | 32 | // Verify that shell features can be used | |
@@ -52,16 +59,18 @@ assert.strictEqual(env.stdout.toString().trim(), 'buzz'); | |||
| 52 | 59 | const shellFlags = platform === 'win32' ? ['/d', '/s', '/c'] : ['-c']; | |
| 53 | 60 | const outputCmd = platform === 'win32' ? `"${cmd}"` : cmd; | |
| 54 | 61 | const windowsVerbatim = platform === 'win32' ? true : undefined; | |
| 55 | - const result = cp.spawnSync(cmd, { shell }); | ||
| 56 | - | ||
| 57 | - assert.strictEqual(result.file, shellOutput); | ||
| 58 | - assert.deepStrictEqual(result.args, | ||
| 59 | - [shellOutput, ...shellFlags, outputCmd]); | ||
| 60 | - assert.strictEqual(result.options.shell, shell); | ||
| 61 | - assert.strictEqual(result.options.file, result.file); | ||
| 62 | - assert.deepStrictEqual(result.options.args, result.args); | ||
| 63 | - assert.strictEqual(result.options.windowsVerbatimArguments, | ||
| 64 | - windowsVerbatim); | ||
| 62 | + internalCp.spawnSync = common.mustCall(function(opts) { | ||
| 63 | + assert.strictEqual(opts.file, shellOutput); | ||
| 64 | + assert.deepStrictEqual(opts.args, | ||
| 65 | + [shellOutput, ...shellFlags, outputCmd]); | ||
| 66 | + assert.strictEqual(opts.options.shell, shell); | ||
| 67 | + assert.strictEqual(opts.options.file, opts.file); | ||
| 68 | + assert.deepStrictEqual(opts.options.args, opts.args); | ||
| 69 | + assert.strictEqual(opts.options.windowsVerbatimArguments, | ||
| 70 | + windowsVerbatim); | ||
| 71 | + }); | ||
| 72 | + cp.spawnSync(cmd, { shell }); | ||
| 73 | + internalCp.spawnSync = oldSpawnSync; | ||
| 65 | 74 | } | |
| 66 | 75 | ||
| 67 | 76 | // Test Unix platforms with the default shell. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments