diff --git a/src/os/path.go b/src/os/path.go index eb996e5fb9..ec6a7938b2 100644 --- a/src/os/path.go +++ b/src/os/path.go @@ -39,8 +39,10 @@ func MkdirAll(path string, perm FileMode) error { } if j > 1 { - // Create parent - err = MkdirAll(path[0:j-1], perm) + // Create parent. + // Pass trailing path separator to MkdirAll, so our + // algorithm works for paths, like \\?\c:\ + err = MkdirAll(path[0:j], perm) if err != nil { return err } diff --git a/src/os/path_windows_test.go b/src/os/path_windows_test.go index cce0bdd522..00a3e63bf3 100644 --- a/src/os/path_windows_test.go +++ b/src/os/path_windows_test.go @@ -5,8 +5,10 @@ package os_test import ( + "io/ioutil" "os" "strings" + "syscall" "testing" ) @@ -44,3 +46,31 @@ func TestFixLongPath(t *testing.T) { } } } + +func TestMkdirAllExtendedLength(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "TestMkdirAllExtendedLength") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + const prefix = `\\?\` + if len(tmpDir) < 4 || tmpDir[:4] != prefix { + fullPath, err := syscall.FullPath(tmpDir) + if err != nil { + t.Fatalf("FullPath(%q) fails: %v", tmpDir, err) + } + tmpDir = prefix + fullPath + } + path := tmpDir + `\dir\` + err = os.MkdirAll(path, 0777) + if err != nil { + t.Fatalf("MkdirAll(%q) failed: %v", path, err) + } + + path = path + `.\dir2` + err = os.MkdirAll(path, 0777) + if err == nil { + t.Fatalf("MkdirAll(%q) should have failed, but did not", path) + } +}