Add a DirEntryInfo interface that is a subset of os.FileInfo
ioutil.ReadDir returns []os.FileInfo, which contains information on each entry in the directory that is only available by calling os.Lstat on the entry. Finder only the name and type (regular, directory or symlink) of the files, which on Linux kernels >= 2.6.4 is available in the return values of syscall.Getdents. In preparation for using syscall.Getdents, switch filesystem.ReadDir to return an interface that only contains the information that will be available from syscall.Getdents. Bug: 70897635 Test: m checkbuild Change-Id: Id2749d709a0f7b5a61abedde68549d4bf208a568
This commit is contained in:
parent
8d6395c09d
commit
a88c883e3e
|
@ -1384,7 +1384,7 @@ func (f *Finder) listDirSync(dir *pathMap) {
|
||||||
f.onFsError(path, err)
|
f.onFsError(path, err)
|
||||||
// if listing the contents of the directory fails (presumably due to
|
// if listing the contents of the directory fails (presumably due to
|
||||||
// permission denied), then treat the directory as empty
|
// permission denied), then treat the directory as empty
|
||||||
children = []os.FileInfo{}
|
children = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var subdirs []string
|
var subdirs []string
|
||||||
|
|
|
@ -51,7 +51,7 @@ type FileSystem interface {
|
||||||
// getting information about files
|
// getting information about files
|
||||||
Open(name string) (file io.ReadCloser, err error)
|
Open(name string) (file io.ReadCloser, err error)
|
||||||
Lstat(path string) (stats os.FileInfo, err error)
|
Lstat(path string) (stats os.FileInfo, err error)
|
||||||
ReadDir(path string) (contents []os.FileInfo, err error)
|
ReadDir(path string) (contents []DirEntryInfo, err error)
|
||||||
|
|
||||||
InodeNumber(info os.FileInfo) (number uint64, err error)
|
InodeNumber(info os.FileInfo) (number uint64, err error)
|
||||||
DeviceNumber(info os.FileInfo) (number uint64, err error)
|
DeviceNumber(info os.FileInfo) (number uint64, err error)
|
||||||
|
@ -67,18 +67,39 @@ type FileSystem interface {
|
||||||
ViewId() (id string) // Some unique id of the user accessing the filesystem
|
ViewId() (id string) // Some unique id of the user accessing the filesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DentryInfo is a subset of the functionality available through os.FileInfo that might be able
|
||||||
|
// to be gleaned through only a syscall.Getdents without requiring a syscall.Lstat of every file.
|
||||||
|
type DirEntryInfo interface {
|
||||||
|
Name() string
|
||||||
|
Mode() os.FileMode // the file type encoded as an os.FileMode
|
||||||
|
IsDir() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ DirEntryInfo = os.FileInfo(nil)
|
||||||
|
|
||||||
// osFs implements FileSystem using the local disk.
|
// osFs implements FileSystem using the local disk.
|
||||||
type osFs struct{}
|
type osFs struct{}
|
||||||
|
|
||||||
|
var _ FileSystem = (*osFs)(nil)
|
||||||
|
|
||||||
func (osFs) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
|
func (osFs) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
|
||||||
|
|
||||||
func (osFs) Lstat(path string) (stats os.FileInfo, err error) {
|
func (osFs) Lstat(path string) (stats os.FileInfo, err error) {
|
||||||
return os.Lstat(path)
|
return os.Lstat(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (osFs) ReadDir(path string) (contents []os.FileInfo, err error) {
|
func (osFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
|
||||||
return ioutil.ReadDir(path)
|
entries, err := ioutil.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, entry := range entries {
|
||||||
|
contents = append(contents, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (osFs) Rename(oldPath string, newPath string) error {
|
func (osFs) Rename(oldPath string, newPath string) error {
|
||||||
return os.Rename(oldPath, newPath)
|
return os.Rename(oldPath, newPath)
|
||||||
}
|
}
|
||||||
|
@ -154,6 +175,8 @@ type MockFs struct {
|
||||||
aggregatesLock sync.Mutex
|
aggregatesLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ FileSystem = (*MockFs)(nil)
|
||||||
|
|
||||||
type mockInode struct {
|
type mockInode struct {
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
permTime time.Time
|
permTime time.Time
|
||||||
|
@ -475,7 +498,7 @@ func (m *MockFs) PermTime(info os.FileInfo) (when time.Time, err error) {
|
||||||
fmt.Errorf("%v is not a mockFileInfo", info)
|
fmt.Errorf("%v is not a mockFileInfo", info)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockFs) ReadDir(path string) (contents []os.FileInfo, err error) {
|
func (m *MockFs) ReadDir(path string) (contents []DirEntryInfo, err error) {
|
||||||
// update aggregates
|
// update aggregates
|
||||||
m.aggregatesLock.Lock()
|
m.aggregatesLock.Lock()
|
||||||
m.ReadDirCalls = append(m.ReadDirCalls, path)
|
m.ReadDirCalls = append(m.ReadDirCalls, path)
|
||||||
|
@ -486,7 +509,7 @@ func (m *MockFs) ReadDir(path string) (contents []os.FileInfo, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
results := []os.FileInfo{}
|
results := []DirEntryInfo{}
|
||||||
dir, err := m.getDir(path, false)
|
dir, err := m.getDir(path, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue