From cece9e1ad6af42a5e9e6ab080c67ae215c1777a6 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 5 Jun 2023 13:02:25 +0200 Subject: [PATCH 01/17] feat(node/os): implement getPriority, setPriority & userInfo --- Cargo.lock | 52 +++++++++++++ ext/node/Cargo.toml | 3 + ext/node/lib.rs | 3 + ext/node/ops/mod.rs | 1 + ext/node/ops/os.rs | 159 +++++++++++++++++++++++++++++++++++++++ ext/node/polyfills/os.ts | 38 ++++++++-- 6 files changed, 250 insertions(+), 6 deletions(-) create mode 100644 ext/node/ops/os.rs diff --git a/Cargo.lock b/Cargo.lock index 07ca3b10fc7f62..1fcc70d8cb06f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1176,6 +1176,7 @@ dependencies = [ "deno_npm", "deno_semver", "digest 0.10.6", + "dirs", "dsa", "ecb", "elliptic-curve 0.13.4", @@ -1184,6 +1185,7 @@ dependencies = [ "idna 0.3.0", "indexmap", "lazy-regex", + "libc", "libz-sys", "md-5", "md4", @@ -1212,6 +1214,8 @@ dependencies = [ "signature 1.6.4", "tokio", "typenum", + "whoami", + "winapi", "x25519-dalek", "x509-parser", ] @@ -1497,6 +1501,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "displaydoc" version = "0.2.3" @@ -3188,6 +3213,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-float" version = "2.10.0" @@ -3766,6 +3797,17 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.8", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.7.1" @@ -5913,6 +5955,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "whoami" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "widestring" version = "0.5.1" diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 0efb27aeaa4e3f..0e4b4a0682544d 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -32,6 +32,7 @@ hkdf.workspace = true idna = "0.3.0" indexmap.workspace = true lazy-regex.workspace = true +libc.workspace = true libz-sys = { version = "1.1.8", features = ["static"] } md-5 = "0.10.5" md4 = "0.10.2" @@ -60,6 +61,8 @@ sha3 = "0.10.5" signature.workspace = true tokio.workspace = true typenum = "1.15.0" +whoami = "1.4.0" +winapi.workspace = true # https://github.com/dalek-cryptography/x25519-dalek/pull/89 x25519-dalek = "2.0.0-pre.1" x509-parser = "0.15.0" diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 6ac64eb2ebfc6d..1aae10bf9077ac 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -219,6 +219,9 @@ deno_core::extension!(deno_node, ops::zlib::op_zlib_init, ops::zlib::op_zlib_reset, ops::http::op_node_http_request

, + ops::os::op_node_os_get_priority, + ops::os::op_node_os_set_priority, + ops::os::op_node_os_username, op_node_build_os, ops::require::op_require_init_paths, ops::require::op_require_node_module_paths

, diff --git a/ext/node/ops/mod.rs b/ext/node/ops/mod.rs index 2bbf02d34312b3..22ad546e89c465 100644 --- a/ext/node/ops/mod.rs +++ b/ext/node/ops/mod.rs @@ -3,6 +3,7 @@ pub mod crypto; pub mod http; pub mod idna; +pub mod os; pub mod require; pub mod v8; pub mod winerror; diff --git a/ext/node/ops/os.rs b/ext/node/ops/os.rs new file mode 100644 index 00000000000000..3bd7d54eabc101 --- /dev/null +++ b/ext/node/ops/os.rs @@ -0,0 +1,159 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::custom_error; +use deno_core::error::type_error; +use deno_core::error::AnyError; +use deno_core::op; + +#[op] +pub fn op_node_os_get_priority(pid: u32) -> Result { + get_priority(pid) +} + +#[op] +pub fn op_node_os_set_priority( + pid: u32, + priority: i32, +) -> Result<(), AnyError> { + set_priority(pid, priority) +} + +#[op] +pub fn op_node_os_username() -> Result { + Ok(whoami::username()) +} + +fn path_into_string(s: std::ffi::OsString) -> Result { + s.into_string().map_err(|s| { + let message = format!("File name or path {s:?} is not valid UTF-8"); + custom_error("InvalidData", message) + }) +} + +#[cfg(unix)] +use libc::id_t; +#[cfg(unix)] +use libc::PRIO_PROCESS; +#[cfg(windows)] +use winapi::shared::minwindef::DWORD; +#[cfg(windows)] +use winapi::shared::minwindef::FALSE; +#[cfg(windows)] +use winapi::shared::ntdef::NULL; +#[cfg(windows)] +use winapi::um::handleapi::CloseHandle; +#[cfg(windows)] +use winapi::um::processthreadsapi::GetCurrentProcess; +#[cfg(windows)] +use winapi::um::processthreadsapi::GetPriorityClass; +#[cfg(windows)] +use winapi::um::processthreadsapi::OpenProcess; +#[cfg(windows)] +use winapi::um::processthreadsapi::SetPriorityClass; +#[cfg(windows)] +use winapi::um::winbase::ABOVE_NORMAL_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winbase::BELOW_NORMAL_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winbase::HIGH_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winbase::IDLE_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winbase::NORMAL_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winbase::REALTIME_PRIORITY_CLASS; +#[cfg(windows)] +use winapi::um::winnt::PROCESS_QUERY_LIMITED_INFORMATION; +#[cfg(target_os = "macos")] +#[allow(non_camel_case_types)] +type priority_t = i32; +#[cfg(target_os = "linux")] +#[allow(non_camel_case_types)] +type priority_t = u32; + +pub const PRIORITY_LOW: i32 = 19; +pub const PRIORITY_BELOW_NORMAL: i32 = 10; +pub const PRIORITY_NORMAL: i32 = 0; +pub const PRIORITY_ABOVE_NORMAL: i32 = -7; +pub const PRIORITY_HIGH: i32 = -14; +pub const PRIORITY_HIGHEST: i32 = -20; + +#[cfg(unix)] +pub fn get_priority(pid: u32) -> Result { + set_errno(Errno(0)); + match (unsafe { libc::getpriority(PRIO_PROCESS, pid) }, errno()) { + (-1, Errno(0)) => Ok(PRIORITY_HIGH), + (-1, _) => Err(std::io::Error::last_os_error().into()), + (priority, _) => Ok(priority), + } +} + +#[cfg(unix)] +pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { + match unsafe { libc::setpriority(PRIO_PROCESS, pid, priority) } { + -1 => Err(std::io::Error::last_os_error().into()), + _ => Ok(()), + } +} + +#[cfg(windows)] +pub fn get_priority(pid: u32) -> Result { + unsafe { + let handle = if pid == 0 { + GetCurrentProcess() + } else { + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) + }; + if handle == NULL { + Err(std::io::Error::last_os_error().into()) + } else { + let result = match GetPriorityClass(handle) { + 0 => Err(std::io::Error::last_os_error().into()), + REALTIME_PRIORITY_CLASS => Ok(PRIORITY_HIGHEST), + HIGH_PRIORITY_CLASS => Ok(PRIORITY_HIGH), + ABOVE_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_ABOVE_NORMAL), + NORMAL_PRIORITY_CLASS => Ok(PRIORITY_NORMAL), + BELOW_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_BELOW_NORMAL), + IDLE_PRIORITY_CLASS => Ok(PRIORITY_LOW), + _ => Ok(PRIORITY_LOW), + }; + CloseHandle(handle); + result + } + } +} + +#[cfg(windows)] +pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { + unsafe { + let handle = if pid == 0 { + GetCurrentProcess() + } else { + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) + }; + if handle == NULL { + Err(std::io::Error::last_os_error().into()) + } else { + let prio_class = match priority { + p if p <= PRIORITY_HIGHEST => REALTIME_PRIORITY_CLASS, + p if PRIORITY_HIGHEST < p && p <= PRIORITY_HIGH => HIGH_PRIORITY_CLASS, + p if PRIORITY_HIGH < p && p <= PRIORITY_ABOVE_NORMAL => { + ABOVE_NORMAL_PRIORITY_CLASS + } + p if PRIORITY_ABOVE_NORMAL < p && p <= PRIORITY_NORMAL => { + NORMAL_PRIORITY_CLASS + } + p if PRIORITY_NORMAL < p && p <= PRIORITY_BELOW_NORMAL => { + BELOW_NORMAL_PRIORITY_CLASS + } + _ => IDLE_PRIORITY_CLASS, + }; + let result = match SetPriorityClass(handle, prio_class) { + FALSE => Err(std::io::Error::last_os_error().into()), + _ => Ok(()), + }; + CloseHandle(handle); + result + } + } +} diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 19e8fd15522cf1..4f0697f8c5b07f 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -20,12 +20,14 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -import { notImplemented } from "ext:deno_node/_utils.ts"; +const core = globalThis.__bootstrap.core; import { validateIntegerRange } from "ext:deno_node/_utils.ts"; import process from "ext:deno_node/process.ts"; import { isWindows, osType } from "ext:deno_node/_util/os.ts"; import { os } from "ext:deno_node/internal_binding/constants.ts"; import { osUptime } from "ext:runtime/30_os.js"; +import { Buffer } from "ext:deno_node/buffer.ts"; + export const constants = os; const SEE_GITHUB_ISSUE = "See https://github.com/denoland/deno_std/issues/1436"; @@ -90,8 +92,8 @@ interface UserInfo { username: string; uid: number; gid: number; - shell: string; - homedir: string; + shell: string | null; + homedir: string | null; } export function arch(): string { @@ -158,7 +160,7 @@ export function freemem(): number { /** Not yet implemented */ export function getPriority(pid = 0): number { validateIntegerRange(pid, "pid"); - notImplemented(SEE_GITHUB_ISSUE); + return core.ops.op_node_os_get_priority(pid); } /** Returns the string path of the current user's home directory. */ @@ -253,7 +255,7 @@ export function setPriority(pid: number, priority?: number) { validateIntegerRange(pid, "pid"); validateIntegerRange(priority, "priority", -20, 19); - notImplemented(SEE_GITHUB_ISSUE); + core.ops.op_node_os_set_priority(pid, priority); } /** Returns the operating system's default directory for temporary files as a string. */ @@ -314,7 +316,31 @@ export function userInfo( // deno-lint-ignore no-unused-vars options: UserInfoOptions = { encoding: "utf-8" }, ): UserInfo { - notImplemented(SEE_GITHUB_ISSUE); + const uid = Deno.uid(); + const gid = Deno.gid(); + + if (isWindows) { + uid = -1; + gid = -1; + } + + let _homedir = homedir(); + let shell = isWindows ? (Deno.env.get("SHELL") || null) : null; + let username = core.ops.op_node_os_username(); + + if (options?.encoding === "buffer") { + _homedir = _homedir ? Buffer.from(_homedir) : _homedir; + shell = shell ? Buffer.from(shell) : shell; + username = Buffer.from(username); + } + + return { + uid, + gid, + homedir: _homedir, + shell, + username, + }; } export const EOL = isWindows ? "\r\n" : "\n"; From f75234a763a066be283be9a0e24b68e03176be28 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 12 Jun 2023 10:21:12 +0200 Subject: [PATCH 02/17] lint --- ext/node/polyfills/os.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 4f0697f8c5b07f..ae6a95da9cb207 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -30,8 +30,6 @@ import { Buffer } from "ext:deno_node/buffer.ts"; export const constants = os; -const SEE_GITHUB_ISSUE = "See https://github.com/denoland/deno_std/issues/1436"; - interface CPUTimes { /** The number of milliseconds the CPU has spent in user mode */ user: number; @@ -313,7 +311,6 @@ export function uptime(): number { /** Not yet implemented */ export function userInfo( - // deno-lint-ignore no-unused-vars options: UserInfoOptions = { encoding: "utf-8" }, ): UserInfo { const uid = Deno.uid(); From 4660c033b21cfd9e4b13e9fb8b1a980f393dc2c2 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 12 Jun 2023 10:31:20 +0200 Subject: [PATCH 03/17] update lock --- Cargo.lock | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1fcc70d8cb06f0..418a2237a28faf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1176,7 +1176,6 @@ dependencies = [ "deno_npm", "deno_semver", "digest 0.10.6", - "dirs", "dsa", "ecb", "elliptic-curve 0.13.4", @@ -1501,27 +1500,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - [[package]] name = "displaydoc" version = "0.2.3" @@ -3213,12 +3191,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "ordered-float" version = "2.10.0" @@ -3797,17 +3769,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom 0.2.8", - "redox_syscall", - "thiserror", -] - [[package]] name = "regex" version = "1.7.1" From be42bc9c9b1efca77e6a07946b5b2e2e59d2a7b9 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 12 Jun 2023 16:56:56 +0200 Subject: [PATCH 04/17] fix & add permissions --- Cargo.lock | 16 +++++++-- ext/node/Cargo.toml | 1 + ext/node/lib.rs | 10 ++++-- ext/node/ops/os.rs | 67 +++++++++++++++++++++++++++++--------- runtime/build.rs | 7 ++++ runtime/permissions/mod.rs | 4 +++ 6 files changed, 85 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 418a2237a28faf..8ea9f8e3279e8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1179,6 +1179,7 @@ dependencies = [ "dsa", "ecb", "elliptic-curve 0.13.4", + "errno 0.3.1", "hex", "hkdf", "idna 0.3.0", @@ -1798,6 +1799,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -3666,7 +3678,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4461e7f96399674b9112e620e511089bc7c4c0d76545b3cc3e0b46bab72a15d5" dependencies = [ - "errno", + "errno 0.2.8", "libc", ] @@ -3965,7 +3977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ "bitflags 1.3.2", - "errno", + "errno 0.2.8", "io-lifetimes", "libc", "linux-raw-sys", diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index 0e4b4a0682544d..467237dc8de1dd 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -27,6 +27,7 @@ digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true elliptic-curve.workspace = true +errno = "0.3.1" hex.workspace = true hkdf.workspace = true idna = "0.3.0" diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 1aae10bf9077ac..043840f2a716cd 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -47,6 +47,7 @@ pub trait NodePermissions { api_name: &str, ) -> Result<(), AnyError>; fn check_read(&self, path: &Path) -> Result<(), AnyError>; + fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError>; } pub(crate) struct AllowAllNodePermissions; @@ -62,6 +63,9 @@ impl NodePermissions for AllowAllNodePermissions { fn check_read(&self, _path: &Path) -> Result<(), AnyError> { Ok(()) } + fn check_sys(&self, _kind: &str, _api_name: &str) -> Result<(), AnyError> { + Ok(()) + } } #[allow(clippy::disallowed_types)] @@ -219,9 +223,9 @@ deno_core::extension!(deno_node, ops::zlib::op_zlib_init, ops::zlib::op_zlib_reset, ops::http::op_node_http_request

, - ops::os::op_node_os_get_priority, - ops::os::op_node_os_set_priority, - ops::os::op_node_os_username, + ops::os::op_node_os_get_priority

, + ops::os::op_node_os_set_priority

, + ops::os::op_node_os_username

, op_node_build_os, ops::require::op_require_init_paths, ops::require::op_require_node_module_paths

, diff --git a/ext/node/ops/os.rs b/ext/node/ops/os.rs index 3bd7d54eabc101..94642019a4b281 100644 --- a/ext/node/ops/os.rs +++ b/ext/node/ops/os.rs @@ -1,35 +1,59 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -use deno_core::error::custom_error; -use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; +use deno_core::OpState; +use errno::errno; +use errno::set_errno; +use errno::Errno; #[op] -pub fn op_node_os_get_priority(pid: u32) -> Result { +pub fn op_node_os_get_priority

( + state: &mut OpState, + pid: u32, +) -> Result +where + P: NodePermissions + 'static, +{ + { + let permissions = state.borrow_mut::

(); + permissions.check_sys("getPriority", "node:os.getPriority()")?; + } + get_priority(pid) } #[op] -pub fn op_node_os_set_priority( +pub fn op_node_os_set_priority

( + state: &mut OpState, pid: u32, priority: i32, -) -> Result<(), AnyError> { +) -> Result<(), AnyError> +where + P: NodePermissions + 'static, +{ + { + let permissions = state.borrow_mut::

(); + permissions.check_sys("setPriority", "node:os.setPriority()")?; + } + set_priority(pid, priority) } #[op] -pub fn op_node_os_username() -> Result { - Ok(whoami::username()) -} +pub fn op_node_os_username

(state: &mut OpState) -> Result +where + P: NodePermissions + 'static, +{ + { + let permissions = state.borrow_mut::

(); + permissions.check_sys("userInfo", "node:os.userInfo()")?; + } -fn path_into_string(s: std::ffi::OsString) -> Result { - s.into_string().map_err(|s| { - let message = format!("File name or path {s:?} is not valid UTF-8"); - custom_error("InvalidData", message) - }) + Ok(whoami::username()) } +use crate::NodePermissions; #[cfg(unix)] use libc::id_t; #[cfg(unix)] @@ -64,6 +88,7 @@ use winapi::um::winbase::NORMAL_PRIORITY_CLASS; use winapi::um::winbase::REALTIME_PRIORITY_CLASS; #[cfg(windows)] use winapi::um::winnt::PROCESS_QUERY_LIMITED_INFORMATION; + #[cfg(target_os = "macos")] #[allow(non_camel_case_types)] type priority_t = i32; @@ -71,17 +96,26 @@ type priority_t = i32; #[allow(non_camel_case_types)] type priority_t = u32; +#[cfg(windows)] pub const PRIORITY_LOW: i32 = 19; +#[cfg(windows)] pub const PRIORITY_BELOW_NORMAL: i32 = 10; +#[cfg(windows)] pub const PRIORITY_NORMAL: i32 = 0; +#[cfg(windows)] pub const PRIORITY_ABOVE_NORMAL: i32 = -7; pub const PRIORITY_HIGH: i32 = -14; +#[cfg(windows)] pub const PRIORITY_HIGHEST: i32 = -20; #[cfg(unix)] pub fn get_priority(pid: u32) -> Result { set_errno(Errno(0)); - match (unsafe { libc::getpriority(PRIO_PROCESS, pid) }, errno()) { + match ( + // SAFETY: libc::getpriority is unsafe + unsafe { libc::getpriority(PRIO_PROCESS as priority_t, pid as id_t) }, + errno(), + ) { (-1, Errno(0)) => Ok(PRIORITY_HIGH), (-1, _) => Err(std::io::Error::last_os_error().into()), (priority, _) => Ok(priority), @@ -90,7 +124,10 @@ pub fn get_priority(pid: u32) -> Result { #[cfg(unix)] pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { - match unsafe { libc::setpriority(PRIO_PROCESS, pid, priority) } { + match unsafe { + // SAFETY: libc::setpriority is unsafe + libc::setpriority(PRIO_PROCESS as priority_t, pid as id_t, priority) + } { -1 => Err(std::io::Error::last_os_error().into()), _ => Ok(()), } diff --git a/runtime/build.rs b/runtime/build.rs index f656682a1d239e..635190f989dd51 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -132,6 +132,13 @@ mod startup_snapshot { fn check_read(&self, _p: &Path) -> Result<(), deno_core::error::AnyError> { unreachable!("snapshotting!") } + fn check_sys( + &self, + _kind: &str, + _api_name: &str, + ) -> Result<(), deno_core::error::AnyError> { + unreachable!("snapshotting!") + } } impl deno_net::NetPermissions for Permissions { diff --git a/runtime/permissions/mod.rs b/runtime/permissions/mod.rs index f1d0362cad5125..8c66e459874ce7 100644 --- a/runtime/permissions/mod.rs +++ b/runtime/permissions/mod.rs @@ -1885,6 +1885,10 @@ impl deno_node::NodePermissions for PermissionsContainer { fn check_read(&self, path: &Path) -> Result<(), AnyError> { self.0.lock().read.check(path, None) } + + fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> { + self.0.lock().sys.check(kind, Some(api_name)) + } } impl deno_net::NetPermissions for PermissionsContainer { From 380f8bdd06f3bdaf06aa91820538165206b8f0f6 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Tue, 13 Jun 2023 02:43:13 +0200 Subject: [PATCH 05/17] fix safety comment --- ext/node/ops/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/node/ops/os.rs b/ext/node/ops/os.rs index 94642019a4b281..90bf1d16694977 100644 --- a/ext/node/ops/os.rs +++ b/ext/node/ops/os.rs @@ -124,8 +124,8 @@ pub fn get_priority(pid: u32) -> Result { #[cfg(unix)] pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { + // SAFETY: libc::setpriority is unsafe match unsafe { - // SAFETY: libc::setpriority is unsafe libc::setpriority(PRIO_PROCESS as priority_t, pid as id_t, priority) } { -1 => Err(std::io::Error::last_os_error().into()), From b8ef1230a4714679997b6c303b96e536570c683a Mon Sep 17 00:00:00 2001 From: crowlkats Date: Tue, 13 Jun 2023 03:22:08 +0200 Subject: [PATCH 06/17] dedupe errno --- Cargo.lock | 17 +++-------------- ext/node/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ff0f1770efd78..45cd5bafccb30f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1255,7 +1255,7 @@ dependencies = [ "dsa", "ecb", "elliptic-curve 0.13.4", - "errno 0.3.1", + "errno", "hex", "hkdf", "idna 0.3.0", @@ -1877,17 +1877,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -3745,7 +3734,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4461e7f96399674b9112e620e511089bc7c4c0d76545b3cc3e0b46bab72a15d5" dependencies = [ - "errno 0.2.8", + "errno", "libc", ] @@ -4044,7 +4033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ "bitflags 1.3.2", - "errno 0.2.8", + "errno", "io-lifetimes", "libc", "linux-raw-sys", diff --git a/ext/node/Cargo.toml b/ext/node/Cargo.toml index bcf3d7306a8f1a..d92b839e49a781 100644 --- a/ext/node/Cargo.toml +++ b/ext/node/Cargo.toml @@ -27,7 +27,7 @@ digest = { version = "0.10.5", features = ["core-api", "std"] } dsa = "0.6.1" ecb.workspace = true elliptic-curve.workspace = true -errno = "0.3.1" +errno = "0.2.8" hex.workspace = true hkdf.workspace = true idna = "0.3.0" From 349fe5ba8aaff3100692baf9d17e4f572b204a66 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Tue, 13 Jun 2023 04:25:45 +0200 Subject: [PATCH 07/17] add priority test --- cli/tests/unit_node/os_test.ts | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/cli/tests/unit_node/os_test.ts b/cli/tests/unit_node/os_test.ts index 85164d1e60d349..04e1d678cd64b2 100644 --- a/cli/tests/unit_node/os_test.ts +++ b/cli/tests/unit_node/os_test.ts @@ -5,6 +5,7 @@ import os from "node:os"; import { assert, assertEquals, + assertNotEquals, assertThrows, } from "../../../test_util/std/testing/asserts.ts"; @@ -252,28 +253,13 @@ Deno.test({ }); Deno.test({ - name: "APIs not yet implemented", + name: "os.setPriority() & os.getPriority()", fn() { - assertThrows( - () => { - os.getPriority(); - }, - Error, - "Not implemented", - ); - assertThrows( - () => { - os.setPriority(0); - }, - Error, - "Not implemented", - ); - assertThrows( - () => { - os.userInfo(); - }, - Error, - "Not implemented", - ); + const originalPriority = os.getPriority(); + assertNotEquals(originalPriority, os.constants.priority.PRIORITY_HIGH); + os.setPriority(os.constants.priority.PRIORITY_HIGH); + assertEquals(os.getPriority(), os.constants.priority.PRIORITY_HIGH); + os.setPriority(originalPriority); + assertEquals(os.getPriority(), originalPriority); }, }); From cc1fc05e559f867f08d3a35a7ed5a847fe55281a Mon Sep 17 00:00:00 2001 From: crowlkats Date: Tue, 13 Jun 2023 15:36:13 +0200 Subject: [PATCH 08/17] disable test and add error test --- cli/tests/unit_node/os_test.ts | 38 +++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/cli/tests/unit_node/os_test.ts b/cli/tests/unit_node/os_test.ts index 04e1d678cd64b2..484c0dfef81e9e 100644 --- a/cli/tests/unit_node/os_test.ts +++ b/cli/tests/unit_node/os_test.ts @@ -254,12 +254,40 @@ Deno.test({ Deno.test({ name: "os.setPriority() & os.getPriority()", + // disabled because os.getPriority() doesn't work without sudo + ignore: true, fn() { - const originalPriority = os.getPriority(); + const child = new Deno.Command(Deno.execPath(), { + args: ["eval", "while (true) { console.log('foo') }"], + }).spawn(); + const originalPriority = os.getPriority(child.pid); assertNotEquals(originalPriority, os.constants.priority.PRIORITY_HIGH); - os.setPriority(os.constants.priority.PRIORITY_HIGH); - assertEquals(os.getPriority(), os.constants.priority.PRIORITY_HIGH); - os.setPriority(originalPriority); - assertEquals(os.getPriority(), originalPriority); + os.setPriority(child.pid, os.constants.priority.PRIORITY_HIGH); + assertEquals( + os.getPriority(child.pid), + os.constants.priority.PRIORITY_HIGH, + ); + os.setPriority(child.pid, originalPriority); + assertEquals(os.getPriority(child.pid), originalPriority); + child.kill(); + }, +}); + +Deno.test({ + name: + "os.setPriority() throw os permission denied error & os.getPriority() doesn't", + fn() { + const child = new Deno.Command(Deno.execPath(), { + args: ["eval", "while (true) { console.log('foo') }"], + }).spawn(); + assertThrows( + () => os.setPriority(child.pid, os.constants.priority.PRIORITY_HIGH), + Deno.errors.PermissionDenied, + ); + assertEquals( + os.getPriority(child.pid), + os.constants.priority.PRIORITY_NORMAL, + ); + child.kill(); }, }); From d83ba4ceac97dc9530660dc571509089347aa671 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Wed, 14 Jun 2023 16:30:08 +0200 Subject: [PATCH 09/17] fix test --- cli/tests/integration/shared_library_tests.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/tests/integration/shared_library_tests.rs b/cli/tests/integration/shared_library_tests.rs index 531fdd5169c3d8..641deab4c1545b 100644 --- a/cli/tests/integration/shared_library_tests.rs +++ b/cli/tests/integration/shared_library_tests.rs @@ -45,12 +45,14 @@ fn macos_shared_libraries() { // target/release/deno: // /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1953.255.0) // /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1228.0.0) + // /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration (compatibility version 1.0.0, current version 1241.100.11) // /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 60420.60.24) // /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0) // /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0) - const EXPECTED: [&str; 6] = + const EXPECTED: [&str; 7] = ["/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation", "/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices", + "/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration", "/System/Library/Frameworks/Security.framework/Versions/A/Security", "/usr/lib/libiconv.2.dylib", "/usr/lib/libSystem.B.dylib", From 2e8273f2b4a4459217a04b76bd7b69e3a1bee904 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Wed, 14 Jun 2023 17:09:12 +0200 Subject: [PATCH 10/17] adjust test --- cli/tests/unit_node/os_test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cli/tests/unit_node/os_test.ts b/cli/tests/unit_node/os_test.ts index 484c0dfef81e9e..65857b63dd38ae 100644 --- a/cli/tests/unit_node/os_test.ts +++ b/cli/tests/unit_node/os_test.ts @@ -284,10 +284,7 @@ Deno.test({ () => os.setPriority(child.pid, os.constants.priority.PRIORITY_HIGH), Deno.errors.PermissionDenied, ); - assertEquals( - os.getPriority(child.pid), - os.constants.priority.PRIORITY_NORMAL, - ); + os.getPriority(child.pid); child.kill(); }, }); From 17a240eeee537dcd698b9d2512d02ec7537d7f15 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Wed, 14 Jun 2023 19:14:19 +0200 Subject: [PATCH 11/17] throw on no homedir --- ext/node/polyfills/internal/errors.ts | 13 +++++++++++++ ext/node/polyfills/os.ts | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/ext/node/polyfills/internal/errors.ts b/ext/node/polyfills/internal/errors.ts index 5e6b9378c6b4cc..c0a9b1658a8329 100644 --- a/ext/node/polyfills/internal/errors.ts +++ b/ext/node/polyfills/internal/errors.ts @@ -2493,6 +2493,19 @@ export class ERR_FS_RMDIR_ENOTDIR extends NodeSystemError { } } +export class ERR_OS_NO_HOMEDIR extends NodeSystemError { + constructor() { + const code = isWindows ? "ENOENT" : "ENOTDIR"; + const ctx: NodeSystemErrorCtx = { + message: "not a directory", + syscall: "home", + code, + errno: isWindows ? osConstants.errno.ENOENT : osConstants.errno.ENOTDIR, + }; + super(code, ctx, "Path is not a directory"); + } +} + interface UvExceptionContext { syscall: string; path?: string; diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 1e05f8ab27c206..c47db4e5696750 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -20,10 +20,12 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. + const core = globalThis.__bootstrap.core; import { validateIntegerRange } from "ext:deno_node/_utils.ts"; import process from "ext:deno_node/process.ts"; import { isWindows, osType } from "ext:deno_node/_util/os.ts"; +import { ERR_OS_NO_HOMEDIR } from "ext:deno_node/internal/errors.ts"; import { os } from "ext:deno_node/internal_binding/constants.ts"; import { osUptime } from "ext:runtime/30_os.js"; import { Buffer } from "ext:deno_node/buffer.ts"; @@ -325,6 +327,9 @@ export function userInfo( } let _homedir = homedir(); + if (!_homedir) { + throw new ERR_OS_NO_HOMEDIR(); + } let shell = isWindows ? (Deno.env.get("SHELL") || null) : null; let username = core.ops.op_node_os_username(); From cc3ea289c940d65f7c8853a034f4cc785267e3d7 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Wed, 14 Jun 2023 19:28:05 +0200 Subject: [PATCH 12/17] fmt --- ext/node/polyfills/os.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index c47db4e5696750..02ad11af9139fc 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -20,7 +20,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - const core = globalThis.__bootstrap.core; import { validateIntegerRange } from "ext:deno_node/_utils.ts"; import process from "ext:deno_node/process.ts"; From 7ba7145945301abd8ab8319e186833fe81ca77eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 28 Jun 2023 22:31:23 +0200 Subject: [PATCH 13/17] await status in test --- cli/tests/unit_node/os_test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/tests/unit_node/os_test.ts b/cli/tests/unit_node/os_test.ts index 65857b63dd38ae..2d0d3a8c80dfc3 100644 --- a/cli/tests/unit_node/os_test.ts +++ b/cli/tests/unit_node/os_test.ts @@ -276,7 +276,7 @@ Deno.test({ Deno.test({ name: "os.setPriority() throw os permission denied error & os.getPriority() doesn't", - fn() { + async fn() { const child = new Deno.Command(Deno.execPath(), { args: ["eval", "while (true) { console.log('foo') }"], }).spawn(); @@ -286,5 +286,6 @@ Deno.test({ ); os.getPriority(child.pid); child.kill(); + await child.status; }, }); From ae2ee0ea8c96641987c31527c898c78407afbbf6 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Thu, 29 Jun 2023 01:17:24 +0200 Subject: [PATCH 14/17] add TODO --- ext/node/polyfills/os.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index bd9d12f335e5da..84dd4e14873b46 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -328,6 +328,10 @@ export function userInfo( gid = -1; } + // TODO(@crowlKats): figure out how to do this correctly: + // The value of homedir returned by os.userInfo() is provided by the operating system. + // This differs from the result of os.homedir(), which queries environment + // variables for the home directory before falling back to the operating system response. let _homedir = homedir(); if (!_homedir) { throw new ERR_OS_NO_HOMEDIR(); From 7e9c2bed3e9c6c64bc11bf1fa7437f3d4496c824 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Fri, 28 Jul 2023 14:50:54 +0200 Subject: [PATCH 15/17] address comments --- ext/node/ops/os.rs | 244 ++++++++++++++++++++++----------------------- 1 file changed, 118 insertions(+), 126 deletions(-) diff --git a/ext/node/ops/os.rs b/ext/node/ops/os.rs index 90bf1d16694977..f8c329314bfe6d 100644 --- a/ext/node/ops/os.rs +++ b/ext/node/ops/os.rs @@ -1,5 +1,6 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +use crate::NodePermissions; use deno_core::error::AnyError; use deno_core::op; use deno_core::OpState; @@ -20,7 +21,7 @@ where permissions.check_sys("getPriority", "node:os.getPriority()")?; } - get_priority(pid) + priority::get_priority(pid) } #[op] @@ -37,7 +38,7 @@ where permissions.check_sys("setPriority", "node:os.setPriority()")?; } - set_priority(pid, priority) + priority::set_priority(pid, priority) } #[op] @@ -53,144 +54,135 @@ where Ok(whoami::username()) } -use crate::NodePermissions; -#[cfg(unix)] -use libc::id_t; -#[cfg(unix)] -use libc::PRIO_PROCESS; -#[cfg(windows)] -use winapi::shared::minwindef::DWORD; -#[cfg(windows)] -use winapi::shared::minwindef::FALSE; -#[cfg(windows)] -use winapi::shared::ntdef::NULL; -#[cfg(windows)] -use winapi::um::handleapi::CloseHandle; -#[cfg(windows)] -use winapi::um::processthreadsapi::GetCurrentProcess; -#[cfg(windows)] -use winapi::um::processthreadsapi::GetPriorityClass; -#[cfg(windows)] -use winapi::um::processthreadsapi::OpenProcess; -#[cfg(windows)] -use winapi::um::processthreadsapi::SetPriorityClass; -#[cfg(windows)] -use winapi::um::winbase::ABOVE_NORMAL_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winbase::BELOW_NORMAL_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winbase::HIGH_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winbase::IDLE_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winbase::NORMAL_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winbase::REALTIME_PRIORITY_CLASS; -#[cfg(windows)] -use winapi::um::winnt::PROCESS_QUERY_LIMITED_INFORMATION; +const PRIORITY_HIGH: i32 = -14; -#[cfg(target_os = "macos")] -#[allow(non_camel_case_types)] -type priority_t = i32; -#[cfg(target_os = "linux")] -#[allow(non_camel_case_types)] -type priority_t = u32; +#[cfg(unix)] +mod priority { + use super::*; + use libc::id_t; + use libc::PRIO_PROCESS; -#[cfg(windows)] -pub const PRIORITY_LOW: i32 = 19; -#[cfg(windows)] -pub const PRIORITY_BELOW_NORMAL: i32 = 10; -#[cfg(windows)] -pub const PRIORITY_NORMAL: i32 = 0; -#[cfg(windows)] -pub const PRIORITY_ABOVE_NORMAL: i32 = -7; -pub const PRIORITY_HIGH: i32 = -14; -#[cfg(windows)] -pub const PRIORITY_HIGHEST: i32 = -20; + #[cfg(target_os = "macos")] + #[allow(non_camel_case_types)] + type priority_t = i32; + #[cfg(target_os = "linux")] + #[allow(non_camel_case_types)] + type priority_t = u32; -#[cfg(unix)] -pub fn get_priority(pid: u32) -> Result { - set_errno(Errno(0)); - match ( - // SAFETY: libc::getpriority is unsafe - unsafe { libc::getpriority(PRIO_PROCESS as priority_t, pid as id_t) }, - errno(), - ) { - (-1, Errno(0)) => Ok(PRIORITY_HIGH), - (-1, _) => Err(std::io::Error::last_os_error().into()), - (priority, _) => Ok(priority), + // Ref: https://github.com/libuv/libuv/blob/55376b044b74db40772e8a6e24d67a8673998e02/src/unix/core.c#L1533-L1547 + pub fn get_priority(pid: u32) -> Result { + set_errno(Errno(0)); + match ( + // SAFETY: libc::getpriority is unsafe + unsafe { libc::getpriority(PRIO_PROCESS as priority_t, pid as id_t) }, + errno(), + ) { + (-1, Errno(0)) => Ok(PRIORITY_HIGH), + (-1, _) => Err(std::io::Error::last_os_error().into()), + (priority, _) => Ok(priority), + } } -} -#[cfg(unix)] -pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { - // SAFETY: libc::setpriority is unsafe - match unsafe { - libc::setpriority(PRIO_PROCESS as priority_t, pid as id_t, priority) - } { - -1 => Err(std::io::Error::last_os_error().into()), - _ => Ok(()), + pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { + // SAFETY: libc::setpriority is unsafe + match unsafe { + libc::setpriority(PRIO_PROCESS as priority_t, pid as id_t, priority) + } { + -1 => Err(std::io::Error::last_os_error().into()), + _ => Ok(()), + } } } #[cfg(windows)] -pub fn get_priority(pid: u32) -> Result { - unsafe { - let handle = if pid == 0 { - GetCurrentProcess() - } else { - OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) - }; - if handle == NULL { - Err(std::io::Error::last_os_error().into()) - } else { - let result = match GetPriorityClass(handle) { - 0 => Err(std::io::Error::last_os_error().into()), - REALTIME_PRIORITY_CLASS => Ok(PRIORITY_HIGHEST), - HIGH_PRIORITY_CLASS => Ok(PRIORITY_HIGH), - ABOVE_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_ABOVE_NORMAL), - NORMAL_PRIORITY_CLASS => Ok(PRIORITY_NORMAL), - BELOW_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_BELOW_NORMAL), - IDLE_PRIORITY_CLASS => Ok(PRIORITY_LOW), - _ => Ok(PRIORITY_LOW), +mod priority { + use super::*; + use deno_core::error::type_error; + use winapi::shared::minwindef::DWORD; + use winapi::shared::minwindef::FALSE; + use winapi::shared::ntdef::NULL; + use winapi::um::handleapi::CloseHandle; + use winapi::um::processthreadsapi::GetCurrentProcess; + use winapi::um::processthreadsapi::GetPriorityClass; + use winapi::um::processthreadsapi::OpenProcess; + use winapi::um::processthreadsapi::SetPriorityClass; + use winapi::um::winbase::ABOVE_NORMAL_PRIORITY_CLASS; + use winapi::um::winbase::BELOW_NORMAL_PRIORITY_CLASS; + use winapi::um::winbase::HIGH_PRIORITY_CLASS; + use winapi::um::winbase::IDLE_PRIORITY_CLASS; + use winapi::um::winbase::NORMAL_PRIORITY_CLASS; + use winapi::um::winbase::REALTIME_PRIORITY_CLASS; + use winapi::um::winnt::PROCESS_QUERY_LIMITED_INFORMATION; + + // Taken from: https://github.com/libuv/libuv/blob/a877ca2435134ef86315326ef4ef0c16bdbabf17/include/uv.h#L1318-L1323 + const PRIORITY_LOW: i32 = 19; + const PRIORITY_BELOW_NORMAL: i32 = 10; + const PRIORITY_NORMAL: i32 = 0; + const PRIORITY_ABOVE_NORMAL: i32 = -7; + const PRIORITY_HIGHEST: i32 = -20; + + // Ported from: https://github.com/libuv/libuv/blob/a877ca2435134ef86315326ef4ef0c16bdbabf17/src/win/util.c#L1649-L1685 + pub fn get_priority(pid: u32) -> Result { + unsafe { + let handle = if pid == 0 { + GetCurrentProcess() + } else { + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) }; - CloseHandle(handle); - result + if handle == NULL { + Err(std::io::Error::last_os_error().into()) + } else { + let result = match GetPriorityClass(handle) { + 0 => Err(std::io::Error::last_os_error().into()), + REALTIME_PRIORITY_CLASS => Ok(PRIORITY_HIGHEST), + HIGH_PRIORITY_CLASS => Ok(PRIORITY_HIGH), + ABOVE_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_ABOVE_NORMAL), + NORMAL_PRIORITY_CLASS => Ok(PRIORITY_NORMAL), + BELOW_NORMAL_PRIORITY_CLASS => Ok(PRIORITY_BELOW_NORMAL), + IDLE_PRIORITY_CLASS => Ok(PRIORITY_LOW), + _ => Ok(PRIORITY_LOW), + }; + CloseHandle(handle); + result + } } } -} -#[cfg(windows)] -pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { - unsafe { - let handle = if pid == 0 { - GetCurrentProcess() - } else { - OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) - }; - if handle == NULL { - Err(std::io::Error::last_os_error().into()) - } else { - let prio_class = match priority { - p if p <= PRIORITY_HIGHEST => REALTIME_PRIORITY_CLASS, - p if PRIORITY_HIGHEST < p && p <= PRIORITY_HIGH => HIGH_PRIORITY_CLASS, - p if PRIORITY_HIGH < p && p <= PRIORITY_ABOVE_NORMAL => { - ABOVE_NORMAL_PRIORITY_CLASS - } - p if PRIORITY_ABOVE_NORMAL < p && p <= PRIORITY_NORMAL => { - NORMAL_PRIORITY_CLASS - } - p if PRIORITY_NORMAL < p && p <= PRIORITY_BELOW_NORMAL => { - BELOW_NORMAL_PRIORITY_CLASS - } - _ => IDLE_PRIORITY_CLASS, + // Ported from: https://github.com/libuv/libuv/blob/a877ca2435134ef86315326ef4ef0c16bdbabf17/src/win/util.c#L1688-L1719 + pub fn set_priority(pid: u32, priority: i32) -> Result<(), AnyError> { + unsafe { + let handle = if pid == 0 { + GetCurrentProcess() + } else { + OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid as DWORD) }; - let result = match SetPriorityClass(handle, prio_class) { - FALSE => Err(std::io::Error::last_os_error().into()), - _ => Ok(()), - }; - CloseHandle(handle); - result + if handle == NULL { + Err(std::io::Error::last_os_error().into()) + } else { + let priority_class = + if priority < UV_PRIORITY_HIGHEST || priority > PRIORITY_LOW { + return Err(type_error("Invalid priority")); + } else if priority < PRIORITY_HIGH { + REALTIME_PRIORITY_CLASS + } else if priority < PRIORITY_ABOVE_NORMAL { + HIGH_PRIORITY_CLASS + } else if priority < PRIORITY_NORMAL { + ABOVE_NORMAL_PRIORITY_CLASS + } else if priority < PRIORITY_BELOW_NORMAL { + NORMAL_PRIORITY_CLASS + } else if priority < PRIORITY_LOW { + BELOW_NORMAL_PRIORITY_CLASS + } else { + IDLE_PRIORITY_CLASS + }; + + let result = match SetPriorityClass(handle, priority_class) { + FALSE => Err(std::io::Error::last_os_error().into()), + _ => Ok(()), + }; + CloseHandle(handle); + result + } } } } From c3fae9383af33c5ceb6413564de91f391785b364 Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 31 Jul 2023 17:01:10 +0200 Subject: [PATCH 16/17] fix build --- ext/node/polyfills/os.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 33f48ceb5857b6..a874c942cbc3c2 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -30,7 +30,7 @@ import { isWindows, osType } from "ext:deno_node/_util/os.ts"; import { ERR_OS_NO_HOMEDIR } from "ext:deno_node/internal/errors.ts"; import { os } from "ext:deno_node/internal_binding/constants.ts"; import { osUptime } from "ext:runtime/30_os.js"; -import { Buffer } from "ext:deno_node/buffer.ts"; +import { Buffer } from "ext:deno_node/internal/buffer.mjs"; export const constants = os; From 0136b9936950304f1160570453c796670037d6da Mon Sep 17 00:00:00 2001 From: crowlkats Date: Mon, 31 Jul 2023 17:21:03 +0200 Subject: [PATCH 17/17] fix build --- ext/node/ops/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/node/ops/os.rs b/ext/node/ops/os.rs index f8c329314bfe6d..0a841a72ac1a74 100644 --- a/ext/node/ops/os.rs +++ b/ext/node/ops/os.rs @@ -160,7 +160,7 @@ mod priority { Err(std::io::Error::last_os_error().into()) } else { let priority_class = - if priority < UV_PRIORITY_HIGHEST || priority > PRIORITY_LOW { + if priority < PRIORITY_HIGHEST || priority > PRIORITY_LOW { return Err(type_error("Invalid priority")); } else if priority < PRIORITY_HIGH { REALTIME_PRIORITY_CLASS