summaryrefslogtreecommitdiff
path: root/runtime/ops/runtime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/runtime.rs')
-rw-r--r--runtime/ops/runtime.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/runtime/ops/runtime.rs b/runtime/ops/runtime.rs
new file mode 100644
index 000000000..cb3b53d53
--- /dev/null
+++ b/runtime/ops/runtime.rs
@@ -0,0 +1,118 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+use crate::metrics::Metrics;
+use crate::permissions::Permissions;
+use deno_core::error::AnyError;
+use deno_core::serde_json;
+use deno_core::serde_json::json;
+use deno_core::serde_json::Value;
+use deno_core::ModuleSpecifier;
+use deno_core::OpState;
+use deno_core::ZeroCopyBuf;
+
+pub fn init(rt: &mut deno_core::JsRuntime, main_module: ModuleSpecifier) {
+ {
+ let op_state = rt.op_state();
+ let mut state = op_state.borrow_mut();
+ state.put::<ModuleSpecifier>(main_module);
+ }
+ super::reg_json_sync(rt, "op_main_module", op_main_module);
+ super::reg_json_sync(rt, "op_metrics", op_metrics);
+}
+
+fn op_main_module(
+ state: &mut OpState,
+ _args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result<Value, AnyError> {
+ let main = state.borrow::<ModuleSpecifier>().to_string();
+ let main_url = ModuleSpecifier::resolve_url_or_path(&main)?;
+ if main_url.as_url().scheme() == "file" {
+ let main_path = std::env::current_dir().unwrap().join(main_url.to_string());
+ state
+ .borrow::<Permissions>()
+ .check_read_blind(&main_path, "main_module")?;
+ }
+ Ok(json!(&main))
+}
+
+fn op_metrics(
+ state: &mut OpState,
+ _args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result<Value, AnyError> {
+ let m = state.borrow::<Metrics>();
+
+ Ok(json!({
+ "opsDispatched": m.ops_dispatched,
+ "opsDispatchedSync": m.ops_dispatched_sync,
+ "opsDispatchedAsync": m.ops_dispatched_async,
+ "opsDispatchedAsyncUnref": m.ops_dispatched_async_unref,
+ "opsCompleted": m.ops_completed,
+ "opsCompletedSync": m.ops_completed_sync,
+ "opsCompletedAsync": m.ops_completed_async,
+ "opsCompletedAsyncUnref": m.ops_completed_async_unref,
+ "bytesSentControl": m.bytes_sent_control,
+ "bytesSentData": m.bytes_sent_data,
+ "bytesReceived": m.bytes_received
+ }))
+}
+
+pub 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()
+ }
+}