Skip to content

Commit 2dd420e

Browse files
committed
process: provide dummy stdio for non-console Windows apps
The only known condition where we could not provide appropriate stdio streams so far were non-console Windows applications. Since this issue has come up a few times in our issue tracker now, switch to providing dummy streams for these cases instead. If there are other valid cases in which `uv_guess_handle` fails, and where there is a more sensible way to provide stdio, we’ll probably still find out because the streams don’t work properly either way. Refs: nodejs/help#1251 PR-URL: nodejs#20640 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
1 parent f6e341a commit 2dd420e

File tree

4 files changed

+68
-26
lines changed

4 files changed

+68
-26
lines changed

doc/api/errors.md

+22-14
Original file line numberDiff line numberDiff line change
@@ -1804,20 +1804,6 @@ An attempt was made to load a module with an unknown or unsupported format.
18041804
An invalid or unknown process signal was passed to an API expecting a valid
18051805
signal (such as [`subprocess.kill()`][]).
18061806

1807-
<a id="ERR_UNKNOWN_STDIN_TYPE"></a>
1808-
### ERR_UNKNOWN_STDIN_TYPE
1809-
1810-
An attempt was made to launch a Node.js process with an unknown `stdin` file
1811-
type. This error is usually an indication of a bug within Node.js itself,
1812-
although it is possible for user code to trigger it.
1813-
1814-
<a id="ERR_UNKNOWN_STREAM_TYPE"></a>
1815-
### ERR_UNKNOWN_STREAM_TYPE
1816-
1817-
An attempt was made to launch a Node.js process with an unknown `stdout` or
1818-
`stderr` file type. This error is usually an indication of a bug within Node.js
1819-
itself, although it is possible for user code to trigger it.
1820-
18211807
<a id="ERR_V8BREAKITERATOR"></a>
18221808
### ERR_V8BREAKITERATOR
18231809

@@ -2074,6 +2060,28 @@ kind of internal Node.js error that should not typically be triggered by user
20742060
code. Instances of this error point to an internal bug within the Node.js
20752061
binary itself.
20762062

2063+
<a id="ERR_UNKNOWN_STDIN_TYPE"></a>
2064+
### ERR_UNKNOWN_STDIN_TYPE
2065+
<!-- YAML
2066+
added: v8.0.0
2067+
removed: REPLACEME
2068+
-->
2069+
2070+
An attempt was made to launch a Node.js process with an unknown `stdin` file
2071+
type. This error is usually an indication of a bug within Node.js itself,
2072+
although it is possible for user code to trigger it.
2073+
2074+
<a id="ERR_UNKNOWN_STREAM_TYPE"></a>
2075+
### ERR_UNKNOWN_STREAM_TYPE
2076+
<!-- YAML
2077+
added: v8.0.0
2078+
removed: REPLACEME
2079+
-->
2080+
2081+
An attempt was made to launch a Node.js process with an unknown `stdout` or
2082+
`stderr` file type. This error is usually an indication of a bug within Node.js
2083+
itself, although it is possible for user code to trigger it.
2084+
20772085
<a id="ERR_VALUE_OUT_OF_RANGE"></a>
20782086
### ERR_VALUE_OUT_OF_RANGE
20792087
<!-- YAML

lib/internal/errors.js

-3
Original file line numberDiff line numberDiff line change
@@ -945,10 +945,7 @@ E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);
945945
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: %s', Error);
946946
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
947947
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
948-
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type', Error);
949948

950-
// This should probably be a `TypeError`.
951-
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type', Error);
952949
E('ERR_V8BREAKITERATOR',
953950
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',
954951
Error);

lib/internal/process/stdio.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
'use strict';
22

3-
const {
4-
ERR_UNKNOWN_STDIN_TYPE,
5-
ERR_UNKNOWN_STREAM_TYPE
6-
} = require('internal/errors').codes;
7-
83
exports.setupProcessStdio = setupProcessStdio;
94
exports.getMainThreadStdio = getMainThreadStdio;
105

@@ -87,8 +82,11 @@ function getMainThreadStdio() {
8782
break;
8883

8984
default:
90-
// Probably an error on in uv_guess_handle()
91-
throw new ERR_UNKNOWN_STDIN_TYPE();
85+
// Provide a dummy contentless input for e.g. non-console
86+
// Windows applications.
87+
const { Readable } = require('stream');
88+
stdin = new Readable({ read() {} });
89+
stdin.push(null);
9290
}
9391

9492
// For supporting legacy API we put the FD here.
@@ -123,6 +121,12 @@ function getMainThreadStdio() {
123121
return stdin;
124122
}
125123

124+
exports.resetStdioForTesting = function() {
125+
stdin = undefined;
126+
stdout = undefined;
127+
stderr = undefined;
128+
};
129+
126130
return {
127131
getStdout,
128132
getStderr,
@@ -199,8 +203,14 @@ function createWritableStdioStream(fd) {
199203
break;
200204

201205
default:
202-
// Probably an error on in uv_guess_handle()
203-
throw new ERR_UNKNOWN_STREAM_TYPE();
206+
// Provide a dummy black-hole output for e.g. non-console
207+
// Windows applications.
208+
const { Writable } = require('stream');
209+
stream = new Writable({
210+
write(buf, enc, cb) {
211+
cb();
212+
}
213+
});
204214
}
205215

206216
// For supporting legacy API we put the FD here.

test/parallel/test-dummy-stdio.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
6+
if (common.isWindows)
7+
common.skip('fs.closeSync(n) does not close stdio on Windows');
8+
9+
function runTest(fd, streamName, testOutputStream, expectedName) {
10+
const result = child_process.spawnSync(process.execPath, [
11+
'--expose-internals',
12+
'-e', `
13+
require('internal/process/stdio').resetStdioForTesting();
14+
fs.closeSync(${fd});
15+
const ctorName = process.${streamName}.constructor.name;
16+
process.${testOutputStream}.write(ctorName);
17+
`]);
18+
assert.strictEqual(result[testOutputStream].toString(), expectedName,
19+
`stdout:\n${result.stdout}\nstderr:\n${result.stderr}\n` +
20+
`while running test with fd = ${fd}`);
21+
if (testOutputStream !== 'stderr')
22+
assert.strictEqual(result.stderr.toString(), '');
23+
}
24+
25+
runTest(0, 'stdin', 'stdout', 'Readable');
26+
runTest(1, 'stdout', 'stderr', 'Writable');
27+
runTest(2, 'stderr', 'stdout', 'Writable');

0 commit comments

Comments
 (0)