--- /dev/null
+// Copyright 2020 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.
+
+// +build darwin dragonfly freebsd netbsd openbsd solaris
+
+// BSD library calls.
+
+package syscall
+
+import (
+ "unsafe"
+)
+
+//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error)
+//sysctl(mib *_C_int, miblen uintptr, old *byte, oldlen *uintptr, new *byte, newlen uintptr) _C_int
+
+//sysnb raw_ptrace(request int, pid int, addr uintptr, data uintptr) (err Errno)
+//ptrace(request _C_int, pid Pid_t, addr *byte, data _C_int) _C_int
+
+//sys paccept(fd int, rsa *RawSockaddrAny, addrlen *Socklen_t, sigmask *_sigset_t, flags int) (nfd int, err error)
+//paccept(s _C_int, rsa *RawSockaddrAny, addrlen *Socklen_t, sigmask *_sigset_t, flags int) _C_int
+
+//sys Flock(fd int, how int) (err error)
+//flock(fd _C_int, how _C_int) _C_int
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+ // Final argument is (basep *uintptr) and the syscall doesn't take nil.
+ // 64 bits should be enough. (32 bits isn't even on 386). Since the
+ // actual system call is getdirentries64, 64 is a good guess.
+ // TODO(rsc): Can we use a single global basep for all calls?
+ var base = (*uintptr)(unsafe.Pointer(new(uint64)))
+ return Getdirentries(fd, buf, base)
+}
+
+func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len Socklen_t = SizeofSockaddrAny
+ nfd, err = paccept(fd, &rsa, &len, nil, flags)
+ if err != nil {
+ return
+ }
+ if len > SizeofSockaddrAny {
+ panic("RawSockaddrAny too small")
+ }
+ sa, err = anyToSockaddr(&rsa)
+ if err != nil {
+ Close(nfd)
+ nfd = 0
+ }
+ return
+}
+
+//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+//pipe2(p *[2]_C_int, flags _C_int) _C_int
+func Pipe2(p []int, flags int) (err error) {
+ if len(p) != 2 {
+ return EINVAL
+ }
+ var pp [2]_C_int
+ err = pipe2(&pp, flags)
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ return
+}
+
+func Sysctl(name string) (value string, err error) {
+ // Translate name to mib number.
+ mib, err := nametomib(name)
+ if err != nil {
+ return "", err
+ }
+
+ // Find size.
+ n := uintptr(0)
+ if err = sysctl(mib, nil, &n, nil, 0); err != nil {
+ return "", err
+ }
+ if n == 0 {
+ return "", nil
+ }
+
+ // Read into buffer of that size.
+ buf := make([]byte, n)
+ if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+ return "", err
+ }
+
+ // Throw away terminating NUL.
+ if n > 0 && buf[n-1] == '\x00' {
+ n--
+ }
+ return string(buf[0:n]), nil
+}
+
+func SysctlUint32(name string) (value uint32, err error) {
+ // Translate name to mib number.
+ mib, err := nametomib(name)
+ if err != nil {
+ return 0, err
+ }
+
+ // Read into buffer of that size.
+ n := uintptr(4)
+ buf := make([]byte, 4)
+ if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+ return 0, err
+ }
+ if n != 4 {
+ return 0, EIO
+ }
+ return *(*uint32)(unsafe.Pointer(&buf[0])), nil
+}
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
}
+//sys Getdents(fd int, buf []byte) (n int, err error)
+//getdents(fd _C_int, buf *byte, nbytes uintptr) _C_int
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+ n, err = Getdents(fd, buf)
+ if err != nil || basep == nil {
+ return
+ }
+
+ var off int64
+ off, err = Seek(fd, 0, 1 /* SEEK_CUR */)
+ if err != nil {
+ *basep = ^uintptr(0)
+ return
+ }
+ *basep = uintptr(off)
+ if unsafe.Sizeof(*basep) == 8 {
+ return
+ }
+ if off>>32 != 0 {
+ // We can't stuff the offset back into a uintptr, so any
+ // future calls would be suspect. Generate an error.
+ // EIO is allowed by getdirentries.
+ err = EIO
+ }
+ return
+}
+
func sysctlNodes(mib []_C_int) (nodes []Sysctlnode, err error) {
var olen uintptr