Removes platform.Readdirnames (#1451)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2023-05-10 14:44:54 +08:00
committed by GitHub
parent 745f2c9d8a
commit 4dd4d54cda
6 changed files with 13 additions and 205 deletions

View File

@@ -324,12 +324,12 @@ func syscallReaddir(_ context.Context, mod api.Module, name string) (*objectArra
}
defer f.Close() //nolint
if names, errno := platform.Readdirnames(f.File(), -1); errno != 0 {
if dirents, errno := platform.Readdir(f.File(), -1); errno != 0 {
return nil, errno
} else {
entries := make([]interface{}, 0, len(names))
for _, e := range names {
entries = append(entries, e)
entries := make([]interface{}, 0, len(dirents))
for _, e := range dirents {
entries = append(entries, e.Name)
}
return &objectArray{entries}, nil
}

View File

@@ -7,43 +7,6 @@ import (
"syscall"
)
// Readdirnames reads the names of the directory associated with file and
// returns a slice of up to n strings in an arbitrary order. This is a stateful
// function, so subsequent calls return any next values.
//
// If n > 0, Readdirnames returns at most n entries or an error.
// If n <= 0, Readdirnames returns all remaining entries or an error.
//
// # Errors
//
// A zero syscall.Errno is success.
//
// For portability reasons, no error is returned on io.EOF, when the file is
// closed or removed while open.
// See https://github.com/ziglang/zig/blob/0.10.1/lib/std/fs.zig#L635-L637
func Readdirnames(f fs.File, n int) (names []string, errno syscall.Errno) {
switch f := f.(type) {
case readdirnamesFile:
var err error
names, err = f.Readdirnames(n)
if errno = adjustReaddirErr(err); errno != 0 {
return
}
case fs.ReadDirFile:
entries, err := f.ReadDir(n)
if errno = adjustReaddirErr(err); errno != 0 {
return
}
names = make([]string, 0, len(entries))
for _, e := range entries {
names = append(names, e.Name())
}
default:
errno = syscall.ENOTDIR
}
return
}
// Dirent is an entry read from a directory.
//
// This is a portable variant of syscall.Dirent containing fields needed for

View File

@@ -14,99 +14,6 @@ import (
"github.com/tetratelabs/wazero/internal/testing/require"
)
func TestReaddirnames(t *testing.T) {
t.Parallel()
tmpDir := t.TempDir()
require.NoError(t, fstest.WriteTestFiles(tmpDir))
dirFS := os.DirFS(tmpDir)
tests := []struct {
name string
fs fs.FS
}{
{name: "os.DirFS", fs: dirFS}, // To test readdirnamesFile
{name: "fstest.MapFS", fs: fstest.FS}, // To test adaptation of ReadDirFile
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
dotF, err := tc.fs.Open(".")
require.NoError(t, err)
defer dotF.Close()
t.Run("dir", func(t *testing.T) {
names, errno := platform.Readdirnames(dotF, -1)
require.EqualErrno(t, 0, errno)
sort.Strings(names)
require.Equal(t, []string{"animals.txt", "dir", "empty.txt", "emptydir", "sub"}, names)
// read again even though it is exhausted
_, errno = platform.Readdirnames(dotF, 100)
require.EqualErrno(t, 0, errno)
})
// Don't err if something else closed the directory while reading.
t.Run("closed dir", func(t *testing.T) {
require.NoError(t, dotF.Close())
_, errno := platform.Readdir(dotF, -1)
require.EqualErrno(t, 0, errno)
})
dirF, err := tc.fs.Open("dir")
require.NoError(t, err)
defer dirF.Close()
t.Run("partial", func(t *testing.T) {
names1, errno := platform.Readdirnames(dirF, 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names1))
names2, errno := platform.Readdirnames(dirF, 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names2))
// read exactly the last entry
names3, errno := platform.Readdirnames(dirF, 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names3))
names := []string{names1[0], names2[0], names3[0]}
sort.Strings(names)
require.Equal(t, []string{"-", "a-", "ab-"}, names)
// no error reading an exhausted directory
_, errno = platform.Readdirnames(dirF, 1)
require.EqualErrno(t, 0, errno)
})
fileF, err := tc.fs.Open("empty.txt")
require.NoError(t, err)
defer fileF.Close()
t.Run("file", func(t *testing.T) {
_, errno := platform.Readdirnames(fileF, -1)
require.EqualErrno(t, syscall.ENOTDIR, errno)
})
subdirF, err := tc.fs.Open("sub")
require.NoError(t, err)
defer subdirF.Close()
t.Run("subdir", func(t *testing.T) {
names, errno := platform.Readdirnames(subdirF, -1)
require.EqualErrno(t, 0, errno)
require.Equal(t, []string{"test.txt"}, names)
})
})
}
}
func TestReaddir(t *testing.T) {
t.Parallel()

View File

@@ -743,7 +743,6 @@ func (f *fsFile) File() fs.File {
// ReadFile declares all read interfaces defined on os.File used by wazero.
type ReadFile interface {
fdFile // for the number of links.
readdirnamesFile
readdirFile
fs.ReadDirFile
io.ReaderAt // for pread
@@ -768,10 +767,6 @@ type (
}
// fdFile is implemented by os.File in file_unix.go and file_windows.go
fdFile interface{ Fd() (fd uintptr) }
// readdirnamesFile is implemented by os.File in dir.go
readdirnamesFile interface {
Readdirnames(n int) (names []string, err error)
}
// readdirFile is implemented by os.File in dir.go
readdirFile interface {
Readdir(n int) ([]fs.FileInfo, error)

View File

@@ -13,7 +13,6 @@ import (
gofstest "testing/fstest"
"github.com/tetratelabs/wazero/internal/fstest"
"github.com/tetratelabs/wazero/internal/platform"
testfs "github.com/tetratelabs/wazero/internal/testing/fs"
"github.com/tetratelabs/wazero/internal/testing/require"
)
@@ -111,18 +110,19 @@ func TestNewRootFS(t *testing.T) {
require.EqualErrno(t, 0, errno)
defer f.Close()
require.Equal(t, []string{"a", "tmp"}, readDirNames(t, f.File()))
entries, err := f.File().(fs.ReadDirFile).ReadDir(-1)
require.NoError(t, err)
names := make([]string, 0, len(entries))
for _, e := range entries {
names = append(names, e.Name())
}
sort.Strings(names)
require.Equal(t, []string{"a", "tmp"}, names)
})
})
}
func readDirNames(t *testing.T, f fs.File) []string {
names, errno := platform.Readdirnames(f, -1)
require.EqualErrno(t, 0, errno)
sort.Strings(names)
return names
}
func TestRootFS_String(t *testing.T) {
tmpFS := NewDirFS(".")
rootFS := NewDirFS(".")

View File

@@ -92,15 +92,6 @@ func testOpen_Read(t *testing.T, testFS FS, expectIno bool) {
}, dirents)
})
t.Run("readdirnames . opens root", func(t *testing.T) {
f, errno := testFS.OpenFile(".", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
names := requireReaddirnames(t, f.File(), -1)
require.Equal(t, []string{"animals.txt", "dir", "empty.txt", "emptydir", "sub"}, names)
})
t.Run("readdir empty", func(t *testing.T) {
f, errno := testFS.OpenFile("emptydir", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -110,15 +101,6 @@ func testOpen_Read(t *testing.T, testFS FS, expectIno bool) {
require.Zero(t, len(entries))
})
t.Run("readdirnames empty", func(t *testing.T) {
f, errno := testFS.OpenFile("emptydir", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer f.Close()
names := requireReaddirnames(t, f.File(), -1)
require.Zero(t, len(names))
})
t.Run("readdir partial", func(t *testing.T) {
dirF, errno := testFS.OpenFile("dir", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -153,36 +135,6 @@ func testOpen_Read(t *testing.T, testFS FS, expectIno bool) {
require.EqualErrno(t, 0, errno)
})
// TODO: consolidate duplicated tests from platform once we have our own
// file type
t.Run("readdirnames partial", func(t *testing.T) {
dirF, errno := testFS.OpenFile("dir", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
defer dirF.Close()
names1, errno := platform.Readdirnames(dirF.File(), 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names1))
names2, errno := platform.Readdirnames(dirF.File(), 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names2))
// read exactly the last entry
names3, errno := platform.Readdirnames(dirF.File(), 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, 1, len(names3))
names := []string{names1[0], names2[0], names3[0]}
sort.Strings(names)
require.Equal(t, []string{"-", "a-", "ab-"}, names)
// no error reading an exhausted directory
_, errno = platform.Readdirnames(dirF.File(), 1)
require.EqualErrno(t, 0, errno)
})
t.Run("file exists", func(t *testing.T) {
f, errno := testFS.OpenFile("animals.txt", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -353,15 +305,6 @@ func requireReaddir(t *testing.T, f fs.File, n int, expectIno bool) []*platform.
return entries
}
// requireReaddirnames ensures the input file is a directory, and returns its
// entries.
func requireReaddirnames(t *testing.T, f fs.File, n int) []string {
names, errno := platform.Readdirnames(f, n)
require.EqualErrno(t, 0, errno)
sort.Strings(names)
return names
}
func testReadlink(t *testing.T, readFS, writeFS FS) {
testLinks := []struct {
old, dst string