Files
gemini-cli/packages/cli/src/utils/readStdin.ts

69 lines
1.9 KiB
TypeScript
Raw Normal View History

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
export async function readStdin(): Promise<string> {
const MAX_STDIN_SIZE = 8 * 1024 * 1024; // 8MB
return new Promise((resolve, reject) => {
let data = '';
let totalSize = 0;
process.stdin.setEncoding('utf8');
const pipedInputShouldBeAvailableInMs = 500;
let pipedInputTimerId: null | NodeJS.Timeout = setTimeout(() => {
// stop reading if input is not available yet, this is needed
// in terminals where stdin is never TTY and nothing's piped
// which causes the program to get stuck expecting data from stdin
onEnd();
}, pipedInputShouldBeAvailableInMs);
const onReadable = () => {
let chunk;
while ((chunk = process.stdin.read()) !== null) {
if (pipedInputTimerId) {
clearTimeout(pipedInputTimerId);
pipedInputTimerId = null;
}
if (totalSize + chunk.length > MAX_STDIN_SIZE) {
const remainingSize = MAX_STDIN_SIZE - totalSize;
data += chunk.slice(0, remainingSize);
console.warn(
`Warning: stdin input truncated to ${MAX_STDIN_SIZE} bytes.`,
);
process.stdin.destroy(); // Stop reading further
break;
}
data += chunk;
totalSize += chunk.length;
}
};
const onEnd = () => {
Jacob314/memory fixes (#754) Address multiple possible memory leaks found bystatic analysis of the codebase. The primary source of the leaks was event listeners on child processes and global objects that were not being properly removed, potentially causing their closures to be retained in memory indefinitely particularly for processes that did not exit. There are two commits. A larger one made by gemini CLI and a smaller one by me to make sure we always disconnect child processes as part of the cleanup methods. These changes may not actually fix any leaks but do look like reasonable defensive coding to avoid leaking event listeners or child processes. The following files were fixed: This is Gemini's somewhat overconfident description of what it did. packages/core/src/tools/shell.ts: Fixed a leak where an abortSignal listener was not being reliably removed. packages/cli/src/utils/readStdin.ts: Fixed a significant leak where listeners on process.stdin were never removed. packages/cli/src/utils/sandbox.ts: Fixed leaks in the imageExists and pullImage helper functions where listeners on spawned child processes were not being removed. packages/core/src/tools/grep.ts: Fixed three separate leaks in the isCommandAvailable check and the git grep and system grep strategies due to un-removed listeners on child processes. packages/core/src/tools/tool-registry.ts: Corrected a leak in the execute method of the DiscoveredTool class where listeners on the spawned tool process were not being removed.
2025-06-05 06:40:33 -07:00
cleanup();
resolve(data);
};
const onError = (err: Error) => {
Jacob314/memory fixes (#754) Address multiple possible memory leaks found bystatic analysis of the codebase. The primary source of the leaks was event listeners on child processes and global objects that were not being properly removed, potentially causing their closures to be retained in memory indefinitely particularly for processes that did not exit. There are two commits. A larger one made by gemini CLI and a smaller one by me to make sure we always disconnect child processes as part of the cleanup methods. These changes may not actually fix any leaks but do look like reasonable defensive coding to avoid leaking event listeners or child processes. The following files were fixed: This is Gemini's somewhat overconfident description of what it did. packages/core/src/tools/shell.ts: Fixed a leak where an abortSignal listener was not being reliably removed. packages/cli/src/utils/readStdin.ts: Fixed a significant leak where listeners on process.stdin were never removed. packages/cli/src/utils/sandbox.ts: Fixed leaks in the imageExists and pullImage helper functions where listeners on spawned child processes were not being removed. packages/core/src/tools/grep.ts: Fixed three separate leaks in the isCommandAvailable check and the git grep and system grep strategies due to un-removed listeners on child processes. packages/core/src/tools/tool-registry.ts: Corrected a leak in the execute method of the DiscoveredTool class where listeners on the spawned tool process were not being removed.
2025-06-05 06:40:33 -07:00
cleanup();
reject(err);
};
Jacob314/memory fixes (#754) Address multiple possible memory leaks found bystatic analysis of the codebase. The primary source of the leaks was event listeners on child processes and global objects that were not being properly removed, potentially causing their closures to be retained in memory indefinitely particularly for processes that did not exit. There are two commits. A larger one made by gemini CLI and a smaller one by me to make sure we always disconnect child processes as part of the cleanup methods. These changes may not actually fix any leaks but do look like reasonable defensive coding to avoid leaking event listeners or child processes. The following files were fixed: This is Gemini's somewhat overconfident description of what it did. packages/core/src/tools/shell.ts: Fixed a leak where an abortSignal listener was not being reliably removed. packages/cli/src/utils/readStdin.ts: Fixed a significant leak where listeners on process.stdin were never removed. packages/cli/src/utils/sandbox.ts: Fixed leaks in the imageExists and pullImage helper functions where listeners on spawned child processes were not being removed. packages/core/src/tools/grep.ts: Fixed three separate leaks in the isCommandAvailable check and the git grep and system grep strategies due to un-removed listeners on child processes. packages/core/src/tools/tool-registry.ts: Corrected a leak in the execute method of the DiscoveredTool class where listeners on the spawned tool process were not being removed.
2025-06-05 06:40:33 -07:00
const cleanup = () => {
if (pipedInputTimerId) {
clearTimeout(pipedInputTimerId);
pipedInputTimerId = null;
}
process.stdin.removeListener('readable', onReadable);
process.stdin.removeListener('end', onEnd);
process.stdin.removeListener('error', onError);
};
Jacob314/memory fixes (#754) Address multiple possible memory leaks found bystatic analysis of the codebase. The primary source of the leaks was event listeners on child processes and global objects that were not being properly removed, potentially causing their closures to be retained in memory indefinitely particularly for processes that did not exit. There are two commits. A larger one made by gemini CLI and a smaller one by me to make sure we always disconnect child processes as part of the cleanup methods. These changes may not actually fix any leaks but do look like reasonable defensive coding to avoid leaking event listeners or child processes. The following files were fixed: This is Gemini's somewhat overconfident description of what it did. packages/core/src/tools/shell.ts: Fixed a leak where an abortSignal listener was not being reliably removed. packages/cli/src/utils/readStdin.ts: Fixed a significant leak where listeners on process.stdin were never removed. packages/cli/src/utils/sandbox.ts: Fixed leaks in the imageExists and pullImage helper functions where listeners on spawned child processes were not being removed. packages/core/src/tools/grep.ts: Fixed three separate leaks in the isCommandAvailable check and the git grep and system grep strategies due to un-removed listeners on child processes. packages/core/src/tools/tool-registry.ts: Corrected a leak in the execute method of the DiscoveredTool class where listeners on the spawned tool process were not being removed.
2025-06-05 06:40:33 -07:00
process.stdin.on('readable', onReadable);
process.stdin.on('end', onEnd);
process.stdin.on('error', onError);
});
}