diff options
author | Nikhil Benesch <nikhil.benesch@gmail.com> | 2020-10-26 17:48:32 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-10-26 15:04:16 -0700 |
commit | a573530d500d7c22e27c0727b1f7abcbc0b73e1d (patch) | |
tree | 1c866623421dc43728e68c0269304bc96bca05e4 /libgo | |
parent | 48722d158cbf692c24025e345ecbbbb570f66aa5 (diff) | |
download | gcc-a573530d500d7c22e27c0727b1f7abcbc0b73e1d.zip gcc-a573530d500d7c22e27c0727b1f7abcbc0b73e1d.tar.gz gcc-a573530d500d7c22e27c0727b1f7abcbc0b73e1d.tar.bz2 |
syscall: import additional BSD-specific syscall wrappers
Import additional code from upstream for handing system
calls on BSD systems. This makes the syscall package on
NetBSD complete enough to compile the standard library.
Updates golang/go#38538.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/265123
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/go/syscall/libcall_bsd.go | 113 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_netbsd.go | 28 |
2 files changed, 141 insertions, 0 deletions
diff --git a/libgo/go/syscall/libcall_bsd.go b/libgo/go/syscall/libcall_bsd.go new file mode 100644 index 0000000..f13d3bc --- /dev/null +++ b/libgo/go/syscall/libcall_bsd.go @@ -0,0 +1,113 @@ +// 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 +} diff --git a/libgo/go/syscall/syscall_netbsd.go b/libgo/go/syscall/syscall_netbsd.go index bbc6799..c3a79e3 100644 --- a/libgo/go/syscall/syscall_netbsd.go +++ b/libgo/go/syscall/syscall_netbsd.go @@ -18,6 +18,34 @@ func direntNamlen(buf []byte) (uint64, bool) { 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 |