blob: fe1f50aecd4476f24825122a7334f48c2fe59f06 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE
package input
import (
"syscall"
)
// iocDir describes the direction data will be transferred during an ioctl.
type iocDir uint
const (
iocNone iocDir = 0
iocWrite = 1
iocRead = 2
)
// ioctl-related constants and functions taken from Linux kernel:
// include/asm-generic/ioctl.h
const (
iocNrBits = 8
iocTypeBits = 8
// TODO: On PowerPC, SPARC, MIPS and Alpha it is defined as a 13-bit constant.
// In the rest, including Intel and ARM it is defined as a 14-bit constant.
// See https://elixir.bootlin.com/linux/latest/ident/_IOC_SIZEBITS
iocSizeBits = 14
iocDirBits = 2
iocNrMask = (1 << iocNrBits) - 1
iocTypeMask = (1 << iocTypeBits) - 1
iocSizeMask = (1 << iocSizeBits) - 1
iocDirMask = (1 << iocDirBits) - 1
iocNrShift = 0
iocTypeShift = iocNrShift + iocNrBits
iocSizeShift = iocTypeShift + iocTypeBits
iocDirShift = iocSizeShift + iocSizeBits
)
// ioc returns an encoded ioctl request in the given direction for the supplied type
// (e.g. UINPUT_IOCTL_BASE), number (e.g. UI_DEV_CREATE), and data size.
// This is analogous to the _IOC C macro.
func ioc(dir iocDir, typ, nr uint, size uintptr) uint {
return (uint(dir) << iocDirShift) | (typ << iocTypeShift) | (nr << iocNrShift) |
(uint(size) << iocSizeShift)
}
// ior returns an encoded read ioctl request. See ioc for arguments.
// This is analogous to the _IOR C macro.
func ior(typ, nr uint, size uintptr) uint {
return ioc(iocRead, typ, nr, size)
}
// iow returns an encoded write ioctl request. See ioc for arguments.
// This is analogous to the _IOW C macro.
func iow(typ, nr uint, size uintptr) uint {
return ioc(iocWrite, typ, nr, size)
}
// ioctl makes an ioctl system call against fd using the supplied encoded request and data.
func ioctl(fd int, req uint, data uintptr) error {
if _, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(req), data); errno != 0 {
return errno
}
return nil
}