From a55a76086885b80f79961eacb876ebd8caf3868d Mon Sep 17 00:00:00 2001 From: Matt Layher Date: Tue, 23 May 2017 22:50:34 -0400 Subject: [PATCH] unix: add IoctlGetInt and IoctlSetInt on Linux This CL adds basic integer get/set functions which wrap a generic ioctl call. The API is similar the one introduced for solaris/amd64 in CL 14587, but the request parameter has been changed to a uint instead of an int. This makes requests with a number larger than the maximum signed 32-bit integer work on linux/386. For consistency, the solaris/amd64 API has also been updated to make use of a uint instead of an int for the request number. Fixes golang/go#20474 Change-Id: Iaae1ee2e4bb4bfcc420dcec252fe53c8d90ce81d Reviewed-on: https://go-review.googlesource.com/44009 Run-TryBot: Matt Layher TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- unix/linux/types.go | 3 +++ unix/syscall_linux.go | 20 +++++++++++++++++++- unix/syscall_linux_test.go | 15 +++++++++++++++ unix/syscall_solaris.go | 18 +++++++++--------- unix/zsyscall_linux_386.go | 10 ++++++++++ unix/zsyscall_linux_amd64.go | 10 ++++++++++ unix/zsyscall_linux_arm.go | 10 ++++++++++ unix/zsyscall_linux_arm64.go | 10 ++++++++++ unix/zsyscall_linux_mips.go | 10 ++++++++++ unix/zsyscall_linux_mips64.go | 10 ++++++++++ unix/zsyscall_linux_mips64le.go | 10 ++++++++++ unix/zsyscall_linux_mipsle.go | 10 ++++++++++ unix/zsyscall_linux_ppc64.go | 10 ++++++++++ unix/zsyscall_linux_ppc64le.go | 10 ++++++++++ unix/zsyscall_linux_s390x.go | 10 ++++++++++ unix/zsyscall_solaris_amd64.go | 2 +- unix/ztypes_linux_386.go | 2 ++ unix/ztypes_linux_amd64.go | 2 ++ unix/ztypes_linux_arm.go | 2 ++ unix/ztypes_linux_arm64.go | 2 ++ unix/ztypes_linux_mips.go | 2 ++ unix/ztypes_linux_mips64.go | 2 ++ unix/ztypes_linux_mips64le.go | 2 ++ unix/ztypes_linux_mipsle.go | 2 ++ unix/ztypes_linux_ppc64.go | 2 ++ unix/ztypes_linux_ppc64le.go | 2 ++ unix/ztypes_linux_s390x.go | 2 ++ 27 files changed, 179 insertions(+), 11 deletions(-) diff --git a/unix/linux/types.go b/unix/linux/types.go index d9aae059..7236b729 100644 --- a/unix/linux/types.go +++ b/unix/linux/types.go @@ -59,6 +59,7 @@ package unix #include #include #include +#include // On mips64, the glibc stat and kernel stat do not agree #if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) @@ -530,6 +531,8 @@ const ( type Sigset_t C.sigset_t +const RNDGETENTCNT = C.RNDGETENTCNT + // sysconf information const _SC_PAGESIZE = C._SC_PAGESIZE diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 4832bf57..c1abe454 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -36,6 +36,25 @@ func Creat(path string, mode uint32) (fd int, err error) { return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) } +//sys ioctl(fd int, req uint, arg uintptr) (err error) + +// ioctl itself should not be exposed directly, but additional get/set +// functions for specific types are permissible. + +// IoctlSetInt performs an ioctl operation which sets an integer value +// on fd, using the specified request number. +func IoctlSetInt(fd int, req uint, value int) (err error) { + return ioctl(fd, req, uintptr(value)) +} + +// IoctlGetInt performs an ioctl operation which gets an integer value +// from fd, using the specified request number. +func IoctlGetInt(fd int, req uint) (int, error) { + var value int + err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) + return value, err +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { @@ -1312,7 +1331,6 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { // IoGetevents // IoSetup // IoSubmit -// Ioctl // IoprioGet // IoprioSet // KexecLoad diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go index 91184cae..e42b4ee6 100644 --- a/unix/syscall_linux_test.go +++ b/unix/syscall_linux_test.go @@ -15,6 +15,21 @@ import ( "golang.org/x/sys/unix" ) +func TestIoctlGetInt(t *testing.T) { + f, err := os.Open("/dev/random") + if err != nil { + t.Fatalf("failed to open device: %v", err) + } + defer f.Close() + + v, err := unix.IoctlGetInt(int(f.Fd()), unix.RNDGETENTCNT) + if err != nil { + t.Fatalf("failed to perform ioctl: %v", err) + } + + t.Logf("%d bits of entropy available", v) +} + func TestPoll(t *testing.T) { f, cleanup := mktmpfifo(t) defer cleanup() diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go index cab9b4fb..4b8ddabd 100644 --- a/unix/syscall_solaris.go +++ b/unix/syscall_solaris.go @@ -519,43 +519,43 @@ func Acct(path string) (err error) { * Expose the ioctl function */ -//sys ioctl(fd int, req int, arg uintptr) (err error) +//sys ioctl(fd int, req uint, arg uintptr) (err error) -func IoctlSetInt(fd int, req int, value int) (err error) { +func IoctlSetInt(fd int, req uint, value int) (err error) { return ioctl(fd, req, uintptr(value)) } -func IoctlSetWinsize(fd int, req int, value *Winsize) (err error) { +func IoctlSetWinsize(fd int, req uint, value *Winsize) (err error) { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermios(fd int, req int, value *Termios) (err error) { +func IoctlSetTermios(fd int, req uint, value *Termios) (err error) { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlSetTermio(fd int, req int, value *Termio) (err error) { +func IoctlSetTermio(fd int, req uint, value *Termio) (err error) { return ioctl(fd, req, uintptr(unsafe.Pointer(value))) } -func IoctlGetInt(fd int, req int) (int, error) { +func IoctlGetInt(fd int, req uint) (int, error) { var value int err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) return value, err } -func IoctlGetWinsize(fd int, req int) (*Winsize, error) { +func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { var value Winsize err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) return &value, err } -func IoctlGetTermios(fd int, req int) (*Termios, error) { +func IoctlGetTermios(fd int, req uint) (*Termios, error) { var value Termios err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) return &value, err } -func IoctlGetTermio(fd int, req int) (*Termio, error) { +func IoctlGetTermio(fd int, req uint) (*Termio, error) { var value Termio err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) return &value, err diff --git a/unix/zsyscall_linux_386.go b/unix/zsyscall_linux_386.go index d71acc17..e119de0e 100644 --- a/unix/zsyscall_linux_386.go +++ b/unix/zsyscall_linux_386.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_amd64.go b/unix/zsyscall_linux_amd64.go index 62823119..5a6b63ef 100644 --- a/unix/zsyscall_linux_amd64.go +++ b/unix/zsyscall_linux_amd64.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_arm.go b/unix/zsyscall_linux_arm.go index d48e2067..7de84dcf 100644 --- a/unix/zsyscall_linux_arm.go +++ b/unix/zsyscall_linux_arm.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_arm64.go b/unix/zsyscall_linux_arm64.go index 1ceabe5f..4a6a1229 100644 --- a/unix/zsyscall_linux_arm64.go +++ b/unix/zsyscall_linux_arm64.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_mips.go b/unix/zsyscall_linux_mips.go index fd3e9721..3b4c9346 100644 --- a/unix/zsyscall_linux_mips.go +++ b/unix/zsyscall_linux_mips.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_mips64.go b/unix/zsyscall_linux_mips64.go index dfa9d930..5a496a9e 100644 --- a/unix/zsyscall_linux_mips64.go +++ b/unix/zsyscall_linux_mips64.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_mips64le.go b/unix/zsyscall_linux_mips64le.go index 2c41e34e..cfa7fe8a 100644 --- a/unix/zsyscall_linux_mips64le.go +++ b/unix/zsyscall_linux_mips64le.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_mipsle.go b/unix/zsyscall_linux_mipsle.go index da9c71f4..7f83efdb 100644 --- a/unix/zsyscall_linux_mipsle.go +++ b/unix/zsyscall_linux_mipsle.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_ppc64.go b/unix/zsyscall_linux_ppc64.go index 170560a3..9a57e352 100644 --- a/unix/zsyscall_linux_ppc64.go +++ b/unix/zsyscall_linux_ppc64.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_ppc64le.go b/unix/zsyscall_linux_ppc64le.go index e03a81c5..d12ce4da 100644 --- a/unix/zsyscall_linux_ppc64le.go +++ b/unix/zsyscall_linux_ppc64le.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_linux_s390x.go b/unix/zsyscall_linux_s390x.go index e6c13aa7..bd289296 100644 --- a/unix/zsyscall_linux_s390x.go +++ b/unix/zsyscall_linux_s390x.go @@ -14,6 +14,16 @@ var _ syscall.Errno // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(oldpath) diff --git a/unix/zsyscall_solaris_amd64.go b/unix/zsyscall_solaris_amd64.go index cbc6f6e3..d1ed0210 100644 --- a/unix/zsyscall_solaris_amd64.go +++ b/unix/zsyscall_solaris_amd64.go @@ -519,7 +519,7 @@ func acct(path *byte) (err error) { return } -func ioctl(fd int, req int, arg uintptr) (err error) { +func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) if e1 != 0 { err = e1 diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go index 20ae16bc..7fc1eb2d 100644 --- a/unix/ztypes_linux_386.go +++ b/unix/ztypes_linux_386.go @@ -660,6 +660,8 @@ type Sigset_t struct { X__val [32]uint32 } +const RNDGETENTCNT = 0x80045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go index 18781420..60a26eee 100644 --- a/unix/ztypes_linux_amd64.go +++ b/unix/ztypes_linux_amd64.go @@ -678,6 +678,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x80045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go index b7556684..b994baa3 100644 --- a/unix/ztypes_linux_arm.go +++ b/unix/ztypes_linux_arm.go @@ -649,6 +649,8 @@ type Sigset_t struct { X__val [32]uint32 } +const RNDGETENTCNT = 0x80045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_arm64.go b/unix/ztypes_linux_arm64.go index 1e99b936..c19c4788 100644 --- a/unix/ztypes_linux_arm64.go +++ b/unix/ztypes_linux_arm64.go @@ -657,6 +657,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x80045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_mips.go b/unix/ztypes_linux_mips.go index 9a7916cb..c84e4620 100644 --- a/unix/ztypes_linux_mips.go +++ b/unix/ztypes_linux_mips.go @@ -654,6 +654,8 @@ type Sigset_t struct { X__val [32]uint32 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_mips64.go b/unix/ztypes_linux_mips64.go index 0b58c64d..0c75cb93 100644 --- a/unix/ztypes_linux_mips64.go +++ b/unix/ztypes_linux_mips64.go @@ -659,6 +659,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_mips64le.go b/unix/ztypes_linux_mips64le.go index aa6a6637..c75f75a2 100644 --- a/unix/ztypes_linux_mips64le.go +++ b/unix/ztypes_linux_mips64le.go @@ -659,6 +659,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_mipsle.go b/unix/ztypes_linux_mipsle.go index b5ef69cf..cfc219f1 100644 --- a/unix/ztypes_linux_mipsle.go +++ b/unix/ztypes_linux_mipsle.go @@ -654,6 +654,8 @@ type Sigset_t struct { X__val [32]uint32 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_ppc64.go b/unix/ztypes_linux_ppc64.go index 326b8e30..4c285227 100644 --- a/unix/ztypes_linux_ppc64.go +++ b/unix/ztypes_linux_ppc64.go @@ -667,6 +667,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_ppc64le.go b/unix/ztypes_linux_ppc64le.go index 1309399b..1b511be2 100644 --- a/unix/ztypes_linux_ppc64le.go +++ b/unix/ztypes_linux_ppc64le.go @@ -667,6 +667,8 @@ type Sigset_t struct { X__val [16]uint64 } +const RNDGETENTCNT = 0x40045200 + const _SC_PAGESIZE = 0x1e type Termios struct { diff --git a/unix/ztypes_linux_s390x.go b/unix/ztypes_linux_s390x.go index a5c40b8c..b408752d 100644 --- a/unix/ztypes_linux_s390x.go +++ b/unix/ztypes_linux_s390x.go @@ -684,6 +684,8 @@ type Sigset_t struct { _ [16]uint64 } +const RNDGETENTCNT = 0x80045200 + const _SC_PAGESIZE = 0x1e type Termios struct {