mirror of
https://github.com/nodejs/node.git
synced 2025-05-09 05:41:13 +00:00

Closing the underlying resource completely has the unwanted side effect that the stream can no longer be used at all, including passing it to other child processes. What we want to avoid is accidentally reading from the stream; accordingly, it should be sufficient to stop its readable side manually, and otherwise leave the underlying resource intact. Fixes: https://github.com/nodejs/node/issues/27097 Refs: https://github.com/nodejs/node/pull/21209 PR-URL: https://github.com/nodejs/node/pull/27373 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
'use strict';
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const spawn = require('child_process').spawn;
|
|
const tmpdir = require('../common/tmpdir');
|
|
|
|
let cat, grep, wc;
|
|
|
|
const KB = 1024;
|
|
const MB = KB * KB;
|
|
|
|
|
|
// Make sure process chaining allows desired data flow:
|
|
// check cat <file> | grep 'x' | wc -c === 1MB
|
|
// This helps to make sure no data is lost between pipes.
|
|
|
|
{
|
|
tmpdir.refresh();
|
|
const file = path.resolve(tmpdir.path, 'data.txt');
|
|
const buf = Buffer.alloc(MB).fill('x');
|
|
|
|
// Most OS commands that deal with data, attach special
|
|
// meanings to new line - for example, line buffering.
|
|
// So cut the buffer into lines at some points, forcing
|
|
// data flow to be split in the stream.
|
|
for (let i = 0; i < KB; i++)
|
|
buf[i * KB] = 10;
|
|
fs.writeFileSync(file, buf.toString());
|
|
|
|
cat = spawn('cat', [file]);
|
|
grep = spawn('grep', ['x'], { stdio: [cat.stdout, 'pipe', 'pipe'] });
|
|
wc = spawn('wc', ['-c'], { stdio: [grep.stdout, 'pipe', 'pipe'] });
|
|
|
|
// Extra checks: We never try to start reading data ourselves.
|
|
cat.stdout._handle.readStart = common.mustNotCall();
|
|
grep.stdout._handle.readStart = common.mustNotCall();
|
|
|
|
[cat, grep, wc].forEach((child, index) => {
|
|
child.stderr.on('data', (d) => {
|
|
// Don't want to assert here, as we might miss error code info.
|
|
console.error(`got unexpected data from child #${index}:\n${d}`);
|
|
});
|
|
child.on('exit', common.mustCall(function(code) {
|
|
assert.strictEqual(code, 0);
|
|
}));
|
|
});
|
|
|
|
wc.stdout.on('data', common.mustCall(function(data) {
|
|
assert.strictEqual(data.toString().trim(), MB.toString());
|
|
}));
|
|
}
|