Commit b86e7668 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDavid du Colombier <0intro@gmail.com>
Reviewed-by: 's avatarAlex Brainman <alex.brainman@gmail.com>
parent bae3fd66
...@@ -40,9 +40,7 @@ func MkdirAll(path string, perm FileMode) error { ...@@ -40,9 +40,7 @@ func MkdirAll(path string, perm FileMode) error {
if j > 1 { if j > 1 {
// Create parent. // Create parent.
// Pass trailing path separator to MkdirAll, so our err = MkdirAll(fixRootDirectory(path[:j-1]), perm)
// algorithm works for paths, like \\?\c:\
err = MkdirAll(path[0:j], perm)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -13,3 +13,7 @@ const ( ...@@ -13,3 +13,7 @@ const (
func IsPathSeparator(c uint8) bool { func IsPathSeparator(c uint8) bool {
return PathSeparator == c return PathSeparator == c
} }
func fixRootDirectory(p string) string {
return p
}
...@@ -33,3 +33,7 @@ func basename(name string) string { ...@@ -33,3 +33,7 @@ func basename(name string) string {
return name return name
} }
func fixRootDirectory(p string) string {
return p
}
...@@ -207,3 +207,14 @@ func fixLongPath(path string) string { ...@@ -207,3 +207,14 @@ func fixLongPath(path string) string {
} }
return string(pathbuf[:w]) 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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment