diff options
Diffstat (limited to 'cli/ops/runtime.rs')
-rw-r--r-- | cli/ops/runtime.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/cli/ops/runtime.rs b/cli/ops/runtime.rs index e47b40792..1e426ad8a 100644 --- a/cli/ops/runtime.rs +++ b/cli/ops/runtime.rs @@ -32,6 +32,7 @@ fn op_start( "denoVersion": version::DENO, "noColor": !colors::use_color(), "pid": std::process::id(), + "ppid": ppid(), "repl": gs.flags.subcommand == DenoSubcommand::Repl, "target": env!("TARGET"), "tsVersion": version::TYPESCRIPT, @@ -78,3 +79,62 @@ fn op_metrics( "bytesReceived": m.bytes_received }))) } + +fn ppid() -> Value { + #[cfg(windows)] + { + // Adopted from rustup: + // https://github.com/rust-lang/rustup/blob/1.21.1/src/cli/self_update.rs#L1036 + // Copyright Diggory Blake, the Mozilla Corporation, and rustup contributors. + // Licensed under either of + // - Apache License, Version 2.0 + // - MIT license + use std::mem; + use winapi::shared::minwindef::DWORD; + use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE}; + use winapi::um::processthreadsapi::GetCurrentProcessId; + use winapi::um::tlhelp32::{ + CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, + TH32CS_SNAPPROCESS, + }; + unsafe { + // Take a snapshot of system processes, one of which is ours + // and contains our parent's pid + let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if snapshot == INVALID_HANDLE_VALUE { + return serde_json::to_value(-1).unwrap(); + } + + let mut entry: PROCESSENTRY32 = mem::zeroed(); + entry.dwSize = mem::size_of::<PROCESSENTRY32>() as DWORD; + + // Iterate over system processes looking for ours + let success = Process32First(snapshot, &mut entry); + if success == 0 { + CloseHandle(snapshot); + return serde_json::to_value(-1).unwrap(); + } + + let this_pid = GetCurrentProcessId(); + while entry.th32ProcessID != this_pid { + let success = Process32Next(snapshot, &mut entry); + if success == 0 { + CloseHandle(snapshot); + return serde_json::to_value(-1).unwrap(); + } + } + CloseHandle(snapshot); + + // FIXME: Using the process ID exposes a race condition + // wherein the parent process already exited and the OS + // reassigned its ID. + let parent_id = entry.th32ParentProcessID; + serde_json::to_value(parent_id).unwrap() + } + } + #[cfg(not(windows))] + { + use std::os::unix::process::parent_id; + serde_json::to_value(parent_id()).unwrap() + } +} |