From b86e76681366447798c94abb959bb60875bcc856 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 19 Feb 2018 13:26:01 -0800 Subject: [PATCH] path: use OS-specific function in MkdirAll, don't always keep trailing slash CL 86295 changed MkdirAll to always pass a trailing path separator to support extended-length paths on Windows. However, when Stat is called on an existing file followed by trailing slash, it will return a "not a directory" error, skipping the fast path at the beginning of MkdirAll. This change fixes MkdirAll to only pass the trailing path separator where required on Windows, by using an OS-specific function fixRootDirectory. Updates #23918 Change-Id: I23f84a20e65ccce556efa743d026d352b4812c34 Reviewed-on: https://go-review.googlesource.com/95255 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: David du Colombier <0intro@gmail.com> Reviewed-by: Alex Brainman --- src/os/path.go | 4 +--- src/os/path_plan9.go | 4 ++++ src/os/path_unix.go | 4 ++++ src/os/path_windows.go | 11 +++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/os/path.go b/src/os/path.go index ec6a7938b2..5c5350670d 100644 --- a/src/os/path.go +++ b/src/os/path.go @@ -40,9 +40,7 @@ func MkdirAll(path string, perm FileMode) error { if j > 1 { // Create parent. - // Pass trailing path separator to MkdirAll, so our - // algorithm works for paths, like \\?\c:\ - err = MkdirAll(path[0:j], perm) + err = MkdirAll(fixRootDirectory(path[:j-1]), perm) if err != nil { return err } diff --git a/src/os/path_plan9.go b/src/os/path_plan9.go index b09b53a3d8..a54b4b98f1 100644 --- a/src/os/path_plan9.go +++ b/src/os/path_plan9.go @@ -13,3 +13,7 @@ const ( func IsPathSeparator(c uint8) bool { return PathSeparator == c } + +func fixRootDirectory(p string) string { + return p +} diff --git a/src/os/path_unix.go b/src/os/path_unix.go index ecf098c461..9117ad0ef6 100644 --- a/src/os/path_unix.go +++ b/src/os/path_unix.go @@ -33,3 +33,7 @@ func basename(name string) string { return name } + +func fixRootDirectory(p string) string { + return p +} diff --git a/src/os/path_windows.go b/src/os/path_windows.go index 101b026dc9..87b1cac531 100644 --- a/src/os/path_windows.go +++ b/src/os/path_windows.go @@ -207,3 +207,14 @@ func fixLongPath(path string) string { } return string(pathbuf[:w]) } + +// fixRootDirectory fixes a reference to a drive's root directory to +// have the required trailing slash. +func fixRootDirectory(p string) string { + if len(p) == len(`\\?\c:`) { + if IsPathSeparator(p[0]) && IsPathSeparator(p[1]) && p[2] == '?' && IsPathSeparator(p[3]) && p[5] == ':' { + return p + `\` + } + } + return p +} -- 2.48.1