diff options
Diffstat (limited to 'runtime/ops/os.rs')
-rw-r--r-- | runtime/ops/os.rs | 145 |
1 files changed, 76 insertions, 69 deletions
diff --git a/runtime/ops/os.rs b/runtime/ops/os.rs index 500c023aa..3e6feacfe 100644 --- a/runtime/ops/os.rs +++ b/runtime/ops/os.rs @@ -1,13 +1,12 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use crate::permissions::Permissions; -use deno_core::error::{type_error, AnyError}; -use deno_core::serde_json::json; -use deno_core::serde_json::Value; +use deno_core::error::{custom_error, type_error, AnyError}; use deno_core::url::Url; use deno_core::OpState; use deno_core::ZeroCopyBuf; use serde::Deserialize; +use serde::Serialize; use std::collections::HashMap; use std::env; @@ -27,9 +26,9 @@ pub fn init(rt: &mut deno_core::JsRuntime) { fn op_exec_path( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<String, AnyError> { let current_exe = env::current_exe().unwrap(); state .borrow::<Permissions>() @@ -39,7 +38,16 @@ fn op_exec_path( // we might get `./` and `../` bits in `exec_path` let exe_url = Url::from_file_path(current_exe).unwrap(); let path = exe_url.to_file_path().unwrap(); - Ok(json!(path)) + + into_string(path.into_os_string()) +} + +// TODO(@AaronO): share this code with fs' into_string() +fn into_string(s: std::ffi::OsString) -> Result<String, AnyError> { + s.into_string().map_err(|s| { + let message = format!("File name or path {:?} is not valid UTF-8", s); + custom_error("InvalidData", message) + }) } #[derive(Deserialize)] @@ -52,7 +60,7 @@ fn op_set_env( state: &mut OpState, args: SetEnv, _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<(), AnyError> { state.borrow::<Permissions>().env.check()?; let invalid_key = args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]); @@ -61,140 +69,139 @@ fn op_set_env( return Err(type_error("Key or value contains invalid characters.")); } env::set_var(args.key, args.value); - Ok(json!({})) + Ok(()) } fn op_env( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<HashMap<String, String>, AnyError> { state.borrow::<Permissions>().env.check()?; - let v = env::vars().collect::<HashMap<String, String>>(); - Ok(json!(v)) -} - -#[derive(Deserialize)] -pub struct GetEnv { - key: String, + Ok(env::vars().collect()) } fn op_get_env( state: &mut OpState, - args: GetEnv, + key: String, _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<Option<String>, AnyError> { state.borrow::<Permissions>().env.check()?; - if args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]) { + if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { return Err(type_error("Key contains invalid characters.")); } - let r = match env::var(args.key) { - Err(env::VarError::NotPresent) => json!([]), - v => json!([v?]), + let r = match env::var(key) { + Err(env::VarError::NotPresent) => None, + v => Some(v?), }; Ok(r) } - -#[derive(Deserialize)] -pub struct DeleteEnv { - key: String, -} - fn op_delete_env( state: &mut OpState, - args: DeleteEnv, + key: String, _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<(), AnyError> { state.borrow::<Permissions>().env.check()?; - if args.key.is_empty() || args.key.contains(&['=', '\0'] as &[char]) { + if key.is_empty() || key.contains(&['=', '\0'] as &[char]) { return Err(type_error("Key contains invalid characters.")); } - env::remove_var(args.key); - Ok(json!({})) -} - -#[derive(Deserialize)] -pub struct Exit { - code: i32, + env::remove_var(key); + Ok(()) } fn op_exit( _state: &mut OpState, - args: Exit, + code: i32, _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { - std::process::exit(args.code) +) -> Result<(), AnyError> { + std::process::exit(code) } fn op_loadavg( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<(f64, f64, f64), AnyError> { super::check_unstable(state, "Deno.loadavg"); state.borrow::<Permissions>().env.check()?; match sys_info::loadavg() { - Ok(loadavg) => Ok(json!([loadavg.one, loadavg.five, loadavg.fifteen])), - Err(_) => Ok(json!([0f64, 0f64, 0f64])), + Ok(loadavg) => Ok((loadavg.one, loadavg.five, loadavg.fifteen)), + Err(_) => Ok((0.0, 0.0, 0.0)), } } fn op_hostname( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<String, AnyError> { super::check_unstable(state, "Deno.hostname"); state.borrow::<Permissions>().env.check()?; let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string()); - Ok(json!(hostname)) + Ok(hostname) } fn op_os_release( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<String, AnyError> { super::check_unstable(state, "Deno.osRelease"); state.borrow::<Permissions>().env.check()?; let release = sys_info::os_release().unwrap_or_else(|_| "".to_string()); - Ok(json!(release)) + Ok(release) +} + +// Copied from sys-info/lib.rs (then tweaked) +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct MemInfo { + pub total: u64, + pub free: u64, + pub available: u64, + pub buffers: u64, + pub cached: u64, + pub swap_total: u64, + pub swap_free: u64, } fn op_system_memory_info( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<Option<MemInfo>, AnyError> { super::check_unstable(state, "Deno.systemMemoryInfo"); state.borrow::<Permissions>().env.check()?; match sys_info::mem_info() { - Ok(info) => Ok(json!({ - "total": info.total, - "free": info.free, - "available": info.avail, - "buffers": info.buffers, - "cached": info.cached, - "swapTotal": info.swap_total, - "swapFree": info.swap_free + Ok(info) => Ok(Some(MemInfo { + total: info.total, + free: info.free, + available: info.avail, + buffers: info.buffers, + cached: info.cached, + swap_total: info.swap_total, + swap_free: info.swap_free, })), - Err(_) => Ok(json!({})), + Err(_) => Ok(None), } } +#[derive(Serialize)] +struct CpuInfo { + cores: Option<u32>, + speed: Option<u64>, +} + fn op_system_cpu_info( state: &mut OpState, - _args: Value, + _args: (), _zero_copy: Option<ZeroCopyBuf>, -) -> Result<Value, AnyError> { +) -> Result<CpuInfo, AnyError> { super::check_unstable(state, "Deno.systemCpuInfo"); state.borrow::<Permissions>().env.check()?; let cores = sys_info::cpu_num().ok(); let speed = sys_info::cpu_speed().ok(); - Ok(json!({ - "cores": cores, - "speed": speed - })) + Ok(CpuInfo { cores, speed }) } |