mirror of
https://github.com/golang/go
synced 2024-11-26 05:27:57 -07:00
os: make Readdir work as documented
Readdir's result should never contain a nil. Fixes #5960. R=golang-dev, rsc, bradfitz CC=golang-dev https://golang.org/cl/12261043
This commit is contained in:
parent
547f1a6fe7
commit
bdbd5418f4
@ -7,3 +7,4 @@ package os
|
|||||||
// Export for testing.
|
// Export for testing.
|
||||||
|
|
||||||
var Atime = atime
|
var Atime = atime
|
||||||
|
var LstatP = &lstat
|
||||||
|
@ -149,6 +149,9 @@ func Lstat(name string) (fi FileInfo, err error) {
|
|||||||
return fileInfoFromStat(&stat, name), nil
|
return fileInfoFromStat(&stat, name), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lstat is overridden in tests.
|
||||||
|
var lstat = Lstat
|
||||||
|
|
||||||
func (f *File) readdir(n int) (fi []FileInfo, err error) {
|
func (f *File) readdir(n int) (fi []FileInfo, err error) {
|
||||||
dirname := f.name
|
dirname := f.name
|
||||||
if dirname == "" {
|
if dirname == "" {
|
||||||
@ -158,12 +161,14 @@ func (f *File) readdir(n int) (fi []FileInfo, err error) {
|
|||||||
names, err := f.Readdirnames(n)
|
names, err := f.Readdirnames(n)
|
||||||
fi = make([]FileInfo, len(names))
|
fi = make([]FileInfo, len(names))
|
||||||
for i, filename := range names {
|
for i, filename := range names {
|
||||||
fip, lerr := Lstat(dirname + filename)
|
fip, lerr := lstat(dirname + filename)
|
||||||
if err == nil {
|
if lerr == nil {
|
||||||
fi[i] = fip
|
fi[i] = fip
|
||||||
err = lerr
|
|
||||||
} else {
|
} else {
|
||||||
fi[i] = &fileStat{name: filename}
|
fi[i] = &fileStat{name: filename}
|
||||||
|
if err == nil {
|
||||||
|
err = lerr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fi, err
|
return fi, err
|
||||||
|
@ -28,7 +28,7 @@ func checkUidGid(t *testing.T, path string, uid, gid int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestChown(t *testing.T) {
|
func TestChown(t *testing.T) {
|
||||||
// Chown is not supported under windows or Plan 9.
|
// Chown is not supported under windows os Plan 9.
|
||||||
// Plan9 provides a native ChownPlan9 version instead.
|
// Plan9 provides a native ChownPlan9 version instead.
|
||||||
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
|
if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
|
||||||
return
|
return
|
||||||
@ -74,3 +74,41 @@ func TestChown(t *testing.T) {
|
|||||||
checkUidGid(t, f.Name(), int(sys.Uid), gid)
|
checkUidGid(t, f.Name(), int(sys.Uid), gid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReaddirWithBadLstat(t *testing.T) {
|
||||||
|
handle, err := Open(sfdir)
|
||||||
|
failfile := sfdir + "/" + sfname
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Couldn't open %s: %s", sfdir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*LstatP = func(file string) (FileInfo, error) {
|
||||||
|
if file == failfile {
|
||||||
|
var fi FileInfo
|
||||||
|
return fi, ErrInvalid
|
||||||
|
}
|
||||||
|
return Lstat(file)
|
||||||
|
}
|
||||||
|
defer func() { *LstatP = Lstat }()
|
||||||
|
|
||||||
|
dirs, err := handle.Readdir(-1)
|
||||||
|
if err != ErrInvalid {
|
||||||
|
t.Fatalf("Expected Readdir to return ErrInvalid, got %v", err)
|
||||||
|
}
|
||||||
|
foundfail := false
|
||||||
|
for _, dir := range dirs {
|
||||||
|
if dir.Name() == sfname {
|
||||||
|
foundfail = true
|
||||||
|
if dir.Sys() != nil {
|
||||||
|
t.Errorf("Expected Readdir for %s should not contain Sys", failfile)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if dir.Sys() == nil {
|
||||||
|
t.Errorf("Readdir for every file other than %s should contain Sys, but %s/%s didn't either", failfile, sfdir, dir.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundfail {
|
||||||
|
t.Fatalf("Expected %s from Readdir, but didn't find it", failfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user