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 <mdlayher@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/linux/types.go b/unix/linux/types.go
index d9aae05..7236b72 100644
--- a/unix/linux/types.go
+++ b/unix/linux/types.go
@@ -59,6 +59,7 @@
#include <linux/if_alg.h>
#include <linux/fs.h>
#include <linux/vm_sockets.h>
+#include <linux/random.h>
// On mips64, the glibc stat and kernel stat do not agree
#if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)
@@ -530,6 +531,8 @@
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 4832bf5..c1abe45 100644
--- a/unix/syscall_linux.go
+++ b/unix/syscall_linux.go
@@ -36,6 +36,25 @@
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 @@
// IoGetevents
// IoSetup
// IoSubmit
-// Ioctl
// IoprioGet
// IoprioSet
// KexecLoad
diff --git a/unix/syscall_linux_test.go b/unix/syscall_linux_test.go
index 91184ca..e42b4ee 100644
--- a/unix/syscall_linux_test.go
+++ b/unix/syscall_linux_test.go
@@ -15,6 +15,21 @@
"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 cab9b4f..4b8ddab 100644
--- a/unix/syscall_solaris.go
+++ b/unix/syscall_solaris.go
@@ -519,43 +519,43 @@
* 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 d71acc1..e119de0 100644
--- a/unix/zsyscall_linux_386.go
+++ b/unix/zsyscall_linux_386.go
@@ -14,6 +14,16 @@
// 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 6282311..5a6b63e 100644
--- a/unix/zsyscall_linux_amd64.go
+++ b/unix/zsyscall_linux_amd64.go
@@ -14,6 +14,16 @@
// 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 d48e206..7de84dc 100644
--- a/unix/zsyscall_linux_arm.go
+++ b/unix/zsyscall_linux_arm.go
@@ -14,6 +14,16 @@
// 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 1ceabe5..4a6a122 100644
--- a/unix/zsyscall_linux_arm64.go
+++ b/unix/zsyscall_linux_arm64.go
@@ -14,6 +14,16 @@
// 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 fd3e972..3b4c934 100644
--- a/unix/zsyscall_linux_mips.go
+++ b/unix/zsyscall_linux_mips.go
@@ -14,6 +14,16 @@
// 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 dfa9d93..5a496a9 100644
--- a/unix/zsyscall_linux_mips64.go
+++ b/unix/zsyscall_linux_mips64.go
@@ -14,6 +14,16 @@
// 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 2c41e34..cfa7fe8 100644
--- a/unix/zsyscall_linux_mips64le.go
+++ b/unix/zsyscall_linux_mips64le.go
@@ -14,6 +14,16 @@
// 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 da9c71f..7f83efd 100644
--- a/unix/zsyscall_linux_mipsle.go
+++ b/unix/zsyscall_linux_mipsle.go
@@ -14,6 +14,16 @@
// 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 170560a..9a57e35 100644
--- a/unix/zsyscall_linux_ppc64.go
+++ b/unix/zsyscall_linux_ppc64.go
@@ -14,6 +14,16 @@
// 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 e03a81c..d12ce4d 100644
--- a/unix/zsyscall_linux_ppc64le.go
+++ b/unix/zsyscall_linux_ppc64le.go
@@ -14,6 +14,16 @@
// 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 e6c13aa..bd28929 100644
--- a/unix/zsyscall_linux_s390x.go
+++ b/unix/zsyscall_linux_s390x.go
@@ -14,6 +14,16 @@
// 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 cbc6f6e..d1ed021 100644
--- a/unix/zsyscall_solaris_amd64.go
+++ b/unix/zsyscall_solaris_amd64.go
@@ -519,7 +519,7 @@
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 20ae16b..7fc1eb2 100644
--- a/unix/ztypes_linux_386.go
+++ b/unix/ztypes_linux_386.go
@@ -660,6 +660,8 @@
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 1878142..60a26ee 100644
--- a/unix/ztypes_linux_amd64.go
+++ b/unix/ztypes_linux_amd64.go
@@ -678,6 +678,8 @@
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 b755668..b994baa 100644
--- a/unix/ztypes_linux_arm.go
+++ b/unix/ztypes_linux_arm.go
@@ -649,6 +649,8 @@
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 1e99b93..c19c478 100644
--- a/unix/ztypes_linux_arm64.go
+++ b/unix/ztypes_linux_arm64.go
@@ -657,6 +657,8 @@
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 9a7916c..c84e462 100644
--- a/unix/ztypes_linux_mips.go
+++ b/unix/ztypes_linux_mips.go
@@ -654,6 +654,8 @@
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 0b58c64..0c75cb9 100644
--- a/unix/ztypes_linux_mips64.go
+++ b/unix/ztypes_linux_mips64.go
@@ -659,6 +659,8 @@
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 aa6a663..c75f75a 100644
--- a/unix/ztypes_linux_mips64le.go
+++ b/unix/ztypes_linux_mips64le.go
@@ -659,6 +659,8 @@
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 b5ef69c..cfc219f 100644
--- a/unix/ztypes_linux_mipsle.go
+++ b/unix/ztypes_linux_mipsle.go
@@ -654,6 +654,8 @@
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 326b8e3..4c28522 100644
--- a/unix/ztypes_linux_ppc64.go
+++ b/unix/ztypes_linux_ppc64.go
@@ -667,6 +667,8 @@
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 1309399..1b511be 100644
--- a/unix/ztypes_linux_ppc64le.go
+++ b/unix/ztypes_linux_ppc64le.go
@@ -667,6 +667,8 @@
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 a5c40b8..b408752 100644
--- a/unix/ztypes_linux_s390x.go
+++ b/unix/ztypes_linux_s390x.go
@@ -684,6 +684,8 @@
_ [16]uint64
}
+const RNDGETENTCNT = 0x80045200
+
const _SC_PAGESIZE = 0x1e
type Termios struct {