Skip to content

Commit 0653acf

Browse files
committed
stdio: implement manual start for ReadStream
All stdio ReadStream's use manual start to avoid consuming data for example when a process execs/spawns Refs: #36251
1 parent 49abda7 commit 0653acf

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

lib/internal/bootstrap/switches/is_main_thread.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ function getStdin() {
157157

158158
case 'FILE':
159159
const fs = require('fs');
160-
stdin = new fs.ReadStream(null, { fd: fd, autoClose: false });
160+
stdin = new fs.ReadStream(null, {
161+
fd: fd,
162+
autoClose: false,
163+
manualStart: true
164+
});
161165
break;
162166

163167
case 'PIPE':

lib/internal/streams/readable.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ function Readable(options) {
196196
Stream.call(this, options);
197197

198198
destroyImpl.construct(this, () => {
199-
maybeReadMore(this, this._readableState);
199+
if (!options || !options.manualStart)
200+
maybeReadMore(this, this._readableState);
200201
});
201202
}
202203

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
const common = require('../common');
3+
const process = require('process');
4+
if (process.platform !== 'linux' && process.platform !== 'darwin')
5+
common.skip('This is an UNIX-only test');
6+
7+
const { execSync } = require('child_process');
8+
const fs = require('fs');
9+
const path = require('path');
10+
const tmpdir = require('../common/tmpdir');
11+
12+
const tmpDir = tmpdir.path;
13+
tmpdir.refresh();
14+
const tmpCmdFile = path.join(tmpDir, 'test-stdin-from-file-spawn-cmd');
15+
const tmpJsFile = path.join(tmpDir, 'test-stdin-from-file-spawn.js');
16+
fs.writeFileSync(tmpCmdFile, 'echo hello');
17+
fs.writeFileSync(tmpJsFile, `
18+
'use strict';
19+
const { spawn } = require('child_process');
20+
// Reference the object to invoke the getter
21+
process.stdin;
22+
setTimeout(() => {
23+
let ok = false;
24+
const child = spawn(process.env.SHELL, [], { stdio: ['inherit', 'pipe'] });
25+
child.stdout.on('data', () => {
26+
ok = true;
27+
});
28+
child.on('close', () => {
29+
process.exit(ok ? 0 : -1);
30+
});
31+
}, 100);
32+
`);
33+
34+
execSync(`${process.argv[0]} ${tmpJsFile} < ${tmpCmdFile}`);

0 commit comments

Comments
 (0)