os: implement readdir for darwin and linux

readdir is disabled on linux for 386 and arm until syscall.seek is implemented there.

windows is hard, so leaving that for later.

File src/os/dir_other_go115.go can be deleted when we drop support for go 1.15.

Also adds TestReadNonDir, which was helpful while debugging.
This commit is contained in:
Dan Kegel
2022-01-08 12:28:32 -08:00
committed by Ron Evans
parent 3fa7d6cc40
commit 641a7e5cb9
20 changed files with 972 additions and 67 deletions
+12
View File
@@ -19,6 +19,14 @@ func Close(fd int) (err error) {
return
}
func Dup(fd int) (fd2 int, err error) {
fd2 = int(libc_dup(int32(fd)))
if fd2 < 0 {
err = getErrno()
}
return
}
func Write(fd int, p []byte) (n int, err error) {
buf, count := splitSlice(p)
n = libc_write(int32(fd), buf, uint(count))
@@ -297,6 +305,10 @@ func libc_open(pathname *byte, flags int32, mode uint32) int32
//export close
func libc_close(fd int32) int32
// int dup(int fd)
//export dup
func libc_dup(fd int32) int32
// void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
//export mmap
func libc_mmap(addr unsafe.Pointer, length uintptr, prot, flags, fd int32, offset uintptr) unsafe.Pointer
+52 -1
View File
@@ -40,6 +40,19 @@ func (e Errno) Is(target error) bool {
return false
}
// Source: upstream zerrors_darwin_amd64.go
const (
DT_BLK = 0x6
DT_CHR = 0x2
DT_DIR = 0x4
DT_FIFO = 0x1
DT_LNK = 0xa
DT_REG = 0x8
DT_SOCK = 0xc
DT_UNKNOWN = 0x0
DT_WHT = 0xe
)
// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/errno.h.auto.html
const (
EPERM Errno = 1
@@ -107,6 +120,17 @@ type Timespec struct {
Nsec int64
}
// Source: upstream ztypes_darwin_amd64.go
type Dirent struct {
Ino uint64
Seekoff uint64
Reclen uint16
Namlen uint16
Type uint8
Name [1024]int8
Pad_cgo_0 [3]byte
}
// Go chose Linux's field names for Stat_t, see https://github.com/golang/go/issues/31735
type Stat_t struct {
Dev int32
@@ -190,9 +214,36 @@ func Lstat(path string, p *Stat_t) (err error) {
return
}
// The odd $INODE64 suffix is an Apple compatibility feature, see https://assert.cc/posts/darwin_use_64_bit_inode_vs_ctypes/
func Fdopendir(fd int) (dir uintptr, err error) {
r0 := libc_fdopendir(int32(fd))
dir = uintptr(r0)
if dir == 0 {
err = getErrno()
}
return
}
func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) {
e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result))
if e1 != 0 {
err = getErrno()
}
return
}
// The odd $INODE64 suffix is an Apple compatibility feature, see
// https://assert.cc/posts/darwin_use_64_bit_inode_vs_ctypes/
// and https://github.com/golang/go/issues/35269
// Without it, you get the old, smaller struct stat from mac os 10.2 or so.
// struct DIR * buf fdopendir(int fd);
//export fdopendir$INODE64
func libc_fdopendir(fd int32) unsafe.Pointer
// int readdir_r(struct DIR * buf, struct dirent *entry, struct dirent **result);
//export readdir_r$INODE64
func libc_readdir_r(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32
// int stat(const char *path, struct stat * buf);
//export stat$INODE64
func libc_stat(pathname *byte, ptr unsafe.Pointer) int32
+25
View File
@@ -202,6 +202,31 @@ const (
S_IXUSR = 0x40
)
// dummy
const (
DT_BLK = 0x6
DT_CHR = 0x2
DT_DIR = 0x4
DT_FIFO = 0x1
DT_LNK = 0xa
DT_REG = 0x8
DT_SOCK = 0xc
DT_UNKNOWN = 0x0
DT_WHT = 0xe
)
// dummy
type Dirent struct {
Ino uint64
Reclen uint16
Type uint8
Name [1024]int8
}
func ReadDirent(fd int, buf []byte) (n int, err error) {
return -1, ENOSYS
}
func Stat(path string, p *Stat_t) (err error) {
data := cstring(path)
n := libc_stat(&data[0], unsafe.Pointer(p))