unix: add Ppoll on openbsd

Change-Id: I3a13730e219e6f6df28829cf0d1e193c62073ac8
Reviewed-on: https://go-review.googlesource.com/c/144057
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/unix/syscall_openbsd.go b/unix/syscall_openbsd.go
index 2c674a5..38ea2ec 100644
--- a/unix/syscall_openbsd.go
+++ b/unix/syscall_openbsd.go
@@ -158,6 +158,15 @@
 	return &value, err
 }
 
+//sys	ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
+
+func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	if len(fds) == 0 {
+		return ppoll(nil, 0, timeout, sigmask)
+	}
+	return ppoll(&fds[0], len(fds), timeout, sigmask)
+}
+
 func Uname(uname *Utsname) error {
 	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
 	n := unsafe.Sizeof(uname.Sysname)
diff --git a/unix/syscall_openbsd_test.go b/unix/syscall_openbsd_test.go
index 65ad1d1..b95f334 100644
--- a/unix/syscall_openbsd_test.go
+++ b/unix/syscall_openbsd_test.go
@@ -6,10 +6,40 @@
 
 import (
 	"testing"
+	"time"
 
 	"golang.org/x/sys/unix"
 )
 
+func TestPpoll(t *testing.T) {
+	f, cleanup := mktmpfifo(t)
+	defer cleanup()
+
+	const timeout = 100 * time.Millisecond
+
+	ok := make(chan bool, 1)
+	go func() {
+		select {
+		case <-time.After(10 * timeout):
+			t.Errorf("Ppoll: failed to timeout after %d", 10*timeout)
+		case <-ok:
+		}
+	}()
+
+	fds := []unix.PollFd{{Fd: int32(f.Fd()), Events: unix.POLLIN}}
+	timeoutTs := unix.NsecToTimespec(int64(timeout))
+	n, err := unix.Ppoll(fds, &timeoutTs, nil)
+	ok <- true
+	if err != nil {
+		t.Errorf("Ppoll: unexpected error: %v", err)
+		return
+	}
+	if n != 0 {
+		t.Errorf("Ppoll: wrong number of events: got %v, expected %v", n, 0)
+		return
+	}
+}
+
 func TestSysctlUvmexp(t *testing.T) {
 	uvm, err := unix.SysctlUvmexp("vm.uvmexp")
 	if err != nil {
diff --git a/unix/types_openbsd.go b/unix/types_openbsd.go
index 297e40d..4e5e57f 100644
--- a/unix/types_openbsd.go
+++ b/unix/types_openbsd.go
@@ -261,6 +261,10 @@
 	POLLWRNORM = C.POLLWRNORM
 )
 
+// Signal Sets
+
+type Sigset_t C.sigset_t
+
 // Uname
 
 type Utsname C.struct_utsname
diff --git a/unix/zsyscall_openbsd_386.go b/unix/zsyscall_openbsd_386.go
index 1942049..7e6f4e1 100644
--- a/unix/zsyscall_openbsd_386.go
+++ b/unix/zsyscall_openbsd_386.go
@@ -431,6 +431,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/zsyscall_openbsd_amd64.go b/unix/zsyscall_openbsd_amd64.go
index d351c72..1132b89 100644
--- a/unix/zsyscall_openbsd_amd64.go
+++ b/unix/zsyscall_openbsd_amd64.go
@@ -431,6 +431,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/zsyscall_openbsd_arm.go b/unix/zsyscall_openbsd_arm.go
index 617d47f..0f7b4af 100644
--- a/unix/zsyscall_openbsd_arm.go
+++ b/unix/zsyscall_openbsd_arm.go
@@ -431,6 +431,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Access(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/unix/ztypes_openbsd_386.go b/unix/ztypes_openbsd_386.go
index c8509bf..8b37d83 100644
--- a/unix/ztypes_openbsd_386.go
+++ b/unix/ztypes_openbsd_386.go
@@ -458,6 +458,8 @@
 	POLLWRNORM = 0x4
 )
 
+type Sigset_t uint32
+
 type Utsname struct {
 	Sysname  [256]byte
 	Nodename [256]byte
diff --git a/unix/ztypes_openbsd_amd64.go b/unix/ztypes_openbsd_amd64.go
index 200575d..6efea46 100644
--- a/unix/ztypes_openbsd_amd64.go
+++ b/unix/ztypes_openbsd_amd64.go
@@ -458,6 +458,8 @@
 	POLLWRNORM = 0x4
 )
 
+type Sigset_t uint32
+
 type Utsname struct {
 	Sysname  [256]byte
 	Nodename [256]byte
diff --git a/unix/ztypes_openbsd_arm.go b/unix/ztypes_openbsd_arm.go
index 3e20cdf..87a637e 100644
--- a/unix/ztypes_openbsd_arm.go
+++ b/unix/ztypes_openbsd_arm.go
@@ -451,6 +451,8 @@
 	POLLWRNORM = 0x4
 )
 
+type Sigset_t uint32
+
 type Utsname struct {
 	Sysname  [256]byte
 	Nodename [256]byte