shell: add option for maxLines

This commit is contained in:
Girish Ramakrishnan
2024-11-18 07:59:05 +05:30
parent d7f829b3e1
commit 8f6637773b
2 changed files with 46 additions and 2 deletions

View File

@@ -22,6 +22,19 @@ function shell(tag) {
const SUDO = '/usr/bin/sudo';
function lineCount(buffer) {
assert(Buffer.isBuffer(buffer));
const NEW_LINE = Buffer.from('\n');
let index = buffer.indexOf(NEW_LINE);
let count = 0;
while (index >= 0) {
index = buffer.indexOf(NEW_LINE, index+1);
++count;
}
return count;
}
function spawn(tag, file, args, options) {
assert.strictEqual(typeof tag, 'string');
assert.strictEqual(typeof file, 'string');
@@ -30,12 +43,23 @@ function spawn(tag, file, args, options) {
debug(`${tag}: ${file} ${args.join(' ').replace(/\n/g, '\\n')}`);
const maxLines = options.maxLines || Number.MAX_SAFE_INTEGER;
return new Promise((resolve, reject) => {
const cp = child_process.spawn(file, args, options);
const stdoutBuffers = [], stderrBuffers = [];
let stdoutLineCount = 0, stderrLineCount = 0;
cp.stdout.on('data', (data) => stdoutBuffers.push(data));
cp.stderr.on('data', (data) => stderrBuffers.push(data));
cp.stdout.on('data', (data) => {
stdoutBuffers.push(data);
stdoutLineCount += lineCount(data);
if (stdoutLineCount >= maxLines) return cp.kill('SIGKILL');
});
cp.stderr.on('data', (data) => {
stderrBuffers.push(data);
stderrLineCount += lineCount(data);
if (stderrLineCount >= maxLines) return cp.kill('SIGKILL');
});
cp.on('close', function (code, signal) { // always called. after 'exit' or 'error'
const stdoutBuffer = Buffer.concat(stdoutBuffers);
@@ -47,7 +71,9 @@ function spawn(tag, file, args, options) {
const e = new BoxError(BoxError.SHELL_ERROR, `${file} exited with code ${code} signal ${signal}`);
e.stdout = stdout; // when promisified, this is the way to get stdout
e.stdoutLineCount = stdoutLineCount;
e.stderr = stderr; // when promisified, this is the way to get stderr
e.stderrLineCount = stderrLineCount;
e.code = code;
e.signal = signal;