diff options
author | Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> | 2024-09-03 14:42:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-03 14:42:35 -0700 |
commit | 105c571fb6ba4d9b9404b5998eb6e17f0efdd79f (patch) | |
tree | b5e01ba8a6e8ba023cb3747d2b75072327f3b28a /cli/util | |
parent | 9a36b6fb04764f49cc617be0c5bc7cdbd7fd5956 (diff) |
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.
Diffstat (limited to 'cli/util')
-rw-r--r-- | cli/util/fs.rs | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/cli/util/fs.rs b/cli/util/fs.rs index d723d24e1..fdf6035ec 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<ErrorKind>| { 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(()) } |