aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/syscall
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-11 14:53:56 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-11 15:01:19 -0800
commit8dc2499aa62f768c6395c9754b8cabc1ce25c494 (patch)
tree43d7fd2bbfd7ad8c9625a718a5e8718889351994 /libgo/go/syscall
parent9a56779dbc4e2d9c15be8d31e36f2f59be7331a8 (diff)
downloadgcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.zip
gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.gz
gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.bz2
libgo: update to Go1.18beta2
gotools/ * Makefile.am (go_cmd_cgo_files): Add ast_go118.go (check-go-tool): Copy golang.org/x/tools directories. * Makefile.in: Regenerate. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/384695
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r--libgo/go/syscall/asan0.go19
-rw-r--r--libgo/go/syscall/bpf_bsd.go1
-rw-r--r--libgo/go/syscall/creds_test.go1
-rw-r--r--libgo/go/syscall/dirent.go1
-rw-r--r--libgo/go/syscall/dirent_test.go40
-rw-r--r--libgo/go/syscall/endian_big.go3
-rw-r--r--libgo/go/syscall/endian_little.go3
-rw-r--r--libgo/go/syscall/env_unix.go1
-rw-r--r--libgo/go/syscall/exec_bsd.go43
-rw-r--r--libgo/go/syscall/exec_freebsd.go294
-rw-r--r--libgo/go/syscall/exec_linux.go35
-rw-r--r--libgo/go/syscall/exec_linux_test.go21
-rw-r--r--libgo/go/syscall/exec_pdeathsig_test.go134
-rw-r--r--libgo/go/syscall/exec_unix.go21
-rw-r--r--libgo/go/syscall/exec_unix_test.go2
-rw-r--r--libgo/go/syscall/exec_windows.go8
-rw-r--r--libgo/go/syscall/export_unix_test.go3
-rw-r--r--libgo/go/syscall/forkpipe.go1
-rw-r--r--libgo/go/syscall/forkpipe2.go1
-rw-r--r--libgo/go/syscall/fs_js.go5
-rw-r--r--libgo/go/syscall/getdirentries_test.go1
-rw-r--r--libgo/go/syscall/js/export_test.go2
-rw-r--r--libgo/go/syscall/js/func.go8
-rw-r--r--libgo/go/syscall/js/js.go37
-rw-r--r--libgo/go/syscall/js/js_test.go20
-rw-r--r--libgo/go/syscall/mkasm.go1
-rw-r--r--libgo/go/syscall/mmap_unix_test.go1
-rw-r--r--libgo/go/syscall/msan0.go1
-rw-r--r--libgo/go/syscall/net_js.go4
-rw-r--r--libgo/go/syscall/netlink_linux.go25
-rw-r--r--libgo/go/syscall/route_bsd.go1
-rw-r--r--libgo/go/syscall/route_freebsd_32bit.go1
-rw-r--r--libgo/go/syscall/route_freebsd_64bit.go1
-rw-r--r--libgo/go/syscall/setuidgid_32_linux.go2
-rw-r--r--libgo/go/syscall/setuidgid_linux.go1
-rw-r--r--libgo/go/syscall/sockcmsg_unix.go1
-rw-r--r--libgo/go/syscall/sockcmsg_unix_other.go1
-rw-r--r--libgo/go/syscall/socket.go150
-rw-r--r--libgo/go/syscall/syscall_dragonfly.go2
-rw-r--r--libgo/go/syscall/syscall_freebsd_test.go12
-rw-r--r--libgo/go/syscall/syscall_js.go1
-rw-r--r--libgo/go/syscall/syscall_linux_mipsx.go2
-rw-r--r--libgo/go/syscall/syscall_linux_test.go117
-rw-r--r--libgo/go/syscall/syscall_ptrace_test.go1
-rw-r--r--libgo/go/syscall/syscall_solaris.go2
-rw-r--r--libgo/go/syscall/syscall_unix.go7
-rw-r--r--libgo/go/syscall/syscall_unix_test.go21
-rw-r--r--libgo/go/syscall/tables_js.go1
-rw-r--r--libgo/go/syscall/time_fake.go1
-rw-r--r--libgo/go/syscall/time_nofake.go1
-rw-r--r--libgo/go/syscall/timestruct.go1
51 files changed, 728 insertions, 336 deletions
diff --git a/libgo/go/syscall/asan0.go b/libgo/go/syscall/asan0.go
new file mode 100644
index 0000000..08bc44d
--- /dev/null
+++ b/libgo/go/syscall/asan0.go
@@ -0,0 +1,19 @@
+// Copyright 2021 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 !asan
+
+package syscall
+
+import (
+ "unsafe"
+)
+
+const asanenabled = false
+
+func asanRead(addr unsafe.Pointer, len int) {
+}
+
+func asanWrite(addr unsafe.Pointer, len int) {
+}
diff --git a/libgo/go/syscall/bpf_bsd.go b/libgo/go/syscall/bpf_bsd.go
index 452d4cf..735c078 100644
--- a/libgo/go/syscall/bpf_bsd.go
+++ b/libgo/go/syscall/bpf_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || netbsd || openbsd
-// +build dragonfly freebsd netbsd openbsd
// Berkeley packet filter for BSD variants
diff --git a/libgo/go/syscall/creds_test.go b/libgo/go/syscall/creds_test.go
index c1a8b51..1ee56fc 100644
--- a/libgo/go/syscall/creds_test.go
+++ b/libgo/go/syscall/creds_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package syscall_test
diff --git a/libgo/go/syscall/dirent.go b/libgo/go/syscall/dirent.go
index 1e95946..504b9fb 100644
--- a/libgo/go/syscall/dirent.go
+++ b/libgo/go/syscall/dirent.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package syscall
diff --git a/libgo/go/syscall/dirent_test.go b/libgo/go/syscall/dirent_test.go
index 71b445b..aeb40e5 100644
--- a/libgo/go/syscall/dirent_test.go
+++ b/libgo/go/syscall/dirent_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package syscall_test
@@ -23,7 +22,7 @@ import (
func TestDirent(t *testing.T) {
const (
- direntBufSize = 2048
+ direntBufSize = 2048 // arbitrary? See https://go.dev/issue/37323.
filenameMinSize = 11
)
@@ -38,23 +37,38 @@ func TestDirent(t *testing.T) {
}
}
- buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8)
+ names := make([]string, 0, 10)
+
fd, err := syscall.Open(d, syscall.O_RDONLY, 0)
if err != nil {
t.Fatalf("syscall.open: %v", err)
}
defer syscall.Close(fd)
- n, err := syscall.ReadDirent(fd, buf)
- if err != nil {
- t.Fatalf("syscall.readdir: %v", err)
- }
- buf = buf[:n]
- names := make([]string, 0, 10)
- for len(buf) > 0 {
- var bc int
- bc, _, names = syscall.ParseDirent(buf, -1, names)
- buf = buf[bc:]
+ buf := bytes.Repeat([]byte{0xCD}, direntBufSize)
+ for {
+ n, err := syscall.ReadDirent(fd, buf)
+ if err == syscall.EINVAL {
+ // On linux, 'man getdents64' says that EINVAL indicates “result buffer is too small”.
+ // Try a bigger buffer.
+ t.Logf("ReadDirent: %v; retrying with larger buffer", err)
+ buf = bytes.Repeat([]byte{0xCD}, len(buf)*2)
+ continue
+ }
+ if err != nil {
+ t.Fatalf("syscall.readdir: %v", err)
+ }
+ t.Logf("ReadDirent: read %d bytes", n)
+ if n == 0 {
+ break
+ }
+
+ var consumed, count int
+ consumed, count, names = syscall.ParseDirent(buf[:n], -1, names)
+ t.Logf("ParseDirent: %d new name(s)", count)
+ if consumed != n {
+ t.Fatalf("ParseDirent: consumed %d bytes; expected %d", consumed, n)
+ }
}
sort.Strings(names)
diff --git a/libgo/go/syscall/endian_big.go b/libgo/go/syscall/endian_big.go
index a38e9c6..e6b1163 100644
--- a/libgo/go/syscall/endian_big.go
+++ b/libgo/go/syscall/endian_big.go
@@ -1,9 +1,8 @@
// Copyright 2016 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 ppc64 || s390x || mips || mips64 || armbe || arm64be || m68k || ppc || mips64p32 || s390 || shbe || sparc || sparc64
-// +build ppc64 s390x mips mips64 armbe arm64be m68k ppc mips64p32 s390 shbe sparc sparc64
package syscall
diff --git a/libgo/go/syscall/endian_little.go b/libgo/go/syscall/endian_little.go
index 2332fa3..63e46d8 100644
--- a/libgo/go/syscall/endian_little.go
+++ b/libgo/go/syscall/endian_little.go
@@ -1,9 +1,8 @@
// Copyright 2016 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 386 || alpha || amd64 || amd64p32 || arm || arm64 || ia64 || ppc64le || mips64le || mipsle || mips64p32le || nios2 || riscv || riscv64 || sh || wasm
-// +build 386 alpha amd64 amd64p32 arm arm64 ia64 ppc64le mips64le mipsle mips64p32le nios2 riscv riscv64 sh wasm
package syscall
diff --git a/libgo/go/syscall/env_unix.go b/libgo/go/syscall/env_unix.go
index 0d95c55..8d82d58 100644
--- a/libgo/go/syscall/env_unix.go
+++ b/libgo/go/syscall/env_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris || plan9
-// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris plan9
// Unix environment variables.
diff --git a/libgo/go/syscall/exec_bsd.go b/libgo/go/syscall/exec_bsd.go
index ad65f63..c05ae13 100644
--- a/libgo/go/syscall/exec_bsd.go
+++ b/libgo/go/syscall/exec_bsd.go
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build aix || darwin || dragonfly || freebsd || hurd || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || hurd || netbsd || openbsd || solaris
package syscall
import (
+ "runtime"
"unsafe"
)
@@ -152,12 +152,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
groups = &gids[0]
}
if !cred.NoSetGroups {
- err2 := setgroups(ngroups, groups)
- if err2 == nil {
- err1 = 0
- } else {
- err1 = err2.(Errno)
- }
+ err1 = raw_setgroups(ngroups, groups)
if err1 != 0 {
goto childerror
}
@@ -185,11 +180,19 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later.
if pipe < nextfd {
- err1 = raw_dup2(pipe, nextfd)
- if err1 != 0 {
- goto childerror
+ switch runtime.GOOS {
+ case "netbsd":
+ err1 = raw_dup3(pipe, nextfd, O_CLOEXEC)
+ if err1 != 0 {
+ goto childerror
+ }
+ default:
+ err1 = raw_dup2(pipe, nextfd)
+ if err1 != 0 {
+ goto childerror
+ }
+ raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
}
- raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
pipe = nextfd
nextfd++
}
@@ -198,11 +201,19 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if nextfd == pipe { // don't stomp on pipe
nextfd++
}
- err1 = raw_dup2(fd[i], nextfd)
- if err1 != 0 {
- goto childerror
+ switch runtime.GOOS {
+ case "netbsd":
+ err1 = raw_dup3(fd[i], nextfd, O_CLOEXEC)
+ if err1 != 0 {
+ goto childerror
+ }
+ default:
+ err1 = raw_dup2(fd[i], nextfd)
+ if err1 != 0 {
+ goto childerror
+ }
+ raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
}
- raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
fd[i] = nextfd
nextfd++
}
diff --git a/libgo/go/syscall/exec_freebsd.go b/libgo/go/syscall/exec_freebsd.go
new file mode 100644
index 0000000..f02f89d
--- /dev/null
+++ b/libgo/go/syscall/exec_freebsd.go
@@ -0,0 +1,294 @@
+// Copyright 2021 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.
+
+package syscall
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+//sysnb raw_procctl(idtype int, id int64, cmd int, data unsafe.Pointer) (ret int, err Errno)
+//procctl(idtype _C_int, id int64, cmd int, data unsafe.Pointer) _C_int
+
+type SysProcAttr struct {
+ Chroot string // Chroot.
+ Credential *Credential // Credential.
+ Ptrace bool // Enable tracing.
+ Setsid bool // Create session.
+ // Setpgid sets the process group ID of the child to Pgid,
+ // or, if Pgid == 0, to the new child's process ID.
+ Setpgid bool
+ // Setctty sets the controlling terminal of the child to
+ // file descriptor Ctty. Ctty must be a descriptor number
+ // in the child process: an index into ProcAttr.Files.
+ // This is only meaningful if Setsid is true.
+ Setctty bool
+ Noctty bool // Detach fd 0 from controlling terminal
+ Ctty int // Controlling TTY fd
+ // Foreground places the child process group in the foreground.
+ // This implies Setpgid. The Ctty field must be set to
+ // the descriptor of the controlling TTY.
+ // Unlike Setctty, in this case Ctty must be a descriptor
+ // number in the parent process.
+ Foreground bool
+ Pgid int // Child's process group ID if Setpgid.
+ Pdeathsig Signal // Signal that the process will get when its parent dies (Linux and FreeBSD only)
+}
+
+const (
+ _P_PID = 0
+
+ _PROC_PDEATHSIG_CTL = 11
+)
+
+// Implemented in runtime package.
+func runtime_BeforeFork()
+func runtime_AfterFork()
+func runtime_AfterForkInChild()
+
+// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
+// If a dup or exec fails, write the errno error to pipe.
+// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
+// In the child, this function must not acquire any locks, because
+// they might have been locked at the time of the fork. This means
+// no rescheduling, no malloc calls, and no new stack segments.
+// For the same reason compiler does not race instrument it.
+// The calls to RawSyscall are okay because they are assembly
+// functions that do not grow the stack.
+//go:norace
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
+ // Declare all variables at top in case any
+ // declarations require heap allocation (e.g., err1).
+ var (
+ r1 Pid_t
+ err1 Errno
+ nextfd int
+ i int
+ )
+
+ // Record parent PID so child can test if it has died.
+ ppid := raw_getpid()
+
+ // guard against side effects of shuffling fds below.
+ // Make sure that nextfd is beyond any currently open files so
+ // that we can't run the risk of overwriting any of them.
+ fd := make([]int, len(attr.Files))
+ nextfd = len(attr.Files)
+ for i, ufd := range attr.Files {
+ if nextfd < int(ufd) {
+ nextfd = int(ufd)
+ }
+ fd[i] = int(ufd)
+ }
+ nextfd++
+
+ // About to call fork.
+ // No more allocation or calls of non-assembly functions.
+ runtime_BeforeFork()
+ r1, err1 = raw_fork()
+ if err1 != 0 {
+ runtime_AfterFork()
+ return 0, err1
+ }
+
+ if r1 != 0 {
+ // parent; return PID
+ runtime_AfterFork()
+ return int(r1), 0
+ }
+
+ // Fork succeeded, now in child.
+
+ // Enable tracing if requested.
+ if sys.Ptrace {
+ err1 = raw_ptrace(_PTRACE_TRACEME, 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Session ID
+ if sys.Setsid {
+ err1 = raw_setsid()
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set process group
+ if sys.Setpgid || sys.Foreground {
+ // Place child in process group.
+ err1 = raw_setpgid(0, sys.Pgid)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ if sys.Foreground {
+ pgrp := Pid_t(sys.Pgid)
+ if pgrp == 0 {
+ pgrp = raw_getpid()
+ }
+
+ // Place process group in foreground.
+ err1 = raw_ioctl(sys.Ctty, TIOCSPGRP, unsafe.Pointner(&pgrp))
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
+ // Chroot
+ if chroot != nil {
+ err1 = raw_chroot(chroot)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // User and groups
+ if cred := sys.Credential; cred != nil {
+ ngroups := len(cred.Groups)
+ var groups *Gid_t
+ if ngroups > 0 {
+ gids := make([]Gid_t, ngroups)
+ for i, v := range cred.Groups {
+ gids[i] = Gid_t(v)
+ }
+ groups = &gids[0]
+ }
+
+ if !cred.NoSetGroups {
+ err1 = raw_setgroups(ngroups, groups)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ err2 := Setgid(int(cred.Gid))
+ if err2 != nil {
+ err1 = err2.(Errno)
+ goto childerror
+ }
+ err2 = Setuid(int(cred.Uid))
+ if err2 != nil {
+ err1 = err2.(Errno)
+ goto childerror
+ }
+
+ }
+
+ // Chdir
+ if dir != nil {
+ err1 = raw_chdir(dir)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Parent death signal
+ if sys.Pdeathsig != 0 {
+ _, err1 = raw_procctl(_P_PID, 0, _PROC_PDEATHSIG_CTL, unsafe.Pointer(&sys.Pdeathsig))
+
+ if err1 != 0 {
+ goto childerror
+ }
+
+ // Signal self if parent is already dead. This might cause a
+ // duplicate signal in rare cases, but it won't matter when
+ // using SIGKILL.
+ r1 = raw_getppid()
+ if r1 != ppid {
+ pid := raw_getpid()
+ err1 = raw_kill(pid, sys.Pdeathsig)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ }
+
+ // Pass 1: look for fd[i] < i and move those up above len(fd)
+ // so that pass 2 won't stomp on an fd it needs later.
+ if pipe < nextfd {
+ _, err1 = raw_fcntl(pipe, _F_DUP2FD_CLOEXEC, nextfd)
+ if err1 != 0 {
+ goto childerror
+ }
+ pipe = nextfd
+ nextfd++
+ }
+ for i = 0; i < len(fd); i++ {
+ if fd[i] >= 0 && fd[i] < int(i) {
+ if nextfd == pipe { // don't stomp on pipe
+ nextfd++
+ }
+ err1 = raw_fcntl(fd[i], _F_DUP2FD_CLOEXEC, nextfd)
+ if err1 != 0 {
+ goto childerror
+ }
+ fd[i] = nextfd
+ nextfd++
+ }
+ }
+
+ // Pass 2: dup fd[i] down onto i.
+ for i = 0; i < len(fd); i++ {
+ if fd[i] == -1 {
+ raw_close(i)
+ continue
+ }
+ if fd[i] == int(i) {
+ // dup2(i, i) won't clear close-on-exec flag on Linux,
+ // probably not elsewhere either.
+ _, err1 = raw_fcntl(fd[i], _F_SETFD, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ continue
+ }
+ // The new fd is created NOT close-on-exec,
+ // which is exactly what we want.
+ err1 = raw_dup2(fd[i], i)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // By convention, we don't close-on-exec the fds we are
+ // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
+ // Programs that know they inherit fds >= 3 will need
+ // to set them close-on-exec.
+ for i = len(fd); i < 3; i++ {
+ raw_close(i)
+ }
+
+ // Detach fd 0 from tty
+ if sys.Noctty {
+ _, err = raw_ioctl(0, TIOCNOTTY, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set the controlling TTY to Ctty
+ if sys.Setctty {
+ _, err1 = raw_ioctl(sys.Cty, TIOCSCTTY, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Time to exec.
+ err1 = raw_execve(argv0, &argv[0], &envv[0])
+
+childerror:
+ // send error code on pipe
+ raw_write(pipe, (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
+ for {
+ raw_exit(253)
+ }
+}
diff --git a/libgo/go/syscall/exec_linux.go b/libgo/go/syscall/exec_linux.go
index c9be86b..86fb8e8 100644
--- a/libgo/go/syscall/exec_linux.go
+++ b/libgo/go/syscall/exec_linux.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package syscall
@@ -57,7 +56,7 @@ type SysProcAttr struct {
// number in the parent process.
Foreground bool
Pgid int // Child's process group ID if Setpgid.
- Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only)
+ Pdeathsig Signal // Signal that the process will get when its parent dies (Linux and FreeBSD only)
Cloneflags uintptr // Flags for clone calls (Linux only)
Unshareflags uintptr // Flags for unshare calls (Linux only)
UidMappings []SysProcIDMap // User ID mappings for user namespaces.
@@ -459,13 +458,7 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
// so that pass 2 won't stomp on an fd it needs later.
if pipe < nextfd {
err1 = raw_dup3(pipe, nextfd, O_CLOEXEC)
- if err1 == ENOSYS {
- err1 = raw_dup2(pipe, nextfd)
- if err1 != 0 {
- goto childerror
- }
- raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
- } else if err1 != 0 {
+ if err1 != 0 {
goto childerror
}
pipe = nextfd
@@ -477,13 +470,7 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
nextfd++
}
err1 = raw_dup3(fd[i], nextfd, O_CLOEXEC)
- if err1 == ENOSYS {
- err1 = raw_dup2(fd[i], nextfd)
- if err1 != 0 {
- goto childerror
- }
- raw_fcntl(nextfd, F_SETFD, FD_CLOEXEC)
- } else if err1 != 0 {
+ if err1 != 0 {
goto childerror
}
fd[i] = nextfd
@@ -508,7 +495,7 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
}
// The new fd is created NOT close-on-exec,
// which is exactly what we want.
- err1 = raw_dup2(fd[i], i)
+ err1 = raw_dup3(fd[i], i, 0)
if err1 != 0 {
goto childerror
}
@@ -561,19 +548,7 @@ childerror:
// Try to open a pipe with O_CLOEXEC set on both file descriptors.
func forkExecPipe(p []int) (err error) {
- err = Pipe2(p, O_CLOEXEC)
- // pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
- // might not be implemented.
- if err == ENOSYS {
- if err = Pipe(p); err != nil {
- return
- }
- if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
- return
- }
- _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
- }
- return
+ return Pipe2(p, O_CLOEXEC)
}
func formatIDMappings(idMap []SysProcIDMap) []byte {
diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go
index ec0a4c0..abe6fdb 100644
--- a/libgo/go/syscall/exec_linux_test.go
+++ b/libgo/go/syscall/exec_linux_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux
-// +build linux
package syscall_test
@@ -111,14 +110,6 @@ func checkUserNS(t *testing.T) {
t.Skip("kernel doesn't support user namespaces")
}
}
-
- // When running under the Go continuous build, skip tests for
- // now when under Kubernetes. (where things are root but not quite)
- // Both of these are our own environment variables.
- // See Issue 12815.
- if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
- t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
- }
}
func whoamiCmd(t *testing.T, uid, gid int, setgroups bool) *exec.Cmd {
@@ -201,14 +192,6 @@ func TestUnshare(t *testing.T) {
t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace")
}
- // When running under the Go continuous build, skip tests for
- // now when under Kubernetes. (where things are root but not quite)
- // Both of these are our own environment variables.
- // See Issue 12815.
- if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" {
- t.Skip("skipping test on Kubernetes-based builders; see Issue 12815")
- }
-
path := "/proc/net/dev"
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
@@ -526,9 +509,7 @@ func mustSupportAmbientCaps(t *testing.T) {
buf[i] = byte(b)
}
ver := string(buf[:])
- if i := strings.Index(ver, "\x00"); i != -1 {
- ver = ver[:i]
- }
+ ver, _, _ = strings.Cut(ver, "\x00")
if strings.HasPrefix(ver, "2.") ||
strings.HasPrefix(ver, "3.") ||
strings.HasPrefix(ver, "4.1.") ||
diff --git a/libgo/go/syscall/exec_pdeathsig_test.go b/libgo/go/syscall/exec_pdeathsig_test.go
new file mode 100644
index 0000000..96ae27b
--- /dev/null
+++ b/libgo/go/syscall/exec_pdeathsig_test.go
@@ -0,0 +1,134 @@
+// Copyright 2015 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 freebsd || linux
+
+package syscall_test
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "os/signal"
+ "path/filepath"
+ "syscall"
+ "testing"
+ "time"
+)
+
+func TestDeathSignal(t *testing.T) {
+ if os.Getuid() != 0 {
+ t.Skip("skipping root only test")
+ }
+
+ // Copy the test binary to a location that a non-root user can read/execute
+ // after we drop privileges
+ tempDir, err := os.MkdirTemp("", "TestDeathSignal")
+ if err != nil {
+ t.Fatalf("cannot create temporary directory: %v", err)
+ }
+ defer os.RemoveAll(tempDir)
+ os.Chmod(tempDir, 0755)
+
+ tmpBinary := filepath.Join(tempDir, filepath.Base(os.Args[0]))
+
+ src, err := os.Open(os.Args[0])
+ if err != nil {
+ t.Fatalf("cannot open binary %q, %v", os.Args[0], err)
+ }
+ defer src.Close()
+
+ dst, err := os.OpenFile(tmpBinary, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
+ if err != nil {
+ t.Fatalf("cannot create temporary binary %q, %v", tmpBinary, err)
+ }
+ if _, err := io.Copy(dst, src); err != nil {
+ t.Fatalf("failed to copy test binary to %q, %v", tmpBinary, err)
+ }
+ err = dst.Close()
+ if err != nil {
+ t.Fatalf("failed to close test binary %q, %v", tmpBinary, err)
+ }
+
+ cmd := exec.Command(tmpBinary)
+ cmd.Env = append(os.Environ(), "GO_DEATHSIG_PARENT=1")
+ chldStdin, err := cmd.StdinPipe()
+ if err != nil {
+ t.Fatalf("failed to create new stdin pipe: %v", err)
+ }
+ chldStdout, err := cmd.StdoutPipe()
+ if err != nil {
+ t.Fatalf("failed to create new stdout pipe: %v", err)
+ }
+ cmd.Stderr = os.Stderr
+
+ err = cmd.Start()
+ defer cmd.Wait()
+ if err != nil {
+ t.Fatalf("failed to start first child process: %v", err)
+ }
+
+ chldPipe := bufio.NewReader(chldStdout)
+
+ if got, err := chldPipe.ReadString('\n'); got == "start\n" {
+ syscall.Kill(cmd.Process.Pid, syscall.SIGTERM)
+
+ go func() {
+ time.Sleep(5 * time.Second)
+ chldStdin.Close()
+ }()
+
+ want := "ok\n"
+ if got, err = chldPipe.ReadString('\n'); got != want {
+ t.Fatalf("expected %q, received %q, %v", want, got, err)
+ }
+ } else {
+ t.Fatalf("did not receive start from child, received %q, %v", got, err)
+ }
+}
+
+func deathSignalParent() {
+ cmd := exec.Command(os.Args[0])
+ cmd.Env = append(os.Environ(),
+ "GO_DEATHSIG_PARENT=",
+ "GO_DEATHSIG_CHILD=1",
+ )
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ attrs := syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGUSR1,
+ // UID/GID 99 is the user/group "nobody" on RHEL/Fedora and is
+ // unused on Ubuntu
+ Credential: &syscall.Credential{Uid: 99, Gid: 99},
+ }
+ cmd.SysProcAttr = &attrs
+
+ err := cmd.Start()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "death signal parent error: %v\n", err)
+ os.Exit(1)
+ }
+ cmd.Wait()
+ os.Exit(0)
+}
+
+func deathSignalChild() {
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, syscall.SIGUSR1)
+ go func() {
+ <-c
+ fmt.Println("ok")
+ os.Exit(0)
+ }()
+ fmt.Println("start")
+
+ buf := make([]byte, 32)
+ os.Stdin.Read(buf)
+
+ // We expected to be signaled before stdin closed
+ fmt.Println("not ok")
+ os.Exit(1)
+}
diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go
index 7e01648..c99171b 100644
--- a/libgo/go/syscall/exec_unix.go
+++ b/libgo/go/syscall/exec_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
// Fork, exec, wait, etc.
@@ -210,9 +209,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
sys = &zeroSysProcAttr
}
- p[0] = -1
- p[1] = -1
-
// Convert args to C form.
argv0p, err := BytePtrFromString(argv0)
if err != nil {
@@ -262,14 +258,17 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
// Allocate child status pipe close on exec.
if err = forkExecPipe(p[:]); err != nil {
- goto error
+ ForkLock.Unlock()
+ return 0, err
}
// Kick off child.
pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
if err1 != 0 {
- err = Errno(err1)
- goto error
+ Close(p[0])
+ Close(p[1])
+ ForkLock.Unlock()
+ return 0, Errno(err1)
}
ForkLock.Unlock()
@@ -301,14 +300,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
// Read got EOF, so pipe closed on exec, so exec succeeded.
return pid, nil
-
-error:
- if p[0] >= 0 {
- Close(p[0])
- Close(p[1])
- }
- ForkLock.Unlock()
- return 0, err
}
// Combination of fork and exec, careful to be thread safe.
diff --git a/libgo/go/syscall/exec_unix_test.go b/libgo/go/syscall/exec_unix_test.go
index 3b78d20..29fd760 100644
--- a/libgo/go/syscall/exec_unix_test.go
+++ b/libgo/go/syscall/exec_unix_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package syscall_test
@@ -329,7 +328,6 @@ func TestExecHelper(t *testing.T) {
// We don't have to worry about restoring these values.
// We are in a child process that only runs this test,
// and we are going to call syscall.Exec anyhow.
- runtime.GOMAXPROCS(50)
os.Setenv("GO_WANT_HELPER_PROCESS", "3")
stop := time.Now().Add(time.Second)
diff --git a/libgo/go/syscall/exec_windows.go b/libgo/go/syscall/exec_windows.go
index 18d1502..9d10d6a 100644
--- a/libgo/go/syscall/exec_windows.go
+++ b/libgo/go/syscall/exec_windows.go
@@ -390,8 +390,10 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
}
fd = fd[:j]
+ willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles
+
// Do not accidentally inherit more than these handles.
- if len(fd) > 0 {
+ if willInheritHandles {
err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_HANDLE_LIST, unsafe.Pointer(&fd[0]), uintptr(len(fd))*unsafe.Sizeof(fd[0]), nil, nil)
if err != nil {
return 0, 0, err
@@ -401,9 +403,9 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
pi := new(ProcessInformation)
flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
if sys.Token != 0 {
- err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
+ err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
} else {
- err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, len(fd) > 0 && !sys.NoInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
+ err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
}
if err != nil {
return 0, 0, err
diff --git a/libgo/go/syscall/export_unix_test.go b/libgo/go/syscall/export_unix_test.go
index f32118b5..184eb84 100644
--- a/libgo/go/syscall/export_unix_test.go
+++ b/libgo/go/syscall/export_unix_test.go
@@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//go:build dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build dragonfly freebsd hurd linux netbsd openbsd solaris
+//go:build dragonfly || freebsd || hurd || linux || netbsd || openbsd
package syscall
diff --git a/libgo/go/syscall/forkpipe.go b/libgo/go/syscall/forkpipe.go
index 79cbdf4..6f7d29c 100644
--- a/libgo/go/syscall/forkpipe.go
+++ b/libgo/go/syscall/forkpipe.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || solaris
-// +build aix darwin solaris
package syscall
diff --git a/libgo/go/syscall/forkpipe2.go b/libgo/go/syscall/forkpipe2.go
index bdffdcd..01c8048 100644
--- a/libgo/go/syscall/forkpipe2.go
+++ b/libgo/go/syscall/forkpipe2.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build dragonfly || freebsd || hurd || netbsd || openbsd
-// +build dragonfly freebsd hurd netbsd openbsd
package syscall
diff --git a/libgo/go/syscall/fs_js.go b/libgo/go/syscall/fs_js.go
index 0170516..3541446 100644
--- a/libgo/go/syscall/fs_js.go
+++ b/libgo/go/syscall/fs_js.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build js && wasm
-// +build js,wasm
package syscall
@@ -492,14 +491,14 @@ func Pipe(fd []int) error {
return ENOSYS
}
-func fsCall(name string, args ...interface{}) (js.Value, error) {
+func fsCall(name string, args ...any) (js.Value, error) {
type callResult struct {
val js.Value
err error
}
c := make(chan callResult, 1)
- f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ f := js.FuncOf(func(this js.Value, args []js.Value) any {
var res callResult
if len(args) >= 1 { // on Node.js 8, fs.utimes calls the callback without any arguments
diff --git a/libgo/go/syscall/getdirentries_test.go b/libgo/go/syscall/getdirentries_test.go
index 814e656..ddd8208 100644
--- a/libgo/go/syscall/getdirentries_test.go
+++ b/libgo/go/syscall/getdirentries_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || freebsd || netbsd || openbsd
-// +build darwin freebsd netbsd openbsd
package syscall_test
diff --git a/libgo/go/syscall/js/export_test.go b/libgo/go/syscall/js/export_test.go
index 1b5ed3c..fb61dae 100644
--- a/libgo/go/syscall/js/export_test.go
+++ b/libgo/go/syscall/js/export_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build js,wasm
+//go:build js && wasm
package js
diff --git a/libgo/go/syscall/js/func.go b/libgo/go/syscall/js/func.go
index da4cf68..cc94972 100644
--- a/libgo/go/syscall/js/func.go
+++ b/libgo/go/syscall/js/func.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build js,wasm
+//go:build js && wasm
package js
@@ -10,12 +10,10 @@ import "sync"
var (
funcsMu sync.Mutex
- funcs = make(map[uint32]func(Value, []Value) interface{})
+ funcs = make(map[uint32]func(Value, []Value) any)
nextFuncID uint32 = 1
)
-var _ Wrapper = Func{} // Func must implement Wrapper
-
// Func is a wrapped Go function to be called by JavaScript.
type Func struct {
Value // the JavaScript function that invokes the Go function
@@ -40,7 +38,7 @@ type Func struct {
// new goroutine.
//
// Func.Release must be called to free up resources when the function will not be invoked any more.
-func FuncOf(fn func(this Value, args []Value) interface{}) Func {
+func FuncOf(fn func(this Value, args []Value) any) Func {
funcsMu.Lock()
id := nextFuncID
nextFuncID++
diff --git a/libgo/go/syscall/js/js.go b/libgo/go/syscall/js/js.go
index a48bbd4..a5210fa 100644
--- a/libgo/go/syscall/js/js.go
+++ b/libgo/go/syscall/js/js.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build js,wasm
+//go:build js && wasm
// Package js gives access to the WebAssembly host environment when using the js/wasm architecture.
// Its API is based on JavaScript semantics.
@@ -27,12 +27,6 @@ type ref uint64
// nanHead are the upper 32 bits of a ref which are set if the value is not encoded as an IEEE 754 number (see above).
const nanHead = 0x7FF80000
-// Wrapper is implemented by types that are backed by a JavaScript value.
-type Wrapper interface {
- // JSValue returns a JavaScript value associated with an object.
- JSValue() Value
-}
-
// Value represents a JavaScript value. The zero value is the JavaScript value "undefined".
// Values can be checked for equality with the Equal method.
type Value struct {
@@ -50,11 +44,6 @@ const (
typeFlagFunction
)
-// JSValue implements Wrapper interface.
-func (v Value) JSValue() Value {
- return v
-}
-
func makeValue(r ref) Value {
var gcPtr *ref
typeFlag := (r >> 32) & 7
@@ -159,12 +148,12 @@ func Global() Value {
// | map[string]interface{} | new object |
//
// Panics if x is not one of the expected types.
-func ValueOf(x interface{}) Value {
+func ValueOf(x any) Value {
switch x := x.(type) {
- case Value: // should precede Wrapper to avoid a loop
+ case Value:
return x
- case Wrapper:
- return x.JSValue()
+ case Func:
+ return x.Value
case nil:
return valueNull
case bool:
@@ -203,13 +192,13 @@ func ValueOf(x interface{}) Value {
return floatValue(x)
case string:
return makeValue(stringVal(x))
- case []interface{}:
+ case []any:
a := arrayConstructor.New(len(x))
for i, s := range x {
a.SetIndex(i, s)
}
return a
- case map[string]interface{}:
+ case map[string]any:
o := objectConstructor.New()
for k, v := range x {
o.Set(k, v)
@@ -307,7 +296,7 @@ func valueGet(v ref, p string) ref
// Set sets the JavaScript property p of value v to ValueOf(x).
// It panics if v is not a JavaScript object.
-func (v Value) Set(p string, x interface{}) {
+func (v Value) Set(p string, x any) {
if vType := v.Type(); !vType.isObject() {
panic(&ValueError{"Value.Set", vType})
}
@@ -346,7 +335,7 @@ func valueIndex(v ref, i int) ref
// SetIndex sets the JavaScript index i of value v to ValueOf(x).
// It panics if v is not a JavaScript object.
-func (v Value) SetIndex(i int, x interface{}) {
+func (v Value) SetIndex(i int, x any) {
if vType := v.Type(); !vType.isObject() {
panic(&ValueError{"Value.SetIndex", vType})
}
@@ -358,7 +347,7 @@ func (v Value) SetIndex(i int, x interface{}) {
func valueSetIndex(v ref, i int, x ref)
-func makeArgs(args []interface{}) ([]Value, []ref) {
+func makeArgs(args []any) ([]Value, []ref) {
argVals := make([]Value, len(args))
argRefs := make([]ref, len(args))
for i, arg := range args {
@@ -385,7 +374,7 @@ func valueLength(v ref) int
// Call does a JavaScript call to the method m of value v with the given arguments.
// It panics if v has no method m.
// The arguments get mapped to JavaScript values according to the ValueOf function.
-func (v Value) Call(m string, args ...interface{}) Value {
+func (v Value) Call(m string, args ...any) Value {
argVals, argRefs := makeArgs(args)
res, ok := valueCall(v.ref, m, argRefs)
runtime.KeepAlive(v)
@@ -407,7 +396,7 @@ func valueCall(v ref, m string, args []ref) (ref, bool)
// Invoke does a JavaScript call of the value v with the given arguments.
// It panics if v is not a JavaScript function.
// The arguments get mapped to JavaScript values according to the ValueOf function.
-func (v Value) Invoke(args ...interface{}) Value {
+func (v Value) Invoke(args ...any) Value {
argVals, argRefs := makeArgs(args)
res, ok := valueInvoke(v.ref, argRefs)
runtime.KeepAlive(v)
@@ -426,7 +415,7 @@ func valueInvoke(v ref, args []ref) (ref, bool)
// New uses JavaScript's "new" operator with value v as constructor and the given arguments.
// It panics if v is not a JavaScript function.
// The arguments get mapped to JavaScript values according to the ValueOf function.
-func (v Value) New(args ...interface{}) Value {
+func (v Value) New(args ...any) Value {
argVals, argRefs := makeArgs(args)
res, ok := valueNew(v.ref, argRefs)
runtime.KeepAlive(v)
diff --git a/libgo/go/syscall/js/js_test.go b/libgo/go/syscall/js/js_test.go
index 5fc9107..f860a5b 100644
--- a/libgo/go/syscall/js/js_test.go
+++ b/libgo/go/syscall/js/js_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build js,wasm
+//go:build js && wasm
// To run these tests:
//
@@ -364,8 +364,8 @@ func TestType(t *testing.T) {
}
}
-type object = map[string]interface{}
-type array = []interface{}
+type object = map[string]any
+type array = []any
func TestValueOf(t *testing.T) {
a := js.ValueOf(array{0, array{0, 42, 0}, 0})
@@ -388,7 +388,7 @@ func TestZeroValue(t *testing.T) {
func TestFuncOf(t *testing.T) {
c := make(chan struct{})
- cb := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ cb := js.FuncOf(func(this js.Value, args []js.Value) any {
if got := args[0].Int(); got != 42 {
t.Errorf("got %#v, want %#v", got, 42)
}
@@ -402,8 +402,8 @@ func TestFuncOf(t *testing.T) {
func TestInvokeFunction(t *testing.T) {
called := false
- cb := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
- cb2 := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ cb := js.FuncOf(func(this js.Value, args []js.Value) any {
+ cb2 := js.FuncOf(func(this js.Value, args []js.Value) any {
called = true
return 42
})
@@ -423,7 +423,7 @@ func TestInterleavedFunctions(t *testing.T) {
c1 := make(chan struct{})
c2 := make(chan struct{})
- js.Global().Get("setTimeout").Invoke(js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ js.Global().Get("setTimeout").Invoke(js.FuncOf(func(this js.Value, args []js.Value) any {
c1 <- struct{}{}
<-c2
return nil
@@ -432,7 +432,7 @@ func TestInterleavedFunctions(t *testing.T) {
<-c1
c2 <- struct{}{}
// this goroutine is running, but the callback of setTimeout did not return yet, invoke another function now
- f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ f := js.FuncOf(func(this js.Value, args []js.Value) any {
return nil
})
f.Invoke()
@@ -440,7 +440,7 @@ func TestInterleavedFunctions(t *testing.T) {
func ExampleFuncOf() {
var cb js.Func
- cb = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ cb = js.FuncOf(func(this js.Value, args []js.Value) any {
fmt.Println("button clicked")
cb.Release() // release the function if the button will not be clicked again
return nil
@@ -593,7 +593,7 @@ func BenchmarkDOM(b *testing.B) {
}
func TestGlobal(t *testing.T) {
- ident := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+ ident := js.FuncOf(func(this js.Value, args []js.Value) any {
return args[0]
})
defer ident.Release()
diff --git a/libgo/go/syscall/mkasm.go b/libgo/go/syscall/mkasm.go
index e0ec466..dce61f3 100644
--- a/libgo/go/syscall/mkasm.go
+++ b/libgo/go/syscall/mkasm.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build ignore
-// +build ignore
// mkasm.go generates assembly trampolines to call library routines from Go.
// This program must be run after mksyscall.pl.
diff --git a/libgo/go/syscall/mmap_unix_test.go b/libgo/go/syscall/mmap_unix_test.go
index f4eb54d..e5f8ffc 100644
--- a/libgo/go/syscall/mmap_unix_test.go
+++ b/libgo/go/syscall/mmap_unix_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd
-// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd
package syscall_test
diff --git a/libgo/go/syscall/msan0.go b/libgo/go/syscall/msan0.go
index 8509702..fba8a5f 100644
--- a/libgo/go/syscall/msan0.go
+++ b/libgo/go/syscall/msan0.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !msan
-// +build !msan
package syscall
diff --git a/libgo/go/syscall/net_js.go b/libgo/go/syscall/net_js.go
index ed46202..2ed4e19 100644
--- a/libgo/go/syscall/net_js.go
+++ b/libgo/go/syscall/net_js.go
@@ -6,7 +6,6 @@
// This file only exists to make the compiler happy.
//go:build js && wasm
-// +build js,wasm
package syscall
@@ -46,8 +45,7 @@ const (
SYS_FCNTL = 500 // unsupported
)
-type Sockaddr interface {
-}
+type Sockaddr any
type SockaddrInet4 struct {
Port int
diff --git a/libgo/go/syscall/netlink_linux.go b/libgo/go/syscall/netlink_linux.go
index 0937ff7..2d81070 100644
--- a/libgo/go/syscall/netlink_linux.go
+++ b/libgo/go/syscall/netlink_linux.go
@@ -55,14 +55,22 @@ func NetlinkRIB(proto, family int) ([]byte, error) {
return nil, err
}
defer Close(s)
- lsa := &SockaddrNetlink{Family: AF_NETLINK}
- if err := Bind(s, lsa); err != nil {
+ sa := &SockaddrNetlink{Family: AF_NETLINK}
+ if err := Bind(s, sa); err != nil {
return nil, err
}
wb := newNetlinkRouteRequest(proto, 1, family)
- if err := Sendto(s, wb, 0, lsa); err != nil {
+ if err := Sendto(s, wb, 0, sa); err != nil {
return nil, err
}
+ lsa, err := Getsockname(s)
+ if err != nil {
+ return nil, err
+ }
+ lsanl, ok := lsa.(*SockaddrNetlink)
+ if !ok {
+ return nil, EINVAL
+ }
var tab []byte
rbNew := make([]byte, Getpagesize())
done:
@@ -82,16 +90,7 @@ done:
return nil, err
}
for _, m := range msgs {
- lsa, err := Getsockname(s)
- if err != nil {
- return nil, err
- }
- switch v := lsa.(type) {
- case *SockaddrNetlink:
- if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
- return nil, EINVAL
- }
- default:
+ if m.Header.Seq != 1 || m.Header.Pid != lsanl.Pid {
return nil, EINVAL
}
if m.Header.Type == NLMSG_DONE {
diff --git a/libgo/go/syscall/route_bsd.go b/libgo/go/syscall/route_bsd.go
index 0dc5fc0..b9d19c5 100644
--- a/libgo/go/syscall/route_bsd.go
+++ b/libgo/go/syscall/route_bsd.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-// +build darwin dragonfly freebsd netbsd openbsd
package syscall
diff --git a/libgo/go/syscall/route_freebsd_32bit.go b/libgo/go/syscall/route_freebsd_32bit.go
index 412833a..c70f0bb 100644
--- a/libgo/go/syscall/route_freebsd_32bit.go
+++ b/libgo/go/syscall/route_freebsd_32bit.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (freebsd && 386) || (freebsd && arm)
-// +build freebsd,386 freebsd,arm
package syscall
diff --git a/libgo/go/syscall/route_freebsd_64bit.go b/libgo/go/syscall/route_freebsd_64bit.go
index 5300bed..9febdfa 100644
--- a/libgo/go/syscall/route_freebsd_64bit.go
+++ b/libgo/go/syscall/route_freebsd_64bit.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build (freebsd && amd64) || (freebsd && arm64)
-// +build freebsd,amd64 freebsd,arm64
package syscall
diff --git a/libgo/go/syscall/setuidgid_32_linux.go b/libgo/go/syscall/setuidgid_32_linux.go
index 4e657c8..cb73fde 100644
--- a/libgo/go/syscall/setuidgid_32_linux.go
+++ b/libgo/go/syscall/setuidgid_32_linux.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux && (386 || arm)
-// +build linux
-// +build 386 arm
package syscall
diff --git a/libgo/go/syscall/setuidgid_linux.go b/libgo/go/syscall/setuidgid_linux.go
index c15090f..4e1804e 100644
--- a/libgo/go/syscall/setuidgid_linux.go
+++ b/libgo/go/syscall/setuidgid_linux.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux && !386 && !arm
-// +build linux,!386,!arm
package syscall
diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go
index aaeecdb..44ef9b8 100644
--- a/libgo/go/syscall/sockcmsg_unix.go
+++ b/libgo/go/syscall/sockcmsg_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
// Socket control messages
diff --git a/libgo/go/syscall/sockcmsg_unix_other.go b/libgo/go/syscall/sockcmsg_unix_other.go
index 0b75b18..6503dbd 100644
--- a/libgo/go/syscall/sockcmsg_unix_other.go
+++ b/libgo/go/syscall/sockcmsg_unix_other.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build aix darwin freebsd hurd linux netbsd openbsd solaris
package syscall
diff --git a/libgo/go/syscall/socket.go b/libgo/go/syscall/socket.go
index f42679d..54a4a99 100644
--- a/libgo/go/syscall/socket.go
+++ b/libgo/go/syscall/socket.go
@@ -12,6 +12,18 @@ package syscall
import "unsafe"
+// These functions are called from the internal/syscall/unix package.
+// Use go:linkname to export them.
+//
+//go:linkname recvfromInet4
+//go:linkname recvfromInet6
+//go:linkname sendtoInet4
+//go:linkname sendtoInet6
+//go:linkname sendmsgNInet4
+//go:linkname sendmsgNInet6
+//go:linkname recvmsgInet4
+//go:linkname recvmsgInet6
+
// For testing: clients can set this flag to force
// creation of IPv6 sockets to return EAFNOSUPPORT.
var SocketDisableIPv6 bool
@@ -332,6 +344,119 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
return
}
+func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) {
+ var rsa RawSockaddrAny
+ var socklen Socklen_t = SizeofSockaddrAny
+ if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.Addr = pp.Addr
+ return
+}
+
+func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) {
+ var rsa RawSockaddrAny
+ var socklen Socklen_t = SizeofSockaddrAny
+ if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.ZoneId = pp.Scope_id
+ from.Addr = pp.Addr
+ return
+}
+
+func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ if err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.Addr = pp.Addr
+ return
+}
+
+func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ if err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.ZoneId = pp.Scope_id
+ from.Addr = pp.Addr
+ return
+}
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ // source address is only specified if the socket is unconnected
+ if rsa.Addr.Family != AF_UNSPEC {
+ from, err = anyToSockaddr(&rsa)
+ }
+ return
+}
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
+ _, err = SendmsgN(fd, p, oob, to, flags)
+ return
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+ var ptr *RawSockaddrAny
+ var salen Socklen_t
+ if to != nil {
+ ptr, salen, err = to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
+ ptr, salen, err := to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
+ ptr, salen, err := to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
+ ptr, n, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ return sendto(fd, p, flags, ptr, n)
+}
+
+func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
+ ptr, n, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ return sendto(fd, p, flags, ptr, n)
+}
+
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
ptr, n, err := to.sockaddr()
if err != nil {
@@ -340,9 +465,8 @@ func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
return sendto(fd, p, flags, ptr, n)
}
-func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
var msg Msghdr
- var rsa RawSockaddrAny
msg.Name = (*byte)(unsafe.Pointer(&rsa))
msg.Namelen = uint32(SizeofSockaddrAny)
var iov Iovec
@@ -372,30 +496,12 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
}
oobn = int(msg.Controllen)
recvflags = int(msg.Flags)
- // source address is only specified if the socket is unconnected
- if rsa.Addr.Family != AF_UNSPEC {
- from, err = anyToSockaddr(&rsa)
- }
- return
-}
-
-func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
- _, err = SendmsgN(fd, p, oob, to, flags)
return
}
-func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
- var ptr *RawSockaddrAny
- var salen Socklen_t
- if to != nil {
- var err error
- ptr, salen, err = to.sockaddr()
- if err != nil {
- return 0, err
- }
- }
+func sendmsgN(fd int, p, oob []byte, to *RawSockaddrAny, salen Socklen_t, flags int) (n int, err error) {
var msg Msghdr
- msg.Name = (*byte)(unsafe.Pointer(ptr))
+ msg.Name = (*byte)(unsafe.Pointer(to))
msg.Namelen = uint32(salen)
var iov Iovec
if len(p) > 0 {
diff --git a/libgo/go/syscall/syscall_dragonfly.go b/libgo/go/syscall/syscall_dragonfly.go
index 930bb46..4b4ed77 100644
--- a/libgo/go/syscall/syscall_dragonfly.go
+++ b/libgo/go/syscall/syscall_dragonfly.go
@@ -9,6 +9,8 @@ import (
"unsafe"
)
+const _SYS_DUP3 = 0
+
// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
var (
osreldateOnce sync.Once
diff --git a/libgo/go/syscall/syscall_freebsd_test.go b/libgo/go/syscall/syscall_freebsd_test.go
index 89c7959..f04b12b 100644
--- a/libgo/go/syscall/syscall_freebsd_test.go
+++ b/libgo/go/syscall/syscall_freebsd_test.go
@@ -3,12 +3,12 @@
// license that can be found in the LICENSE file.
//go:build freebsd
-// +build freebsd
package syscall_test
import (
"fmt"
+ "os"
"syscall"
"testing"
"unsafe"
@@ -53,3 +53,13 @@ func TestConvertFromDirent11(t *testing.T) {
}
}
}
+
+func TestMain(m *testing.M) {
+ if os.Getenv("GO_DEATHSIG_PARENT") == "1" {
+ deathSignalParent()
+ } else if os.Getenv("GO_DEATHSIG_CHILD") == "1" {
+ deathSignalChild()
+ }
+
+ os.Exit(m.Run())
+}
diff --git a/libgo/go/syscall/syscall_js.go b/libgo/go/syscall/syscall_js.go
index ed70d62..cd95499 100644
--- a/libgo/go/syscall/syscall_js.go
+++ b/libgo/go/syscall/syscall_js.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build js && wasm
-// +build js,wasm
package syscall
diff --git a/libgo/go/syscall/syscall_linux_mipsx.go b/libgo/go/syscall/syscall_linux_mipsx.go
index 1df7a5f..809775f 100644
--- a/libgo/go/syscall/syscall_linux_mipsx.go
+++ b/libgo/go/syscall/syscall_linux_mipsx.go
@@ -3,8 +3,6 @@
// license that can be found in the LICENSE file.
//go:build linux && (mips || mipsle || mips64 || mips64le || mips64p32 || mips64p32le)
-// +build linux
-// +build mips mipsle mips64 mips64le mips64p32 mips64p32le
package syscall
diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go
index fd826e9..6be48e2 100644
--- a/libgo/go/syscall/syscall_linux_test.go
+++ b/libgo/go/syscall/syscall_linux_test.go
@@ -5,13 +5,11 @@
package syscall_test
import (
- "bufio"
"fmt"
"io"
"io/fs"
"os"
"os/exec"
- "os/signal"
"path/filepath"
"runtime"
"sort"
@@ -19,7 +17,6 @@ import (
"strings"
"syscall"
"testing"
- "time"
"unsafe"
)
@@ -153,120 +150,6 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
-func TestLinuxDeathSignal(t *testing.T) {
- if os.Getuid() != 0 {
- t.Skip("skipping root only test")
- }
-
- // Copy the test binary to a location that a non-root user can read/execute
- // after we drop privileges
- tempDir, err := os.MkdirTemp("", "TestDeathSignal")
- if err != nil {
- t.Fatalf("cannot create temporary directory: %v", err)
- }
- defer os.RemoveAll(tempDir)
- os.Chmod(tempDir, 0755)
-
- tmpBinary := filepath.Join(tempDir, filepath.Base(os.Args[0]))
-
- src, err := os.Open(os.Args[0])
- if err != nil {
- t.Fatalf("cannot open binary %q, %v", os.Args[0], err)
- }
- defer src.Close()
-
- dst, err := os.OpenFile(tmpBinary, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
- if err != nil {
- t.Fatalf("cannot create temporary binary %q, %v", tmpBinary, err)
- }
- if _, err := io.Copy(dst, src); err != nil {
- t.Fatalf("failed to copy test binary to %q, %v", tmpBinary, err)
- }
- err = dst.Close()
- if err != nil {
- t.Fatalf("failed to close test binary %q, %v", tmpBinary, err)
- }
-
- cmd := exec.Command(tmpBinary)
- cmd.Env = append(os.Environ(), "GO_DEATHSIG_PARENT=1")
- chldStdin, err := cmd.StdinPipe()
- if err != nil {
- t.Fatalf("failed to create new stdin pipe: %v", err)
- }
- chldStdout, err := cmd.StdoutPipe()
- if err != nil {
- t.Fatalf("failed to create new stdout pipe: %v", err)
- }
- cmd.Stderr = os.Stderr
-
- err = cmd.Start()
- defer cmd.Wait()
- if err != nil {
- t.Fatalf("failed to start first child process: %v", err)
- }
-
- chldPipe := bufio.NewReader(chldStdout)
-
- if got, err := chldPipe.ReadString('\n'); got == "start\n" {
- syscall.Kill(cmd.Process.Pid, syscall.SIGTERM)
-
- go func() {
- time.Sleep(5 * time.Second)
- chldStdin.Close()
- }()
-
- want := "ok\n"
- if got, err = chldPipe.ReadString('\n'); got != want {
- t.Fatalf("expected %q, received %q, %v", want, got, err)
- }
- } else {
- t.Fatalf("did not receive start from child, received %q, %v", got, err)
- }
-}
-
-func deathSignalParent() {
- cmd := exec.Command(os.Args[0])
- cmd.Env = append(os.Environ(),
- "GO_DEATHSIG_PARENT=",
- "GO_DEATHSIG_CHILD=1",
- )
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- attrs := syscall.SysProcAttr{
- Pdeathsig: syscall.SIGUSR1,
- // UID/GID 99 is the user/group "nobody" on RHEL/Fedora and is
- // unused on Ubuntu
- Credential: &syscall.Credential{Uid: 99, Gid: 99},
- }
- cmd.SysProcAttr = &attrs
-
- err := cmd.Start()
- if err != nil {
- fmt.Fprintf(os.Stderr, "death signal parent error: %v\n", err)
- os.Exit(1)
- }
- cmd.Wait()
- os.Exit(0)
-}
-
-func deathSignalChild() {
- c := make(chan os.Signal, 1)
- signal.Notify(c, syscall.SIGUSR1)
- go func() {
- <-c
- fmt.Println("ok")
- os.Exit(0)
- }()
- fmt.Println("start")
-
- buf := make([]byte, 32)
- os.Stdin.Read(buf)
-
- // We expected to be signaled before stdin closed
- fmt.Println("not ok")
- os.Exit(1)
-}
-
func TestParseNetlinkMessage(t *testing.T) {
for i, b := range [][]byte{
{103, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 11, 0, 1, 0, 0, 0, 0, 5, 8, 0, 3,
diff --git a/libgo/go/syscall/syscall_ptrace_test.go b/libgo/go/syscall/syscall_ptrace_test.go
index 45729d9..5b128de 100644
--- a/libgo/go/syscall/syscall_ptrace_test.go
+++ b/libgo/go/syscall/syscall_ptrace_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
-// +build darwin dragonfly freebsd linux netbsd openbsd
package syscall_test
diff --git a/libgo/go/syscall/syscall_solaris.go b/libgo/go/syscall/syscall_solaris.go
index 673ba82..13c60a4 100644
--- a/libgo/go/syscall/syscall_solaris.go
+++ b/libgo/go/syscall/syscall_solaris.go
@@ -6,6 +6,8 @@ package syscall
import "unsafe"
+const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
+
func (ts *Timestruc) Unix() (sec int64, nsec int64) {
return int64(ts.Sec), int64(ts.Nsec)
}
diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go
index 730cbfa..bd9b79c 100644
--- a/libgo/go/syscall/syscall_unix.go
+++ b/libgo/go/syscall/syscall_unix.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
package syscall
@@ -157,6 +156,9 @@ func Read(fd int, p []byte) (n int, err error) {
if msanenabled && n > 0 {
msanWrite(unsafe.Pointer(&p[0]), n)
}
+ if asanenabled && n > 0 {
+ asanWrite(unsafe.Pointer(&p[0]), n)
+ }
return
}
@@ -178,6 +180,9 @@ func Write(fd int, p []byte) (n int, err error) {
if msanenabled && n > 0 {
msanRead(unsafe.Pointer(&p[0]), n)
}
+ if asanenabled && n > 0 {
+ asanRead(unsafe.Pointer(&p[0]), n)
+ }
return
}
diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go
index d3d4673..205c600 100644
--- a/libgo/go/syscall/syscall_unix_test.go
+++ b/libgo/go/syscall/syscall_unix_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package syscall_test
@@ -87,16 +86,24 @@ func TestFcntlFlock(t *testing.T) {
if err != nil {
t.Fatalf("Open failed: %v", err)
}
- defer syscall.Close(fd)
- if err := syscall.Ftruncate(fd, 1<<20); err != nil {
+ // f takes ownership of fd, and will close it.
+ //
+ // N.B. This defer is also necessary to keep f alive
+ // while we use its fd, preventing its finalizer from
+ // executing.
+ f := os.NewFile(uintptr(fd), name)
+ defer f.Close()
+
+ if err := syscall.Ftruncate(int(f.Fd()), 1<<20); err != nil {
t.Fatalf("Ftruncate(1<<20) failed: %v", err)
}
- if err := syscall.FcntlFlock(uintptr(fd), syscall.F_SETLK, &flock); err != nil {
+ if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &flock); err != nil {
t.Fatalf("FcntlFlock(F_SETLK) failed: %v", err)
}
+
cmd := exec.Command(os.Args[0], "-test.run=^TestFcntlFlock$")
cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
- cmd.ExtraFiles = []*os.File{os.NewFile(uintptr(fd), name)}
+ cmd.ExtraFiles = []*os.File{f}
out, err := cmd.CombinedOutput()
if len(out) > 0 || err != nil {
t.Fatalf("child process: %q, %v", out, err)
@@ -254,6 +261,10 @@ func passFDChild() {
fmt.Printf("TempFile: %v", err)
return
}
+ // N.B. This defer is also necessary to keep f alive
+ // while we use its fd, preventing its finalizer from
+ // executing.
+ defer f.Close()
f.Write([]byte("Hello from child process!\n"))
f.Seek(0, io.SeekStart)
diff --git a/libgo/go/syscall/tables_js.go b/libgo/go/syscall/tables_js.go
index 64d9584..78a1e71 100644
--- a/libgo/go/syscall/tables_js.go
+++ b/libgo/go/syscall/tables_js.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build js && wasm
-// +build js,wasm
package syscall
diff --git a/libgo/go/syscall/time_fake.go b/libgo/go/syscall/time_fake.go
index cf88aeb..b60fe60 100644
--- a/libgo/go/syscall/time_fake.go
+++ b/libgo/go/syscall/time_fake.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build faketime
-// +build faketime
package syscall
diff --git a/libgo/go/syscall/time_nofake.go b/libgo/go/syscall/time_nofake.go
index 5eaa2da..231875d 100644
--- a/libgo/go/syscall/time_nofake.go
+++ b/libgo/go/syscall/time_nofake.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build !faketime
-// +build !faketime
package syscall
diff --git a/libgo/go/syscall/timestruct.go b/libgo/go/syscall/timestruct.go
index f22c282..3a98985 100644
--- a/libgo/go/syscall/timestruct.go
+++ b/libgo/go/syscall/timestruct.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//go:build aix || darwin || dragonfly || freebsd || hurd || (js && wasm) || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
package syscall