Pārlūkot izejas kodu

unix: add Ppoll support for linux

Use a shim for Poll on arm64.

Fixes golang/go#16052.

Change-Id: I929e7a2293561bddb9355bf65f98bc68b91905b2
Reviewed-on: https://go-review.googlesource.com/24062
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
kortschak 9 gadi atpakaļ
vecāks
revīzija
5a8c7f28c1

+ 4 - 5
unix/syscall_linux.go

@@ -60,13 +60,13 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 	return openat(dirfd, path, flags|O_LARGEFILE, mode)
 }
 
-//sys	poll(fds *PollFd, nfd int, timeout int) (n int, err error)
+//sys	ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
 
-func Poll(fds []PollFd, timeout int) (n int, err error) {
+func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
 	if len(fds) == 0 {
-		return poll(nil, 0, timeout)
+		return ppoll(nil, 0, timeout, sigmask)
 	}
-	return poll(&fds[0], len(fds), timeout)
+	return ppoll(&fds[0], len(fds), timeout, sigmask)
 }
 
 //sys	readlinkat(dirfd int, path string, buf []byte) (n int, err error)
@@ -1052,7 +1052,6 @@ func Munmap(b []byte) (err error) {
 // Newfstatat
 // Nfsservctl
 // Personality
-// Ppoll
 // Pselect6
 // Ptrace
 // Putpmsg

+ 9 - 0
unix/syscall_linux_386.go

@@ -388,3 +388,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.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)
+}

+ 9 - 0
unix/syscall_linux_amd64.go

@@ -146,3 +146,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.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)
+}

+ 9 - 0
unix/syscall_linux_arm.go

@@ -252,3 +252,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.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)
+}

+ 12 - 0
unix/syscall_linux_arm64.go

@@ -178,3 +178,15 @@ const (
 	SYS_EPOLL_CREATE = 1042
 	SYS_EPOLL_WAIT   = 1069
 )
+
+func Poll(fds []PollFd, timeout int) (n int, err error) {
+	var ts *Timespec
+	if timeout >= 0 {
+		ts = new(*Timespec)
+		*ts = NsecToTimespec(timeout * 1e6)
+	}
+	if len(fds) == 0 {
+		return ppoll(nil, 0, ts, nil)
+	}
+	return ppoll(&fds[0], len(fds), ts, nil)
+}

+ 9 - 0
unix/syscall_linux_mips64x.go

@@ -204,3 +204,12 @@ func (msghdr *Msghdr) SetControllen(length int) {
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.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)
+}

+ 9 - 0
unix/syscall_linux_ppc64x.go

@@ -124,3 +124,12 @@ func Pipe2(p []int, flags int) (err error) {
 	p[1] = int(pp[1])
 	return
 }
+
+//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)
+}

+ 9 - 0
unix/syscall_linux_s390x.go

@@ -318,3 +318,12 @@ func Shutdown(s, how int) error {
 	}
 	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)
+}

+ 50 - 13
unix/syscall_linux_test.go

@@ -16,19 +16,8 @@ import (
 )
 
 func TestPoll(t *testing.T) {
-	err := unix.Mkfifo("fifo", 0666)
-	if err != nil {
-		t.Errorf("Poll: failed to create FIFO: %v", err)
-		return
-	}
-	defer os.Remove("fifo")
-
-	f, err := os.OpenFile("fifo", os.O_RDWR, 0666)
-	if err != nil {
-		t.Errorf("Poll: failed to open FIFO: %v", err)
-		return
-	}
-	defer f.Close()
+	f, cleanup := mktmpfifo(t)
+	defer cleanup()
 
 	const timeout = 100
 
@@ -54,6 +43,54 @@ func TestPoll(t *testing.T) {
 	}
 }
 
+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
+	}
+}
+
+// mktmpfifo creates a temporary FIFO and provides a cleanup function.
+func mktmpfifo(t *testing.T) (*os.File, func()) {
+	err := unix.Mkfifo("fifo", 0666)
+	if err != nil {
+		t.Fatalf("mktmpfifo: failed to create FIFO: %v", err)
+	}
+
+	f, err := os.OpenFile("fifo", os.O_RDWR, 0666)
+	if err != nil {
+		os.Remove("fifo")
+		t.Fatalf("mktmpfifo: failed to open FIFO: %v", err)
+	}
+
+	return f, func() {
+		f.Close()
+		os.Remove("fifo")
+	}
+}
+
 func TestTime(t *testing.T) {
 	var ut unix.Time_t
 	ut2, err := unix.Time(&ut)

+ 2 - 0
unix/types_linux.go

@@ -443,6 +443,8 @@ const (
 	POLLNVAL  = C.POLLNVAL
 )
 
+type Sigset_t C.sigset_t
+
 // Terminal handling
 
 type Termios C.termios_t

+ 13 - 2
unix/zsyscall_linux_386.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1647,3 +1647,14 @@ func Utime(path string, buf *Utimbuf) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_amd64.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1841,3 +1841,14 @@ func pipe2(p *[2]_C_int, flags int) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_arm.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1748,3 +1748,14 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
 	}
 	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
+}

+ 2 - 2
unix/zsyscall_linux_arm64.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)

+ 13 - 2
unix/zsyscall_linux_mips64.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1790,3 +1790,14 @@ func stat(path string, st *stat_t) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_mips64le.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1790,3 +1790,14 @@ func stat(path string, st *stat_t) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_ppc64.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1852,3 +1852,14 @@ func pipe2(p *[2]_C_int, flags int) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_ppc64le.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1852,3 +1852,14 @@ func pipe2(p *[2]_C_int, flags int) (err error) {
 	}
 	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
+}

+ 13 - 2
unix/zsyscall_linux_s390x.go

@@ -53,8 +53,8 @@ func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func poll(fds *PollFd, nfd int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfd), uintptr(timeout))
+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)
@@ -1632,3 +1632,14 @@ func pipe2(p *[2]_C_int, flags int) (err error) {
 	}
 	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
+}

+ 4 - 0
unix/ztypes_linux_386.go

@@ -611,6 +611,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_amd64.go

@@ -629,6 +629,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_arm.go

@@ -591,6 +591,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_arm64.go

@@ -608,6 +608,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_mips64.go

@@ -612,6 +612,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag     uint32
 	Oflag     uint32

+ 4 - 0
unix/ztypes_linux_mips64le.go

@@ -612,6 +612,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag     uint32
 	Oflag     uint32

+ 4 - 0
unix/ztypes_linux_ppc64.go

@@ -618,6 +618,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_ppc64le.go

@@ -618,6 +618,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32

+ 4 - 0
unix/ztypes_linux_s390x.go

@@ -633,6 +633,10 @@ const (
 	POLLNVAL  = 0x20
 )
 
+type Sigset_t struct {
+	X__val [16]uint64
+}
+
 type Termios struct {
 	Iflag  uint32
 	Oflag  uint32