mirror of
https://github.com/golang/go
synced 2024-11-18 15:04:44 -07:00
os: treat "nul" as DevNull file on windows
Also add more tests to test both nul and NUL on windows. Fixes #24482 Change-Id: I3dfe68ec8de7f90ca869c1096dde0054df3c5cf6 Reviewed-on: https://go-review.googlesource.com/102457 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
5ce92d0384
commit
48c4eeeed7
@ -1791,23 +1791,60 @@ func TestSameFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDevNullFile(t *testing.T) {
|
||||
f, err := Open(DevNull)
|
||||
if err != nil {
|
||||
t.Fatalf("Open(%s): %v", DevNull, err)
|
||||
}
|
||||
defer f.Close()
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
t.Fatalf("Stat(%s): %v", DevNull, err)
|
||||
}
|
||||
name := filepath.Base(DevNull)
|
||||
if fi.Name() != name {
|
||||
t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
|
||||
func testDevNullFileInfo(t *testing.T, statname, devNullName string, fi FileInfo, ignoreCase bool) {
|
||||
pre := fmt.Sprintf("%s(%q): ", statname, devNullName)
|
||||
name := filepath.Base(devNullName)
|
||||
if ignoreCase {
|
||||
if strings.ToUpper(fi.Name()) != strings.ToUpper(name) {
|
||||
t.Errorf(pre+"wrong file name have %v want %v", fi.Name(), name)
|
||||
}
|
||||
} else {
|
||||
if fi.Name() != name {
|
||||
t.Errorf(pre+"wrong file name have %v want %v", fi.Name(), name)
|
||||
}
|
||||
}
|
||||
if fi.Size() != 0 {
|
||||
t.Fatalf("wrong file size have %d want 0", fi.Size())
|
||||
t.Errorf(pre+"wrong file size have %d want 0", fi.Size())
|
||||
}
|
||||
if fi.Mode()&ModeDevice == 0 {
|
||||
t.Errorf(pre+"wrong file mode %q: ModeDevice is not set", fi.Mode())
|
||||
}
|
||||
if fi.Mode()&ModeCharDevice == 0 {
|
||||
t.Errorf(pre+"wrong file mode %q: ModeCharDevice is not set", fi.Mode())
|
||||
}
|
||||
if fi.Mode().IsRegular() {
|
||||
t.Errorf(pre+"wrong file mode %q: IsRegular returns true", fi.Mode())
|
||||
}
|
||||
}
|
||||
|
||||
func testDevNullFile(t *testing.T, devNullName string, ignoreCase bool) {
|
||||
f, err := Open(devNullName)
|
||||
if err != nil {
|
||||
t.Fatalf("Open(%s): %v", devNullName, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
t.Fatalf("Stat(%s): %v", devNullName, err)
|
||||
}
|
||||
testDevNullFileInfo(t, "f.Stat", devNullName, fi, ignoreCase)
|
||||
|
||||
fi, err = Stat(devNullName)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat(%s): %v", devNullName, err)
|
||||
}
|
||||
testDevNullFileInfo(t, "Stat", devNullName, fi, ignoreCase)
|
||||
|
||||
fi, err = Lstat(devNullName)
|
||||
if err != nil {
|
||||
t.Fatalf("Lstat(%s): %v", devNullName, err)
|
||||
}
|
||||
testDevNullFileInfo(t, "Lstat", devNullName, fi, ignoreCase)
|
||||
}
|
||||
|
||||
func TestDevNullFile(t *testing.T) {
|
||||
testDevNullFile(t, DevNull, false)
|
||||
}
|
||||
|
||||
var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
|
||||
|
@ -979,3 +979,35 @@ func TestOneDrive(t *testing.T) {
|
||||
}
|
||||
testIsDir(t, dir, fi)
|
||||
}
|
||||
|
||||
func TestWindowsDevNullFile(t *testing.T) {
|
||||
testDevNullFile(t, "NUL", true)
|
||||
testDevNullFile(t, "nul", true)
|
||||
testDevNullFile(t, "Nul", true)
|
||||
|
||||
f1, err := os.Open("NUL")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f1.Close()
|
||||
|
||||
fi1, err := f1.Stat()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f2, err := os.Open("nul")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f2.Close()
|
||||
|
||||
fi2, err := f2.Stat()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !os.SameFile(fi1, fi2) {
|
||||
t.Errorf(`"NUL" and "nul" are not the same file`)
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,24 @@ import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// isNulName returns true if name is NUL file name.
|
||||
// For example, it returns true for both "NUL" and "nul".
|
||||
func isNulName(name string) bool {
|
||||
if len(name) != 3 {
|
||||
return false
|
||||
}
|
||||
if name[0] != 'n' && name[0] != 'N' {
|
||||
return false
|
||||
}
|
||||
if name[1] != 'u' && name[1] != 'U' {
|
||||
return false
|
||||
}
|
||||
if name[2] != 'l' && name[2] != 'L' {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Stat returns the FileInfo structure describing file.
|
||||
// If there is an error, it will be of type *PathError.
|
||||
func (file *File) Stat() (FileInfo, error) {
|
||||
@ -19,7 +37,7 @@ func (file *File) Stat() (FileInfo, error) {
|
||||
// I don't know any better way to do that for directory
|
||||
return Stat(file.dirinfo.path)
|
||||
}
|
||||
if file.name == DevNull {
|
||||
if isNulName(file.name) {
|
||||
return &devNullStat, nil
|
||||
}
|
||||
|
||||
@ -45,7 +63,7 @@ func statNolog(name string) (FileInfo, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
|
||||
}
|
||||
if name == DevNull {
|
||||
if isNulName(name) {
|
||||
return &devNullStat, nil
|
||||
}
|
||||
namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
|
||||
@ -80,7 +98,7 @@ func lstatNolog(name string) (FileInfo, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, &PathError{"Lstat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
|
||||
}
|
||||
if name == DevNull {
|
||||
if isNulName(name) {
|
||||
return &devNullStat, nil
|
||||
}
|
||||
namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
|
||||
|
Loading…
Reference in New Issue
Block a user