From 69fe6d637738e2faaef7968971c1aa9f7ee76490 Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 26 Aug 2025 17:15:43 +0800 Subject: [PATCH] runtime/internal/lib/os: fix readdir for darwin-amd64 --- _demo/readdir/main.go | 10 ++++++ runtime/internal/clite/os/dir.go | 17 ++++++++++ runtime/internal/clite/os/dir_darwin_amd64.go | 17 ++++++++++ runtime/internal/clite/os/dir_unix.go | 20 ++++++++++++ runtime/internal/clite/os/os.go | 6 ---- runtime/internal/clite/os/stat.go | 3 ++ runtime/internal/clite/os/stat_darwin.go | 3 ++ runtime/internal/lib/os/dir.go | 32 ++++--------------- 8 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 runtime/internal/clite/os/dir.go create mode 100644 runtime/internal/clite/os/dir_darwin_amd64.go create mode 100644 runtime/internal/clite/os/dir_unix.go diff --git a/_demo/readdir/main.go b/_demo/readdir/main.go index ed394e64..32899617 100644 --- a/_demo/readdir/main.go +++ b/_demo/readdir/main.go @@ -13,7 +13,17 @@ func main() { if len(entries) == 0 { panic("No files found") } + var check int for _, e := range entries { fmt.Printf("%s isDir[%t]\n", e.Name(), e.IsDir()) + if !e.IsDir() { + switch e.Name() { + case "go.sum", "go.mod": + check++ + } + } + } + if check != 2 { + panic("Bad readdir entries go.mod/go.sum") } } diff --git a/runtime/internal/clite/os/dir.go b/runtime/internal/clite/os/dir.go new file mode 100644 index 00000000..b000aa2f --- /dev/null +++ b/runtime/internal/clite/os/dir.go @@ -0,0 +1,17 @@ +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" +) + +type DIR struct { + Unused [0]byte +} + +//go:linkname Opendir C.opendir +func Opendir(name *c.Char) *DIR + +//go:linkname Closedir C.closedir +func Closedir(dir *DIR) c.Int diff --git a/runtime/internal/clite/os/dir_darwin_amd64.go b/runtime/internal/clite/os/dir_darwin_amd64.go new file mode 100644 index 00000000..ec9c4b5a --- /dev/null +++ b/runtime/internal/clite/os/dir_darwin_amd64.go @@ -0,0 +1,17 @@ +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + "github.com/goplus/llgo/runtime/internal/clite/syscall" +) + +//go:linkname Fdopendir C.fdopendir$INODE64 +func Fdopendir(fd c.Int) *DIR + +//go:linkname Readdir C.readdir$INODE64 +func Readdir(dir *DIR) *syscall.Dirent + +//go:linkname Fstatat C.fstatat$INODE64 +func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int diff --git a/runtime/internal/clite/os/dir_unix.go b/runtime/internal/clite/os/dir_unix.go new file mode 100644 index 00000000..734d18ab --- /dev/null +++ b/runtime/internal/clite/os/dir_unix.go @@ -0,0 +1,20 @@ +//go:build !(darwin && amd64) +// +build !darwin !amd64 + +package os + +import ( + _ "unsafe" + + c "github.com/goplus/llgo/runtime/internal/clite" + "github.com/goplus/llgo/runtime/internal/clite/syscall" +) + +//go:linkname Fdopendir C.fdopendir +func Fdopendir(fd c.Int) *DIR + +//go:linkname Readdir C.readdir +func Readdir(dir *DIR) *syscall.Dirent + +//go:linkname Fstatat C.fstatat +func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int diff --git a/runtime/internal/clite/os/os.go b/runtime/internal/clite/os/os.go index df9a0b17..ee05d416 100644 --- a/runtime/internal/clite/os/os.go +++ b/runtime/internal/clite/os/os.go @@ -135,9 +135,6 @@ func Fchmodat(dirfd c.Int, path *c.Char, mode ModeT, flags c.Int) c.Int //go:linkname Fchownat C.fchownat func Fchownat(dirfd c.Int, path *c.Char, owner UidT, group GidT, flags c.Int) c.Int -//go:linkname Fstatat C.fstatat -func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int - // ----------------------------------------------------------------------------- //go:linkname Open C.open @@ -191,9 +188,6 @@ func Fchmod(fd c.Int, mode ModeT) c.Int //go:linkname Fchown C.fchown func Fchown(fd c.Int, owner UidT, group GidT) c.Int -//go:linkname Fstat C.fstat -func Fstat(fd c.Int, buf *StatT) c.Int - //go:linkname Isatty C.isatty func Isatty(fd c.Int) c.Int diff --git a/runtime/internal/clite/os/stat.go b/runtime/internal/clite/os/stat.go index 2fc00ca6..11c189ed 100644 --- a/runtime/internal/clite/os/stat.go +++ b/runtime/internal/clite/os/stat.go @@ -14,3 +14,6 @@ func Stat(path *c.Char, buf *StatT) c.Int //go:linkname Lstat C.lstat func Lstat(path *c.Char, buf *StatT) c.Int + +//go:linkname Fstat C.fstat +func Fstat(fd c.Int, buf *StatT) c.Int diff --git a/runtime/internal/clite/os/stat_darwin.go b/runtime/internal/clite/os/stat_darwin.go index 0017571e..a0dc6568 100644 --- a/runtime/internal/clite/os/stat_darwin.go +++ b/runtime/internal/clite/os/stat_darwin.go @@ -11,3 +11,6 @@ func Stat(path *c.Char, buf *StatT) c.Int //go:linkname Lstat C.lstat64 func Lstat(path *c.Char, buf *StatT) c.Int + +//go:linkname Fstat C.fstat64 +func Fstat(fd c.Int, buf *StatT) c.Int diff --git a/runtime/internal/lib/os/dir.go b/runtime/internal/lib/os/dir.go index 37840e62..8b353458 100644 --- a/runtime/internal/lib/os/dir.go +++ b/runtime/internal/lib/os/dir.go @@ -82,30 +82,10 @@ func ReadDir(name string) ([]DirEntry, error) { return dirs, err } -//go:linkname c_fdopendir C.fdopendir -func c_fdopendir(fd c.Int) uintptr - -func fdopendir(fd int) (dir uintptr, err error) { - return c_fdopendir(c.Int(fd)), nil -} - -//go:linkname c_closedir C.closedir -func c_closedir(dir uintptr) c.Int - -func closedir(dir uintptr) error { - if c_closedir(dir) != 0 { - return syscall.Errno(os.Errno()) - } - return nil -} - -//go:linkname c_readdir C.readdir -func c_readdir(dir uintptr) *syscall.Dirent - -func readdir(dir uintptr) ([]syscall.Dirent, error) { +func readdir(dir *os.DIR) ([]syscall.Dirent, error) { var entries []syscall.Dirent for { - dirent := c_readdir(dir) + dirent := os.Readdir(dir) if dirent == nil { break } @@ -139,11 +119,11 @@ func (f *File) ReadDir(n int) (dirents []DirEntry, err error) { } // Open directory using file descriptor - dir, err := fdopendir(int(f.fd)) - if err != nil { - return nil, err + dir := os.Fdopendir(c.Int(f.fd)) + if dir == nil { + return nil, syscall.Errno(os.Errno()) } - defer closedir(dir) + defer os.Closedir(dir) // Match Readdir and Readdirnames: don't return nil slices. dirents = []DirEntry{}