From 105c571fb6ba4d9b9404b5998eb6e17f0efdd79f Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:42:35 -0700 Subject: [PATCH] fix(cli): Map error kind to `PermissionDenied` when symlinking fails due to permissions (#25398) Fixes https://github.com/denoland/deno/issues/25333. We fall back to junctions if the error kind is `PermissionDenied` but the std library actually sets the kind to `Uncategorized` if the symlink fails due to insufficient privileges. This was causing the fallback to not actually fall back in this case. --- cli/util/fs.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/cli/util/fs.rs b/cli/util/fs.rs index d723d24e1f..fdf6035ecd 100644 --- a/cli/util/fs.rs +++ b/cli/util/fs.rs @@ -496,9 +496,9 @@ pub fn hard_link_dir_recursive(from: &Path, to: &Path) -> Result<(), AnyError> { } pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> { - let err_mapper = |err: Error| { + let err_mapper = |err: Error, kind: Option| { Error::new( - err.kind(), + kind.unwrap_or_else(|| err.kind()), format!( "{}, symlink '{}' -> '{}'", err, @@ -510,12 +510,19 @@ pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> { #[cfg(unix)] { use std::os::unix::fs::symlink; - symlink(oldpath, newpath).map_err(err_mapper)?; + symlink(oldpath, newpath).map_err(|e| err_mapper(e, None))?; } #[cfg(not(unix))] { use std::os::windows::fs::symlink_dir; - symlink_dir(oldpath, newpath).map_err(err_mapper)?; + symlink_dir(oldpath, newpath).map_err(|err| { + if let Some(code) = err.raw_os_error() { + if code as u32 == winapi::shared::winerror::ERROR_PRIVILEGE_NOT_HELD { + return err_mapper(err, Some(ErrorKind::PermissionDenied)); + } + } + err_mapper(err, None) + })?; } Ok(()) }