Skip to content

Commit 8ff8af5

Browse files
addaleaxBridgeAR
authored andcommitted
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 2dfaa48 commit 8ff8af5

File tree

4 files changed

+68
-26
lines changed

4 files changed

+68
-26
lines changed

doc/api/errors.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,20 +1778,6 @@ An attempt was made to load a module with an unknown or unsupported format.
17781778
An invalid or unknown process signal was passed to an API expecting a valid
17791779
signal (such as [`subprocess.kill()`][]).
17801780

1781-
<a id="ERR_UNKNOWN_STDIN_TYPE"></a>
1782-
### ERR_UNKNOWN_STDIN_TYPE
1783-
1784-
An attempt was made to launch a Node.js process with an unknown `stdin` file
1785-
type. This error is usually an indication of a bug within Node.js itself,
1786-
although it is possible for user code to trigger it.
1787-
1788-
<a id="ERR_UNKNOWN_STREAM_TYPE"></a>
1789-
### ERR_UNKNOWN_STREAM_TYPE
1790-
1791-
An attempt was made to launch a Node.js process with an unknown `stdout` or
1792-
`stderr` file type. This error is usually an indication of a bug within Node.js
1793-
itself, although it is possible for user code to trigger it.
1794-
17951781
<a id="ERR_V8BREAKITERATOR"></a>
17961782
### ERR_V8BREAKITERATOR
17971783

@@ -2048,6 +2034,28 @@ kind of internal Node.js error that should not typically be triggered by user
20482034
code. Instances of this error point to an internal bug within the Node.js
20492035
binary itself.
20502036

2037+
<a id="ERR_UNKNOWN_STDIN_TYPE"></a>
2038+
### ERR_UNKNOWN_STDIN_TYPE
2039+
<!-- YAML
2040+
added: v8.0.0
2041+
removed: REPLACEME
2042+
-->
2043+
2044+
An attempt was made to launch a Node.js process with an unknown `stdin` file
2045+
type. This error is usually an indication of a bug within Node.js itself,
2046+
although it is possible for user code to trigger it.
2047+
2048+
<a id="ERR_UNKNOWN_STREAM_TYPE"></a>
2049+
### ERR_UNKNOWN_STREAM_TYPE
2050+
<!-- YAML
2051+
added: v8.0.0
2052+
removed: REPLACEME
2053+
-->
2054+
2055+
An attempt was made to launch a Node.js process with an unknown `stdout` or
2056+
`stderr` file type. This error is usually an indication of a bug within Node.js
2057+
itself, although it is possible for user code to trigger it.
2058+
20512059
<a id="ERR_VALUE_OUT_OF_RANGE"></a>
20522060
### ERR_VALUE_OUT_OF_RANGE
20532061
<!-- YAML

lib/internal/errors.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -901,10 +901,7 @@ E('ERR_UNKNOWN_ENCODING', 'Unknown encoding: %s', TypeError);
901901
E('ERR_UNKNOWN_FILE_EXTENSION', 'Unknown file extension: %s', Error);
902902
E('ERR_UNKNOWN_MODULE_FORMAT', 'Unknown module format: %s', RangeError);
903903
E('ERR_UNKNOWN_SIGNAL', 'Unknown signal: %s', TypeError);
904-
E('ERR_UNKNOWN_STDIN_TYPE', 'Unknown stdin file type', Error);
905904

906-
// This should probably be a `TypeError`.
907-
E('ERR_UNKNOWN_STREAM_TYPE', 'Unknown stream file type', Error);
908905
E('ERR_V8BREAKITERATOR',
909906
'Full ICU data not installed. See https://github.com/nodejs/node/wiki/Intl',
910907
Error);

lib/internal/process/stdio.js

Lines changed: 19 additions & 9 deletions
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

Lines changed: 27 additions & 0 deletions
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)