Skip to content

Commit 2bc177a

Browse files
cjihrigBridgeAR
authored andcommitted
child_process: setup stdio on error when possible
As more spawn() errors are classified as runtime errors, it's no longer appropriate to only check UV_ENOENT when determining if stdio can be setup. This commit reverses the check to look for EMFILE and ENFILE specifically. PR-URL: #27696Fixes: #26852 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 10b4a81 commit 2bc177a

3 files changed

Lines changed: 19 additions & 4 deletions

File tree

‎lib/internal/child_process.js‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,11 @@ ChildProcess.prototype.spawn = function(options) {
375375
err===UV_ENFILE||
376376
err===UV_ENOENT){
377377
process.nextTick(onErrorNT,this,err);
378+
378379
// There is no point in continuing when we've hit EMFILE or ENFILE
379380
// because we won't be able to set up the stdio file descriptors.
380-
// It's kind of silly that the de facto spec for ENOENT (the test suite)
381-
// mandates that stdio _is_ set up, even if there is no process on the
382-
// receiving end, but it is what it is.
383-
if(err!==UV_ENOENT)returnerr;
381+
if(err===UV_EMFILE||err===UV_ENFILE)
382+
returnerr;
384383
}elseif(err){
385384
// Close all opened fds on error
386385
for(i=0;i<stdio.length;i++){

‎test/parallel/test-child-process-spawn-error.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ const spawnargs = ['bar'];
3030
assert.strictEqual(fs.existsSync(enoentPath),false);
3131

3232
constenoentChild=spawn(enoentPath,spawnargs);
33+
34+
// Verify that stdio is setup if the error is not EMFILE or ENFILE.
35+
assert.notStrictEqual(enoentChild.stdin,undefined);
36+
assert.notStrictEqual(enoentChild.stdout,undefined);
37+
assert.notStrictEqual(enoentChild.stderr,undefined);
38+
assert(Array.isArray(enoentChild.stdio));
39+
assert.strictEqual(enoentChild.stdio[0],enoentChild.stdin);
40+
assert.strictEqual(enoentChild.stdio[1],enoentChild.stdout);
41+
assert.strictEqual(enoentChild.stdio[2],enoentChild.stderr);
42+
3343
enoentChild.on('error',common.mustCall(function(err){
3444
assert.strictEqual(err.code,'ENOENT');
3545
assert.strictEqual(err.errno,'ENOENT');

‎test/sequential/test-child-process-emfile.js‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ for (;;) {
5858
// Should emit an error, not throw.
5959
constproc=child_process.spawn(process.execPath,['-e','0']);
6060

61+
// Verify that stdio is not setup on EMFILE or ENFILE.
62+
assert.strictEqual(proc.stdin,undefined);
63+
assert.strictEqual(proc.stdout,undefined);
64+
assert.strictEqual(proc.stderr,undefined);
65+
assert.strictEqual(proc.stdio,undefined);
66+
6167
proc.on('error',common.mustCall(function(err){
6268
assert.strictEqual(err.code,'EMFILE');
6369
}));

0 commit comments

Comments
 (0)