Skip to content

Commit 1805236

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: #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 272ddb1 commit 1805236

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
@@ -1810,20 +1810,6 @@ An attempt was made to load a module with an unknown or unsupported format.
18101810
An invalid or unknown process signal was passed to an API expecting a valid
18111811
signal (such as [`subprocess.kill()`][]).
18121812

1813-
<a id="ERR_UNKNOWN_STDIN_TYPE"></a>
1814-
### ERR_UNKNOWN_STDIN_TYPE
1815-
1816-
An attempt was made to launch a Node.js process with an unknown `stdin` file
1817-
type. This error is usually an indication of a bug within Node.js itself,
1818-
although it is possible for user code to trigger it.
1819-
1820-
<a id="ERR_UNKNOWN_STREAM_TYPE"></a>
1821-
### ERR_UNKNOWN_STREAM_TYPE
1822-
1823-
An attempt was made to launch a Node.js process with an unknown `stdout` or
1824-
`stderr` file type. This error is usually an indication of a bug within Node.js
1825-
itself, although it is possible for user code to trigger it.
1826-
18271813
<a id="ERR_V8BREAKITERATOR"></a>
18281814
### ERR_V8BREAKITERATOR
18291815

@@ -2080,6 +2066,28 @@ kind of internal Node.js error that should not typically be triggered by user
20802066
code. Instances of this error point to an internal bug within the Node.js
20812067
binary itself.
20822068

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

lib/internal/errors.js

-3
Original file line numberDiff line numberDiff line change
@@ -947,10 +947,7 @@ E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);
947947
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: %s', Error);
948948
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
949949
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
950-
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type', Error);
951950

952-
// This should probably be a `TypeError`.
953-
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type', Error);
954951
E('ERR_V8BREAKITERATOR',
955952
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',
956953
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)