diff options
| author | christine betts <[email protected]> | 2025-08-14 18:09:19 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-14 18:09:19 +0000 |
| commit | af93a10a92423184b30c8ef0f5a8e9e70abff167 (patch) | |
| tree | 2b94b9d8ac40ba026b9d2c40685988f621f575dd /packages/core/src/ide/process-utils.ts | |
| parent | ec7b84191f539c1a3f890fc994dd62b68d3232fd (diff) | |
[ide-mode] Write port to file in ide-server (#5811)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Diffstat (limited to 'packages/core/src/ide/process-utils.ts')
| -rw-r--r-- | packages/core/src/ide/process-utils.ts | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/packages/core/src/ide/process-utils.ts b/packages/core/src/ide/process-utils.ts new file mode 100644 index 00000000..40e16a73 --- /dev/null +++ b/packages/core/src/ide/process-utils.ts @@ -0,0 +1,62 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { exec } from 'child_process'; +import { promisify } from 'util'; +import os from 'os'; + +const execAsync = promisify(exec); + +/** + * Traverses up the process tree from the current process to find the top-level ancestor process ID. + * This is useful for identifying the main application process that spawned the current script, + * such as the main VS Code window process. + * + * @returns A promise that resolves to the numeric PID of the top-level process. + * @throws Will throw an error if the underlying shell commands fail unexpectedly. + */ +export async function getIdeProcessId(): Promise<number> { + const platform = os.platform(); + let currentPid = process.pid; + + // Loop upwards through the process tree, with a depth limit to prevent infinite loops. + const MAX_TRAVERSAL_DEPTH = 32; + for (let i = 0; i < MAX_TRAVERSAL_DEPTH; i++) { + let parentPid: number; + + try { + // Use wmic for Windows + if (platform === 'win32') { + const command = `wmic process where "ProcessId=${currentPid}" get ParentProcessId /value`; + const { stdout } = await execAsync(command); + const match = stdout.match(/ParentProcessId=(\d+)/); + parentPid = match ? parseInt(match[1], 10) : 0; // Top of the tree is 0 + } + // Use ps for macOS, Linux, and other Unix-like systems + else { + const command = `ps -o ppid= -p ${currentPid}`; + const { stdout } = await execAsync(command); + const ppid = parseInt(stdout.trim(), 10); + parentPid = isNaN(ppid) ? 1 : ppid; // Top of the tree is 1 + } + } catch (_) { + // This can happen if a process in the chain dies during execution. + // We'll break the loop and return the last valid PID we found. + break; + } + + // Define the root PID for the current OS + const rootPid = platform === 'win32' ? 0 : 1; + + // If the parent is the root process or invalid, we've found our target. + if (parentPid === rootPid || parentPid <= 0) { + break; + } + // Move one level up the tree for the next iteration. + currentPid = parentPid; + } + return currentPid; +} |
