Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/fsutils/fsutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func EvalSymlinks(path string) (string, error) {
}

var er evalSymlinkRes
er.path, er.err = filepath.EvalSymlinks(path)
er.path, er.err = evalSymlinks(path)
evalSymlinkCache.Store(path, er)

return er.path, er.err
Expand Down
9 changes: 9 additions & 0 deletions pkg/fsutils/fsutils_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//go:build !windows

package fsutils

import "path/filepath"

func evalSymlinks(path string) (string, error) {
return filepath.EvalSymlinks(path)
}
35 changes: 35 additions & 0 deletions pkg/fsutils/fsutils_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//go:build windows

package fsutils

import (
"os"
"path/filepath"
"syscall"
)

func evalSymlinks(path string) (string, error) {
resolved, err := filepath.EvalSymlinks(path)
if err != nil {
// This is a workaround for the behavior of filepath.EvalSymlinks, which fails with
// syscall.ENOTDIR if the specified path contains a junction on Windows. Junctions
// can occur, for example, when a volume is mounted as a subdirectory inside another
// drive. This can usually happen when using the Dev Drives feature and replacing
// existing directories. See: https://github.com/golang/go/issues/40180
//
// Since syscall.ENOTDIR is only returned when calling filepath.EvalSymlinks on
// Windows if part of the presented path is a junction and nothing before was a
// symlink, we simply treat this as NOT symlink, because a symlink over the junction
// makes no sense at all.
if err == syscall.ENOTDIR {
if _, sErr := os.Stat(path); sErr == nil {
// If exists, we make the path absolute, to be sure...
if abs, aErr := filepath.Abs(path); aErr == nil {
return abs, nil
}
}
}
return "", err
}
return resolved, nil
}