From e2fefa8ec2a940fb6ef4eb6e2f06905b6d9d296b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 24 Sep 2019 09:34:00 +0000 Subject: [PATCH] unix: fix Select to return number of ready fds on Solaris Make Select's signature on Solaris match the one on Linux and return the number of ready file descriptors. Updates golang/go#34458 Change-Id: I118c4c35cbc83dba015ef357ce9bef44c9165ec1 Reviewed-on: https://go-review.googlesource.com/c/sys/+/196807 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- unix/mkerrors.sh | 1 + unix/syscall_solaris.go | 2 +- unix/syscall_solaris_test.go | 35 ++++++++++++++++++++++++++++++++-- unix/zerrors_solaris_amd64.go | 3 ++- unix/zsyscall_solaris_amd64.go | 5 +++-- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh index 3f256236..02e5cca0 100755 --- a/unix/mkerrors.sh +++ b/unix/mkerrors.sh @@ -348,6 +348,7 @@ includes_OpenBSD=' includes_SunOS=' #include #include +#include #include #include #include diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go index 1610f551..62f968c7 100644 --- a/unix/syscall_solaris.go +++ b/unix/syscall_solaris.go @@ -649,7 +649,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) //sys Rmdir(path string) (err error) //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek -//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) +//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) //sysnb Setegid(egid int) (err error) //sysnb Seteuid(euid int) (err error) //sysnb Setgid(gid int) (err error) diff --git a/unix/syscall_solaris_test.go b/unix/syscall_solaris_test.go index 57dba882..21a57133 100644 --- a/unix/syscall_solaris_test.go +++ b/unix/syscall_solaris_test.go @@ -7,6 +7,7 @@ package unix_test import ( + "os" "os/exec" "testing" "time" @@ -15,23 +16,53 @@ import ( ) func TestSelect(t *testing.T) { - err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0}) + n, err := unix.Select(0, nil, nil, nil, &unix.Timeval{Sec: 0, Usec: 0}) if err != nil { t.Fatalf("Select: %v", err) } + if n != 0 { + t.Fatalf("Select: expected 0 ready file descriptors, got %v", n) + } dur := 150 * time.Millisecond tv := unix.NsecToTimeval(int64(dur)) start := time.Now() - err = unix.Select(0, nil, nil, nil, &tv) + n, err = unix.Select(0, nil, nil, nil, &tv) took := time.Since(start) if err != nil { t.Fatalf("Select: %v", err) } + if n != 0 { + t.Fatalf("Select: expected 0 ready file descriptors, got %v", n) + } if took < dur { t.Errorf("Select: timeout should have been at least %v, got %v", dur, took) } + + rr, ww, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + defer rr.Close() + defer ww.Close() + + if _, err := ww.Write([]byte("HELLO GOPHER")); err != nil { + t.Fatal(err) + } + + rFdSet := &unix.FdSet{} + fd := rr.Fd() + // FD_SET(fd, rFdSet) + rFdSet.Bits[fd/unix.NFDBITS] |= (1 << (fd % unix.NFDBITS)) + + n, err = unix.Select(int(fd+1), rFdSet, nil, nil, nil) + if err != nil { + t.Fatalf("Select: %v", err) + } + if n != 1 { + t.Fatalf("Select: expected 1 ready file descriptors, got %v", n) + } } func TestStatvfs(t *testing.T) { diff --git a/unix/zerrors_solaris_amd64.go b/unix/zerrors_solaris_amd64.go index 22569db3..46e054cc 100644 --- a/unix/zerrors_solaris_amd64.go +++ b/unix/zerrors_solaris_amd64.go @@ -3,7 +3,7 @@ // +build amd64,solaris -// Created by cgo -godefs - DO NOT EDIT +// Code generated by cmd/cgo -godefs; DO NOT EDIT. // cgo -godefs -- -m64 _const.go package unix @@ -666,6 +666,7 @@ const ( M_FLUSH = 0x86 NAME_MAX = 0xff NEWDEV = 0x1 + NFDBITS = 0x40 NL0 = 0x0 NL1 = 0x100 NLDLY = 0x100 diff --git a/unix/zsyscall_solaris_amd64.go b/unix/zsyscall_solaris_amd64.go index 5f614760..a96165d4 100644 --- a/unix/zsyscall_solaris_amd64.go +++ b/unix/zsyscall_solaris_amd64.go @@ -1478,8 +1478,9 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSelect)), 5, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) +func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSelect)), 5, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) + n = int(r0) if e1 != 0 { err = e1 }