unix: implement ppoll in terms of poll on Linux

Android's Bionic libc installs a seccomp filter that allows ppoll but
not poll. This has been fine for arm64, where we already implement poll
in terms of ppoll, but not the other architectures, such as amd64, which
runs on Chromebooks, and currently leads to crashes.

This commit implements poll in terms of ppoll on the remaining
architectures and makes this common code, so that everyone uses the more
modern syscall.

Change-Id: Ic01a32b5abe48ab53a2549f592a41561f1684c30
Reviewed-on: https://go-review.googlesource.com/c/sys/+/352310
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go
index 6a2c5cd..e253a91 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -145,6 +145,15 @@
 	return ppoll(&fds[0], len(fds), timeout, sigmask)
 }
 
+func Poll(fds []PollFd, timeout int) (n int, err error) {
+	var ts *Timespec
+	if timeout >= 0 {
+		ts = new(Timespec)
+		*ts = NsecToTimespec(int64(timeout) * 1e6)
+	}
+	return Ppoll(fds, ts, nil)
+}
+
 //sys	Readlinkat(dirfd int, path string, buf []byte) (n int, err error)
 
 func Readlink(path string, buf []byte) (n int, err error) {
diff --git a/unix/syscall_linux_386.go b/unix/syscall_linux_386.go
index 08b3f6a..5f757e8 100644
--- a/unix/syscall_linux_386.go
+++ b/unix/syscall_linux_386.go
@@ -352,12 +352,3 @@
 func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
 	rsa.Service_name_len = uint32(length)
 }
-
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
diff --git a/unix/syscall_linux_amd64.go b/unix/syscall_linux_amd64.go
index dc31a15..4299125 100644
--- a/unix/syscall_linux_amd64.go
+++ b/unix/syscall_linux_amd64.go
@@ -137,15 +137,6 @@
 	rsa.Service_name_len = uint64(length)
 }
 
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
-
 //sys	kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
 
 func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
diff --git a/unix/syscall_linux_arm.go b/unix/syscall_linux_arm.go
index 1d136ba..79edeb9 100644
--- a/unix/syscall_linux_arm.go
+++ b/unix/syscall_linux_arm.go
@@ -227,15 +227,6 @@
 	rsa.Service_name_len = uint32(length)
 }
 
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
-
 //sys	armSyncFileRange(fd int, flags int, off int64, n int64) (err error) = SYS_ARM_SYNC_FILE_RANGE
 
 func SyncFileRange(fd int, off int64, n int64, flags int) error {
diff --git a/unix/syscall_linux_arm64.go b/unix/syscall_linux_arm64.go
index 9c715dc..862890d 100644
--- a/unix/syscall_linux_arm64.go
+++ b/unix/syscall_linux_arm64.go
@@ -185,18 +185,6 @@
 	return err
 }
 
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	var ts *Timespec
-	if timeout >= 0 {
-		ts = new(Timespec)
-		*ts = NsecToTimespec(int64(timeout) * 1e6)
-	}
-	if len(fds) == 0 {
-		return ppoll(nil, 0, ts, nil)
-	}
-	return ppoll(&fds[0], len(fds), ts, nil)
-}
-
 //sys	kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
 
 func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
diff --git a/unix/syscall_linux_mips64x.go b/unix/syscall_linux_mips64x.go
index d47ceaf..8932e34 100644
--- a/unix/syscall_linux_mips64x.go
+++ b/unix/syscall_linux_mips64x.go
@@ -194,12 +194,3 @@
 func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
 	rsa.Service_name_len = uint64(length)
 }
-
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
diff --git a/unix/syscall_linux_mipsx.go b/unix/syscall_linux_mipsx.go
index 27ee4db..7821c25 100644
--- a/unix/syscall_linux_mipsx.go
+++ b/unix/syscall_linux_mipsx.go
@@ -206,12 +206,3 @@
 func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
 	rsa.Service_name_len = uint32(length)
 }
-
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
diff --git a/unix/syscall_linux_ppc.go b/unix/syscall_linux_ppc.go
index 299ba9d..c5053a0 100644
--- a/unix/syscall_linux_ppc.go
+++ b/unix/syscall_linux_ppc.go
@@ -215,15 +215,6 @@
 	rsa.Service_name_len = uint32(length)
 }
 
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
-
 //sys	syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
 
 func SyncFileRange(fd int, off int64, n int64, flags int) error {
diff --git a/unix/syscall_linux_ppc64x.go b/unix/syscall_linux_ppc64x.go
index 0873b07..25786c4 100644
--- a/unix/syscall_linux_ppc64x.go
+++ b/unix/syscall_linux_ppc64x.go
@@ -101,15 +101,6 @@
 	rsa.Service_name_len = uint64(length)
 }
 
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
-
 //sys	syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
 
 func SyncFileRange(fd int, off int64, n int64, flags int) error {
diff --git a/unix/syscall_linux_riscv64.go b/unix/syscall_linux_riscv64.go
index e2c5b32..6f9f710 100644
--- a/unix/syscall_linux_riscv64.go
+++ b/unix/syscall_linux_riscv64.go
@@ -166,18 +166,6 @@
 	return err
 }
 
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	var ts *Timespec
-	if timeout >= 0 {
-		ts = new(Timespec)
-		*ts = NsecToTimespec(int64(timeout) * 1e6)
-	}
-	if len(fds) == 0 {
-		return ppoll(nil, 0, ts, nil)
-	}
-	return ppoll(&fds[0], len(fds), ts, nil)
-}
-
 func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
 	return Renameat2(olddirfd, oldpath, newdirfd, newpath, 0)
 }
diff --git a/unix/syscall_linux_s390x.go b/unix/syscall_linux_s390x.go
index dfa204d..6aa59cb 100644
--- a/unix/syscall_linux_s390x.go
+++ b/unix/syscall_linux_s390x.go
@@ -297,15 +297,6 @@
 	return nil
 }
 
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
-
 //sys	kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
 
 func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
diff --git a/unix/syscall_linux_sparc64.go b/unix/syscall_linux_sparc64.go
index 4c54e09..bbe8d17 100644
--- a/unix/syscall_linux_sparc64.go
+++ b/unix/syscall_linux_sparc64.go
@@ -117,12 +117,3 @@
 func (rsa *RawSockaddrNFCLLCP) SetServiceNameLen(length int) {
 	rsa.Service_name_len = uint64(length)
 }
-
-//sys	poll(fds *PollFd, nfds int, timeout int) (n int, err error)
-
-func Poll(fds []PollFd, timeout int) (n int, err error) {
-	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
-	}
-	return poll(&fds[0], len(fds), timeout)
-}
diff --git a/unix/zsyscall_linux_386.go b/unix/zsyscall_linux_386.go
index 7f3eccf..ff90c81 100644
--- a/unix/zsyscall_linux_386.go
+++ b/unix/zsyscall_linux_386.go
@@ -524,14 +524,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
diff --git a/unix/zsyscall_linux_amd64.go b/unix/zsyscall_linux_amd64.go
index c1c9ac4..fa7d3db 100644
--- a/unix/zsyscall_linux_amd64.go
+++ b/unix/zsyscall_linux_amd64.go
@@ -679,17 +679,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(cmdline)
diff --git a/unix/zsyscall_linux_arm.go b/unix/zsyscall_linux_arm.go
index d89b8be..654f915 100644
--- a/unix/zsyscall_linux_arm.go
+++ b/unix/zsyscall_linux_arm.go
@@ -639,17 +639,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func armSyncFileRange(fd int, flags int, off int64, n int64) (err error) {
 	_, _, e1 := Syscall6(SYS_ARM_SYNC_FILE_RANGE, uintptr(fd), uintptr(flags), uintptr(off), uintptr(off>>32), uintptr(n), uintptr(n>>32))
 	if e1 != 0 {
diff --git a/unix/zsyscall_linux_mips.go b/unix/zsyscall_linux_mips.go
index 9e609dd..6d15528 100644
--- a/unix/zsyscall_linux_mips.go
+++ b/unix/zsyscall_linux_mips.go
@@ -702,14 +702,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
diff --git a/unix/zsyscall_linux_mips64.go b/unix/zsyscall_linux_mips64.go
index 46b1d82..1e20d72 100644
--- a/unix/zsyscall_linux_mips64.go
+++ b/unix/zsyscall_linux_mips64.go
@@ -696,14 +696,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
diff --git a/unix/zsyscall_linux_mips64le.go b/unix/zsyscall_linux_mips64le.go
index ab2f9db..82b5e2d 100644
--- a/unix/zsyscall_linux_mips64le.go
+++ b/unix/zsyscall_linux_mips64le.go
@@ -696,14 +696,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
diff --git a/unix/zsyscall_linux_mipsle.go b/unix/zsyscall_linux_mipsle.go
index 0d4a48b..a0440c1 100644
--- a/unix/zsyscall_linux_mipsle.go
+++ b/unix/zsyscall_linux_mipsle.go
@@ -702,14 +702,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
diff --git a/unix/zsyscall_linux_ppc.go b/unix/zsyscall_linux_ppc.go
index 078f1cc..5864b9c 100644
--- a/unix/zsyscall_linux_ppc.go
+++ b/unix/zsyscall_linux_ppc.go
@@ -685,17 +685,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
 	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off>>32), uintptr(off), uintptr(n>>32), uintptr(n))
 	if e1 != 0 {
diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go
index 791efbb..beeb49e 100644
--- a/unix/zsyscall_linux_ppc64.go
+++ b/unix/zsyscall_linux_ppc64.go
@@ -731,17 +731,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
 	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
 	if e1 != 0 {
diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go
index dbc7621..53139b8 100644
--- a/unix/zsyscall_linux_ppc64le.go
+++ b/unix/zsyscall_linux_ppc64le.go
@@ -731,17 +731,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func syncFileRange2(fd int, flags int, off int64, n int64) (err error) {
 	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off), uintptr(n), 0, 0)
 	if e1 != 0 {
diff --git a/unix/zsyscall_linux_s390x.go b/unix/zsyscall_linux_s390x.go
index 8f65b2e..202add3 100644
--- a/unix/zsyscall_linux_s390x.go
+++ b/unix/zsyscall_linux_s390x.go
@@ -521,17 +521,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(cmdline)
diff --git a/unix/zsyscall_linux_sparc64.go b/unix/zsyscall_linux_sparc64.go
index 227f0f8..2ab268c 100644
--- a/unix/zsyscall_linux_sparc64.go
+++ b/unix/zsyscall_linux_sparc64.go
@@ -697,14 +697,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}