pkg/ioutils: remove usage of os.Lstat() in FTW()

As os.Readdir() is used get file entries where statinfo is already
present.  This patch fixes to use statinfo provided by os.Readdir().
This commit is contained in:
Bala.FA 2016-02-10 19:02:26 +05:30 committed by Harshavardhana
parent 31dbdb1787
commit 255505a83b

View File

@ -46,45 +46,37 @@ func FTW(root string, walkFn FTWFunc) error {
return walk(root, info, walkFn) return walk(root, info, walkFn)
} }
// getRealName - gets the proper filename for sorting purposes // byName implements sort.Interface for sorting os.FileInfo list.
// Readdir() filters out directory names without separators, add type byName []os.FileInfo
// them back for proper sorting results.
func getRealName(info os.FileInfo) string { func (f byName) Len() int { return len(f) }
if info.IsDir() { func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
// Make sure directory has its end separator. func (f byName) Less(i, j int) bool {
return info.Name() + string(os.PathSeparator) n1 := f[i].Name()
if f[i].IsDir() {
n1 = n1 + string(os.PathSeparator)
} }
return info.Name()
n2 := f[j].Name()
if f[i].IsDir() {
n2 = n2 + string(os.PathSeparator)
}
return n1 < n2
} }
// readDirNames reads the directory named by dirname and returns // readDir reads the directory named by dirname and returns
// a sorted list of directory entries. // a sorted list of directory entries.
func readDirNames(dirname string) ([]string, error) { func readDir(dirname string) (fi []os.FileInfo, err error) {
names, err := readDirUnsortedNames(dirname)
if err != nil {
return nil, err
}
sort.Strings(names)
return names, nil
}
func readDirUnsortedNames(dirname string) ([]string, error) {
f, err := os.Open(dirname) f, err := os.Open(dirname)
if err != nil { if err == nil {
return nil, err defer f.Close()
if fi, err = f.Readdir(-1); fi != nil {
sort.Sort(byName(fi))
} }
nameInfos, err := f.Readdir(-1)
if err != nil {
return nil, err
} }
if err = f.Close(); err != nil {
return nil, err return
}
var names []string
for _, nameInfo := range nameInfos {
names = append(names, getRealName(nameInfo))
}
return names, nil
} }
// FTWFunc is the type of the function called for each file or directory // FTWFunc is the type of the function called for each file or directory
@ -125,13 +117,12 @@ func walk(path string, info os.FileInfo, walkFn FTWFunc) error {
return nil return nil
} }
names, err := readDirNames(path) fis, err := readDir(path)
if err != nil { if err != nil {
return walkFn(path, info, err) return walkFn(path, info, err)
} }
for _, name := range names { for _, fileInfo := range fis {
filename := filepath.Join(path, name) filename := filepath.Join(path, fileInfo.Name())
fileInfo, err := os.Lstat(filename)
if err != nil { if err != nil {
if err := walkFn(filename, fileInfo, err); err != nil && err != ErrSkipDir && err != ErrSkipFile { if err := walkFn(filename, fileInfo, err); err != nil && err != ErrSkipDir && err != ErrSkipFile {
return err return err