Commit a55a7608 authored by Matt Layher's avatar Matt Layher

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: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent dbc2be91
...@@ -59,6 +59,7 @@ package unix ...@@ -59,6 +59,7 @@ package unix
#include <linux/if_alg.h> #include <linux/if_alg.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/vm_sockets.h> #include <linux/vm_sockets.h>
#include <linux/random.h>
// On mips64, the glibc stat and kernel stat do not agree // On mips64, the glibc stat and kernel stat do not agree
#if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64) #if (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64)
...@@ -530,6 +531,8 @@ const ( ...@@ -530,6 +531,8 @@ const (
type Sigset_t C.sigset_t type Sigset_t C.sigset_t
const RNDGETENTCNT = C.RNDGETENTCNT
// sysconf information // sysconf information
const _SC_PAGESIZE = C._SC_PAGESIZE const _SC_PAGESIZE = C._SC_PAGESIZE
......
...@@ -36,6 +36,25 @@ func Creat(path string, mode uint32) (fd int, err error) { ...@@ -36,6 +36,25 @@ func Creat(path string, mode uint32) (fd int, err error) {
return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) 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) //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
func Link(oldpath string, newpath string) (err error) { func Link(oldpath string, newpath string) (err error) {
...@@ -1312,7 +1331,6 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { ...@@ -1312,7 +1331,6 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
// IoGetevents // IoGetevents
// IoSetup // IoSetup
// IoSubmit // IoSubmit
// Ioctl
// IoprioGet // IoprioGet
// IoprioSet // IoprioSet
// KexecLoad // KexecLoad
......
...@@ -15,6 +15,21 @@ import ( ...@@ -15,6 +15,21 @@ import (
"golang.org/x/sys/unix" "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) { func TestPoll(t *testing.T) {
f, cleanup := mktmpfifo(t) f, cleanup := mktmpfifo(t)
defer cleanup() defer cleanup()
......
...@@ -519,43 +519,43 @@ func Acct(path string) (err error) { ...@@ -519,43 +519,43 @@ func Acct(path string) (err error) {
* Expose the ioctl function * 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)) 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))) 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))) 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))) 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 var value int
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return value, err return value, err
} }
func IoctlGetWinsize(fd int, req int) (*Winsize, error) { func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
var value Winsize var value Winsize
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err return &value, err
} }
func IoctlGetTermios(fd int, req int) (*Termios, error) { func IoctlGetTermios(fd int, req uint) (*Termios, error) {
var value Termios var value Termios
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err return &value, err
} }
func IoctlGetTermio(fd int, req int) (*Termio, error) { func IoctlGetTermio(fd int, req uint) (*Termio, error) {
var value Termio var value Termio
err := ioctl(fd, req, uintptr(unsafe.Pointer(&value))) err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
return &value, err return &value, err
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -14,6 +14,16 @@ var _ syscall.Errno ...@@ -14,6 +14,16 @@ var _ syscall.Errno
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // 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) { func Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
var _p0 *byte var _p0 *byte
_p0, err = BytePtrFromString(oldpath) _p0, err = BytePtrFromString(oldpath)
......
...@@ -519,7 +519,7 @@ func acct(path *byte) (err error) { ...@@ -519,7 +519,7 @@ func acct(path *byte) (err error) {
return 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) _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0)
if e1 != 0 { if e1 != 0 {
err = e1 err = e1
......
...@@ -660,6 +660,8 @@ type Sigset_t struct { ...@@ -660,6 +660,8 @@ type Sigset_t struct {
X__val [32]uint32 X__val [32]uint32
} }
const RNDGETENTCNT = 0x80045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -678,6 +678,8 @@ type Sigset_t struct { ...@@ -678,6 +678,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x80045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -649,6 +649,8 @@ type Sigset_t struct { ...@@ -649,6 +649,8 @@ type Sigset_t struct {
X__val [32]uint32 X__val [32]uint32
} }
const RNDGETENTCNT = 0x80045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -657,6 +657,8 @@ type Sigset_t struct { ...@@ -657,6 +657,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x80045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -654,6 +654,8 @@ type Sigset_t struct { ...@@ -654,6 +654,8 @@ type Sigset_t struct {
X__val [32]uint32 X__val [32]uint32
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -659,6 +659,8 @@ type Sigset_t struct { ...@@ -659,6 +659,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -659,6 +659,8 @@ type Sigset_t struct { ...@@ -659,6 +659,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -654,6 +654,8 @@ type Sigset_t struct { ...@@ -654,6 +654,8 @@ type Sigset_t struct {
X__val [32]uint32 X__val [32]uint32
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -667,6 +667,8 @@ type Sigset_t struct { ...@@ -667,6 +667,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -667,6 +667,8 @@ type Sigset_t struct { ...@@ -667,6 +667,8 @@ type Sigset_t struct {
X__val [16]uint64 X__val [16]uint64
} }
const RNDGETENTCNT = 0x40045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
...@@ -684,6 +684,8 @@ type Sigset_t struct { ...@@ -684,6 +684,8 @@ type Sigset_t struct {
_ [16]uint64 _ [16]uint64
} }
const RNDGETENTCNT = 0x80045200
const _SC_PAGESIZE = 0x1e const _SC_PAGESIZE = 0x1e
type Termios struct { type Termios struct {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment