mirror of
https://github.com/golang/go
synced 2024-11-25 13:17:56 -07:00
os: make sure Remove returns correct error on windows
R=golang-dev, bsiegert, rsc CC=golang-dev https://golang.org/cl/5493078
This commit is contained in:
parent
448d89d67a
commit
796a2c19ea
@ -24,39 +24,6 @@ func epipecheck(file *File, e error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes the named file or directory.
|
|
||||||
func Remove(name string) error {
|
|
||||||
// System call interface forces us to know
|
|
||||||
// whether name is a file or directory.
|
|
||||||
// Try both: it is cheaper on average than
|
|
||||||
// doing a Stat plus the right one.
|
|
||||||
e := syscall.Unlink(name)
|
|
||||||
if e == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
e1 := syscall.Rmdir(name)
|
|
||||||
if e1 == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Both failed: figure out which error to return.
|
|
||||||
// OS X and Linux differ on whether unlink(dir)
|
|
||||||
// returns EISDIR, so can't use that. However,
|
|
||||||
// both agree that rmdir(file) returns ENOTDIR,
|
|
||||||
// so we can use that to decide which error is real.
|
|
||||||
// Rmdir might also return ENOTDIR if given a bad
|
|
||||||
// file path, like /etc/passwd/foo, but in that case,
|
|
||||||
// both errors will be ENOTDIR, so it's okay to
|
|
||||||
// use the error from unlink.
|
|
||||||
// For windows syscall.ENOTDIR is set
|
|
||||||
// to syscall.ERROR_PATH_NOT_FOUND, hopefully it should
|
|
||||||
// do the trick.
|
|
||||||
if e1 != syscall.ENOTDIR {
|
|
||||||
e = e1
|
|
||||||
}
|
|
||||||
return &PathError{"remove", name, e}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinkError records an error during a link or symlink or rename
|
// LinkError records an error during a link or symlink or rename
|
||||||
// system call and the paths that caused it.
|
// system call and the paths that caused it.
|
||||||
type LinkError struct {
|
type LinkError struct {
|
||||||
|
@ -210,6 +210,36 @@ func Truncate(name string, size int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove removes the named file or directory.
|
||||||
|
func Remove(name string) error {
|
||||||
|
// System call interface forces us to know
|
||||||
|
// whether name is a file or directory.
|
||||||
|
// Try both: it is cheaper on average than
|
||||||
|
// doing a Stat plus the right one.
|
||||||
|
e := syscall.Unlink(name)
|
||||||
|
if e == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
e1 := syscall.Rmdir(name)
|
||||||
|
if e1 == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both failed: figure out which error to return.
|
||||||
|
// OS X and Linux differ on whether unlink(dir)
|
||||||
|
// returns EISDIR, so can't use that. However,
|
||||||
|
// both agree that rmdir(file) returns ENOTDIR,
|
||||||
|
// so we can use that to decide which error is real.
|
||||||
|
// Rmdir might also return ENOTDIR if given a bad
|
||||||
|
// file path, like /etc/passwd/foo, but in that case,
|
||||||
|
// both errors will be ENOTDIR, so it's okay to
|
||||||
|
// use the error from unlink.
|
||||||
|
if e1 != syscall.ENOTDIR {
|
||||||
|
e = e1
|
||||||
|
}
|
||||||
|
return &PathError{"remove", name, e}
|
||||||
|
}
|
||||||
|
|
||||||
// basename removes trailing slashes and the leading directory name from path name
|
// basename removes trailing slashes and the leading directory name from path name
|
||||||
func basename(name string) string {
|
func basename(name string) string {
|
||||||
i := len(name) - 1
|
i := len(name) - 1
|
||||||
|
@ -281,6 +281,35 @@ func Truncate(name string, size int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove removes the named file or directory.
|
||||||
|
func Remove(name string) error {
|
||||||
|
p := &syscall.StringToUTF16(name)[0]
|
||||||
|
|
||||||
|
// Go file interface forces us to know whether
|
||||||
|
// name is a file or directory. Try both.
|
||||||
|
e := syscall.DeleteFile(p)
|
||||||
|
if e == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
e1 := syscall.RemoveDirectory(p)
|
||||||
|
if e1 == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both failed: figure out which error to return.
|
||||||
|
if e1 != e {
|
||||||
|
a, e2 := syscall.GetFileAttributes(p)
|
||||||
|
if e2 != nil {
|
||||||
|
e = e2
|
||||||
|
} else {
|
||||||
|
if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
|
||||||
|
e = e1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &PathError{"remove", name, e}
|
||||||
|
}
|
||||||
|
|
||||||
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
|
// Pipe returns a connected pair of Files; reads from r return bytes written to w.
|
||||||
// It returns the files and an error, if any.
|
// It returns the files and an error, if any.
|
||||||
func Pipe() (r *File, w *File, err error) {
|
func Pipe() (r *File, w *File, err error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user