summaryrefslogtreecommitdiff
path: root/libgo/go/syscall
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-18 13:10:34 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-18 13:12:08 -0800
commit20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7 (patch)
tree94aec72c2092a11fa49f0b45da8e036f13416209 /libgo/go/syscall
parent1931cbad498e625b1e24452dcfffe02539b12224 (diff)
downloadgcc-20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7.tar.gz
libgo: update to Go1.18rc1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386594
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r--libgo/go/syscall/syscall_linux_test.go71
-rw-r--r--libgo/go/syscall/syscall_unix_test.go21
2 files changed, 75 insertions, 17 deletions
diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go
index 6be48e24dc7..3169cdda556 100644
--- a/libgo/go/syscall/syscall_linux_test.go
+++ b/libgo/go/syscall/syscall_linux_test.go
@@ -15,6 +15,7 @@ import (
"sort"
"strconv"
"strings"
+ "sync"
"syscall"
"testing"
"unsafe"
@@ -569,3 +570,73 @@ func TestSetuidEtc(t *testing.T) {
}
}
}
+
+// TestAllThreadsSyscallError verifies that errors are properly returned when
+// the syscall fails on the original thread.
+func TestAllThreadsSyscallError(t *testing.T) {
+ // SYS_CAPGET takes pointers as the first two arguments. Since we pass
+ // 0, we expect to get EFAULT back.
+ r1, r2, err := syscall.AllThreadsSyscall(syscall.SYS_CAPGET, 0, 0, 0)
+ if err == syscall.ENOTSUP {
+ t.Skip("AllThreadsSyscall disabled with cgo")
+ }
+ if err != syscall.EFAULT {
+ t.Errorf("AllThreadSyscall(SYS_CAPGET) got %d, %d, %v, want err %v", r1, r2, err, syscall.EFAULT)
+ }
+}
+
+// TestAllThreadsSyscallBlockedSyscall confirms that AllThreadsSyscall
+// can interrupt threads in long-running system calls. This test will
+// deadlock if this doesn't work correctly.
+func TestAllThreadsSyscallBlockedSyscall(t *testing.T) {
+ if _, _, err := syscall.AllThreadsSyscall(syscall.SYS_PRCTL, PR_SET_KEEPCAPS, 0, 0); err == syscall.ENOTSUP {
+ t.Skip("AllThreadsSyscall disabled with cgo")
+ }
+
+ rd, wr, err := os.Pipe()
+ if err != nil {
+ t.Fatalf("unable to obtain a pipe: %v", err)
+ }
+
+ // Perform a blocking read on the pipe.
+ var wg sync.WaitGroup
+ ready := make(chan bool)
+ wg.Add(1)
+ go func() {
+ data := make([]byte, 1)
+
+ // To narrow the window we have to wait for this
+ // goroutine to block in read, synchronize just before
+ // calling read.
+ ready <- true
+
+ // We use syscall.Read directly to avoid the poller.
+ // This will return when the write side is closed.
+ n, err := syscall.Read(int(rd.Fd()), data)
+ if !(n == 0 && err == nil) {
+ t.Errorf("expected read to return 0, got %d, %s", n, err)
+ }
+
+ // Clean up rd and also ensure rd stays reachable so
+ // it doesn't get closed by GC.
+ rd.Close()
+ wg.Done()
+ }()
+ <-ready
+
+ // Loop here to give the goroutine more time to block in read.
+ // Generally this will trigger on the first iteration anyway.
+ pid := syscall.Getpid()
+ for i := 0; i < 100; i++ {
+ if id, _, e := syscall.AllThreadsSyscall(syscall.SYS_GETPID, 0, 0, 0); e != 0 {
+ t.Errorf("[%d] getpid failed: %v", i, e)
+ } else if int(id) != pid {
+ t.Errorf("[%d] getpid got=%d, want=%d", i, id, pid)
+ }
+ // Provide an explicit opportunity for this goroutine
+ // to change Ms.
+ runtime.Gosched()
+ }
+ wr.Close()
+ wg.Wait()
+}
diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go
index 205c6003261..8bfbc934035 100644
--- a/libgo/go/syscall/syscall_unix_test.go
+++ b/libgo/go/syscall/syscall_unix_test.go
@@ -330,8 +330,7 @@ func TestUnixRightsRoundtrip(t *testing.T) {
func TestRlimit(t *testing.T) {
var rlimit, zero syscall.Rlimit
- err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit)
- if err != nil {
+ if err := syscall.Getrlimit(syscall.RLIMIT_CPU, &rlimit); err != nil {
t.Fatalf("Getrlimit: save failed: %v", err)
}
if zero == rlimit {
@@ -339,31 +338,19 @@ func TestRlimit(t *testing.T) {
}
set := rlimit
set.Cur = set.Max - 1
- if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && set.Cur > 4096 {
- // rlim_min for RLIMIT_NOFILE should be equal to
- // or lower than kern.maxfilesperproc, which on
- // some machines are 4096. See #40564.
- set.Cur = 4096
- }
- err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &set)
- if err != nil {
+ if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &set); err != nil {
t.Fatalf("Setrlimit: set failed: %#v %v", set, err)
}
var get syscall.Rlimit
- err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &get)
- if err != nil {
+ if err := syscall.Getrlimit(syscall.RLIMIT_CPU, &get); err != nil {
t.Fatalf("Getrlimit: get failed: %v", err)
}
set = rlimit
set.Cur = set.Max - 1
- if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && set.Cur > 4096 {
- set.Cur = 4096
- }
if set != get {
t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get)
}
- err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit)
- if err != nil {
+ if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &rlimit); err != nil {
t.Fatalf("Setrlimit: restore failed: %#v %v", rlimit, err)
}
}