mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-29 07:21:27 -07:00
fix(core): destroy PTY on kill() and exception to prevent fd leak (#21693)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
@@ -552,6 +552,8 @@ export class ShellExecutionService {
|
||||
// This should not happen, but as a safeguard...
|
||||
throw new Error('PTY implementation not found');
|
||||
}
|
||||
let spawnedPty: IPty | undefined;
|
||||
|
||||
try {
|
||||
const cols = shellExecutionConfig.terminalWidth ?? 80;
|
||||
const rows = shellExecutionConfig.terminalHeight ?? 30;
|
||||
@@ -585,6 +587,8 @@ export class ShellExecutionService {
|
||||
},
|
||||
handleFlowControl: true,
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
spawnedPty = ptyProcess as IPty;
|
||||
|
||||
const result = new Promise<ShellExecutionResult>((resolve) => {
|
||||
this.activeResolvers.set(ptyProcess.pid, resolve);
|
||||
@@ -882,6 +886,15 @@ export class ShellExecutionService {
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
const error = e as Error;
|
||||
|
||||
if (spawnedPty) {
|
||||
try {
|
||||
(spawnedPty as IPty & { destroy?: () => void }).destroy?.();
|
||||
} catch {
|
||||
// Ignore errors during cleanup
|
||||
}
|
||||
}
|
||||
|
||||
if (error.message.includes('posix_spawnp failed')) {
|
||||
onOutputEvent({
|
||||
type: 'data',
|
||||
@@ -1008,6 +1021,11 @@ export class ShellExecutionService {
|
||||
this.activeChildProcesses.delete(pid);
|
||||
} else if (activePty) {
|
||||
killProcessGroup({ pid, pty: activePty.ptyProcess }).catch(() => {});
|
||||
try {
|
||||
(activePty.ptyProcess as IPty & { destroy?: () => void }).destroy?.();
|
||||
} catch {
|
||||
// Ignore errors during cleanup
|
||||
}
|
||||
this.activePtys.delete(pid);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user