Commit 0f4510b3 authored by Yasuhiro Matsumoto's avatar Yasuhiro Matsumoto Committed by Alex Brainman

os: fix os.MkdirAll with backslash path separator.

MkdirAll() need to use isSeparator().
Move primary defines of filepath.Separator/filepath.ListSeparator
 to os.PathSeparator/os.PathListSeparator.
Move filepath.isSeparator() to os.IsPathSeparator().
filepath package refer them from os package.
Fixes #1831.

R=rsc, alex.brainman
CC=golang-dev
https://golang.org/cl/4535100
parent 505f0bb3
...@@ -23,6 +23,7 @@ GOFILES_freebsd=\ ...@@ -23,6 +23,7 @@ GOFILES_freebsd=\
env_unix.go\ env_unix.go\
file_posix.go\ file_posix.go\
file_unix.go\ file_unix.go\
path_unix.go\
sys_bsd.go\ sys_bsd.go\
exec_posix.go\ exec_posix.go\
exec_unix.go\ exec_unix.go\
...@@ -33,6 +34,7 @@ GOFILES_darwin=\ ...@@ -33,6 +34,7 @@ GOFILES_darwin=\
env_unix.go\ env_unix.go\
file_posix.go\ file_posix.go\
file_unix.go\ file_unix.go\
path_unix.go\
sys_bsd.go\ sys_bsd.go\
exec_posix.go\ exec_posix.go\
exec_unix.go\ exec_unix.go\
...@@ -43,6 +45,7 @@ GOFILES_linux=\ ...@@ -43,6 +45,7 @@ GOFILES_linux=\
env_unix.go\ env_unix.go\
file_posix.go\ file_posix.go\
file_unix.go\ file_unix.go\
path_unix.go\
sys_linux.go\ sys_linux.go\
exec_posix.go\ exec_posix.go\
exec_unix.go\ exec_unix.go\
...@@ -53,6 +56,7 @@ GOFILES_windows=\ ...@@ -53,6 +56,7 @@ GOFILES_windows=\
env_windows.go\ env_windows.go\
file_posix.go\ file_posix.go\
file_windows.go\ file_windows.go\
path_windows.go\
sys_windows.go\ sys_windows.go\
exec_posix.go\ exec_posix.go\
exec_windows.go\ exec_windows.go\
...@@ -62,6 +66,7 @@ GOFILES_plan9=\ ...@@ -62,6 +66,7 @@ GOFILES_plan9=\
error_plan9.go\ error_plan9.go\
env_plan9.go\ env_plan9.go\
file_plan9.go\ file_plan9.go\
path_plan9.go\
sys_plan9.go\ sys_plan9.go\
exec_plan9.go\ exec_plan9.go\
......
...@@ -24,12 +24,12 @@ func MkdirAll(path string, perm uint32) Error { ...@@ -24,12 +24,12 @@ func MkdirAll(path string, perm uint32) Error {
// Doesn't already exist; make sure parent does. // Doesn't already exist; make sure parent does.
i := len(path) i := len(path)
for i > 0 && path[i-1] == '/' { // Skip trailing slashes. for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
i-- i--
} }
j := i j := i
for j > 0 && path[j-1] != '/' { // Scan backward over element. for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
j-- j--
} }
...@@ -90,7 +90,7 @@ func RemoveAll(path string) Error { ...@@ -90,7 +90,7 @@ func RemoveAll(path string) Error {
for { for {
names, err1 := fd.Readdirnames(100) names, err1 := fd.Readdirnames(100)
for _, name := range names { for _, name := range names {
err1 := RemoveAll(path + "/" + name) err1 := RemoveAll(path + string(PathSeparator) + name)
if err == nil { if err == nil {
err = err1 err = err1
} }
......
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package os
const (
PathSeparator = '/' // OS-specific path separator
PathListSeparator = 0 // OS-specific path list separator
)
// IsPathSeparator returns true if c is a directory separator character.
func IsPathSeparator(c uint8) bool {
return PathSeparator == c
}
...@@ -6,6 +6,7 @@ package os_test ...@@ -6,6 +6,7 @@ package os_test
import ( import (
. "os" . "os"
"path/filepath"
"testing" "testing"
"runtime" "runtime"
"syscall" "syscall"
...@@ -44,8 +45,8 @@ func TestMkdirAll(t *testing.T) { ...@@ -44,8 +45,8 @@ func TestMkdirAll(t *testing.T) {
if !ok { if !ok {
t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err) t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
} }
if perr.Path != fpath { if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, perr.Path, fpath) t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
} }
// Can't make subdirectory of file. // Can't make subdirectory of file.
...@@ -58,8 +59,16 @@ func TestMkdirAll(t *testing.T) { ...@@ -58,8 +59,16 @@ func TestMkdirAll(t *testing.T) {
if !ok { if !ok {
t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err) t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
} }
if perr.Path != fpath { if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, perr.Path, fpath) t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
}
if syscall.OS == "windows" {
path := `_test\_TestMkdirAll_\dir\.\dir2\`
err := MkdirAll(path, 0777)
if err != nil {
t.Fatalf("MkdirAll %q: %s", path, err)
}
} }
} }
......
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package os
const (
PathSeparator = '/' // OS-specific path separator
PathListSeparator = ':' // OS-specific path list separator
)
// IsPathSeparator returns true if c is a directory separator character.
func IsPathSeparator(c uint8) bool {
return PathSeparator == c
}
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package os
const (
PathSeparator = '\\' // OS-specific path separator
PathListSeparator = ':' // OS-specific path list separator
)
// IsPathSeparator returns true if c is a directory separator character.
func IsPathSeparator(c uint8) bool {
// NOTE: Windows accept / as path separator.
return c == '\\' || c == '/'
}
...@@ -15,6 +15,8 @@ import ( ...@@ -15,6 +15,8 @@ import (
) )
const ( const (
Separator = os.PathSeparator
ListSeparator = os.PathListSeparator
SeparatorString = string(Separator) SeparatorString = string(Separator)
ListSeparatorString = string(ListSeparator) ListSeparatorString = string(ListSeparator)
) )
...@@ -61,20 +63,20 @@ func Clean(path string) string { ...@@ -61,20 +63,20 @@ func Clean(path string) string {
for r < n { for r < n {
switch { switch {
case isSeparator(path[r]): case os.IsPathSeparator(path[r]):
// empty path element // empty path element
r++ r++
case path[r] == '.' && (r+1 == n || isSeparator(path[r+1])): case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
// . element // . element
r++ r++
case path[r] == '.' && path[r+1] == '.' && (r+2 == n || isSeparator(path[r+2])): case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
// .. element: remove to last separator // .. element: remove to last separator
r += 2 r += 2
switch { switch {
case w > dotdot: case w > dotdot:
// can backtrack // can backtrack
w-- w--
for w > dotdot && !isSeparator(buf[w]) { for w > dotdot && !os.IsPathSeparator(buf[w]) {
w-- w--
} }
case !rooted: case !rooted:
...@@ -97,7 +99,7 @@ func Clean(path string) string { ...@@ -97,7 +99,7 @@ func Clean(path string) string {
w++ w++
} }
// copy element // copy element
for ; r < n && !isSeparator(path[r]); r++ { for ; r < n && !os.IsPathSeparator(path[r]); r++ {
buf[w] = path[r] buf[w] = path[r]
w++ w++
} }
...@@ -145,7 +147,7 @@ func SplitList(path string) []string { ...@@ -145,7 +147,7 @@ func SplitList(path string) []string {
// and file set to path. // and file set to path.
func Split(path string) (dir, file string) { func Split(path string) (dir, file string) {
i := len(path) - 1 i := len(path) - 1
for i >= 0 && !isSeparator(path[i]) { for i >= 0 && !os.IsPathSeparator(path[i]) {
i-- i--
} }
return path[:i+1], path[i+1:] return path[:i+1], path[i+1:]
...@@ -167,7 +169,7 @@ func Join(elem ...string) string { ...@@ -167,7 +169,7 @@ func Join(elem ...string) string {
// in the final element of path; it is empty if there is // in the final element of path; it is empty if there is
// no dot. // no dot.
func Ext(path string) string { func Ext(path string) string {
for i := len(path) - 1; i >= 0 && !isSeparator(path[i]); i-- { for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
if path[i] == '.' { if path[i] == '.' {
return path[i:] return path[i:]
} }
...@@ -339,12 +341,12 @@ func Base(path string) string { ...@@ -339,12 +341,12 @@ func Base(path string) string {
return "." return "."
} }
// Strip trailing slashes. // Strip trailing slashes.
for len(path) > 0 && isSeparator(path[len(path)-1]) { for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) {
path = path[0 : len(path)-1] path = path[0 : len(path)-1]
} }
// Find the last element // Find the last element
i := len(path) - 1 i := len(path) - 1
for i >= 0 && !isSeparator(path[i]) { for i >= 0 && !os.IsPathSeparator(path[i]) {
i-- i--
} }
if i >= 0 { if i >= 0 {
......
...@@ -6,16 +6,6 @@ package filepath ...@@ -6,16 +6,6 @@ package filepath
import "strings" import "strings"
const (
Separator = '/' // OS-specific path separator
ListSeparator = 0 // OS-specific path list separator
)
// isSeparator returns true if c is a directory separator character.
func isSeparator(c uint8) bool {
return Separator == c
}
// IsAbs returns true if the path is absolute. // IsAbs returns true if the path is absolute.
func IsAbs(path string) bool { func IsAbs(path string) bool {
return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#") return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#")
......
...@@ -6,16 +6,6 @@ package filepath ...@@ -6,16 +6,6 @@ package filepath
import "strings" import "strings"
const (
Separator = '/' // OS-specific path separator
ListSeparator = ':' // OS-specific path list separator
)
// isSeparator returns true if c is a directory separator character.
func isSeparator(c uint8) bool {
return Separator == c
}
// IsAbs returns true if the path is absolute. // IsAbs returns true if the path is absolute.
func IsAbs(path string) bool { func IsAbs(path string) bool {
return strings.HasPrefix(path, "/") return strings.HasPrefix(path, "/")
......
...@@ -4,20 +4,11 @@ ...@@ -4,20 +4,11 @@
package filepath package filepath
const ( import "os"
Separator = '\\' // OS-specific path separator
ListSeparator = ':' // OS-specific path list separator
)
// isSeparator returns true if c is a directory separator character.
func isSeparator(c uint8) bool {
// NOTE: Windows accept / as path separator.
return c == '\\' || c == '/'
}
// IsAbs returns true if the path is absolute. // IsAbs returns true if the path is absolute.
func IsAbs(path string) bool { func IsAbs(path string) bool {
return path != "" && (volumeName(path) != "" || isSeparator(path[0])) return path != "" && (volumeName(path) != "" || os.IsPathSeparator(path[0]))
} }
// volumeName return leading volume name. // volumeName return leading volume name.
...@@ -28,7 +19,7 @@ func volumeName(path string) string { ...@@ -28,7 +19,7 @@ func volumeName(path string) string {
} }
// with drive letter // with drive letter
c := path[0] c := path[0]
if len(path) > 2 && path[1] == ':' && isSeparator(path[2]) && if len(path) > 2 && path[1] == ':' && os.IsPathSeparator(path[2]) &&
('0' <= c && c <= '9' || 'a' <= c && c <= 'z' || ('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
'A' <= c && c <= 'Z') { 'A' <= c && c <= 'Z') {
return path[0:2] return path[0:2]
......
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