aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go')
-rw-r--r--vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
new file mode 100644
index 0000000..1596426
--- /dev/null
+++ b/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
@@ -0,0 +1,108 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && go1.13
+// +build darwin,go1.13
+
+package unix
+
+import (
+ "unsafe"
+
+ "golang.org/x/sys/internal/unsafeheader"
+)
+
+//sys closedir(dir uintptr) (err error)
+//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
+
+func fdopendir(fd int) (dir uintptr, err error) {
+ r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
+ dir = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+var libc_fdopendir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+ // Simulate Getdirentries using fdopendir/readdir_r/closedir.
+ // We store the number of entries to skip in the seek
+ // offset of fd. See issue #31368.
+ // It's not the full required semantics, but should handle the case
+ // of calling Getdirentries or ReadDirent repeatedly.
+ // It won't handle assigning the results of lseek to *basep, or handle
+ // the directory being edited underfoot.
+ skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
+ if err != nil {
+ return 0, err
+ }
+
+ // We need to duplicate the incoming file descriptor
+ // because the caller expects to retain control of it, but
+ // fdopendir expects to take control of its argument.
+ // Just Dup'ing the file descriptor is not enough, as the
+ // result shares underlying state. Use Openat to make a really
+ // new file descriptor referring to the same directory.
+ fd2, err := Openat(fd, ".", O_RDONLY, 0)
+ if err != nil {
+ return 0, err
+ }
+ d, err := fdopendir(fd2)
+ if err != nil {
+ Close(fd2)
+ return 0, err
+ }
+ defer closedir(d)
+
+ var cnt int64
+ for {
+ var entry Dirent
+ var entryp *Dirent
+ e := readdir_r(d, &entry, &entryp)
+ if e != 0 {
+ return n, errnoErr(e)
+ }
+ if entryp == nil {
+ break
+ }
+ if skip > 0 {
+ skip--
+ cnt++
+ continue
+ }
+
+ reclen := int(entry.Reclen)
+ if reclen > len(buf) {
+ // Not enough room. Return for now.
+ // The counter will let us know where we should start up again.
+ // Note: this strategy for suspending in the middle and
+ // restarting is O(n^2) in the length of the directory. Oh well.
+ break
+ }
+
+ // Copy entry into return buffer.
+ var s []byte
+ hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
+ hdr.Data = unsafe.Pointer(&entry)
+ hdr.Cap = reclen
+ hdr.Len = reclen
+ copy(buf, s)
+
+ buf = buf[reclen:]
+ n += reclen
+ cnt++
+ }
+ // Set the seek offset of the input fd to record
+ // how many files we've already returned.
+ _, err = Seek(fd, cnt, 0 /* SEEK_SET */)
+ if err != nil {
+ return n, err
+ }
+
+ return n, nil
+}

Snix LLC Git Repository Holder Copyright(C) 2022 All Rights Reserved Email To Snix.IR