github.com/aamcrae/webcam@v0.0.0-20210915060337-934acc13bdc3/ioctl/ioctl.go (about)

     1  package ioctl
     2  
     3  import "golang.org/x/sys/unix"
     4  
     5  const (
     6  	typeBits      = 8
     7  	numberBits    = 8
     8  	sizeBits      = 14
     9  	directionBits = 2
    10  
    11  	typeMask      = (1 << typeBits) - 1
    12  	numberMask    = (1 << numberBits) - 1
    13  	sizeMask      = (1 << sizeBits) - 1
    14  	directionMask = (1 << directionBits) - 1
    15  
    16  	directionNone  = 0
    17  	directionWrite = 1
    18  	directionRead  = 2
    19  
    20  	numberShift    = 0
    21  	typeShift      = numberShift + numberBits
    22  	sizeShift      = typeShift + typeBits
    23  	directionShift = sizeShift + sizeBits
    24  
    25  	ErrEINVAL = unix.EINVAL
    26  )
    27  
    28  func ioc(dir, t, nr, size uintptr) uintptr {
    29  	return (dir << directionShift) | (t << typeShift) | (nr << numberShift) | (size << sizeShift)
    30  }
    31  
    32  // Io used for a simple ioctl that sends nothing but the type and number, and receives back nothing but an (integer) retval.
    33  func Io(t, nr uintptr) uintptr {
    34  	return ioc(directionNone, t, nr, 0)
    35  }
    36  
    37  // IoR used for an ioctl that reads data from the device driver. The driver will be allowed to return sizeof(data_type) bytes to the user.
    38  func IoR(t, nr, size uintptr) uintptr {
    39  	return ioc(directionRead, t, nr, size)
    40  }
    41  
    42  // IoW used for an ioctl that writes data to the device driver.
    43  func IoW(t, nr, size uintptr) uintptr {
    44  	return ioc(directionWrite, t, nr, size)
    45  }
    46  
    47  // IoRW  a combination of IoR and IoW. That is, data is both written to the driver and then read back from the driver by the client.
    48  func IoRW(t, nr, size uintptr) uintptr {
    49  	return ioc(directionRead|directionWrite, t, nr, size)
    50  }
    51  
    52  // Ioctl simplified ioct call
    53  func Ioctl(fd, op, arg uintptr) error {
    54  	_, _, ep := unix.Syscall(unix.SYS_IOCTL, fd, op, arg)
    55  	if ep != 0 {
    56  		return ep
    57  	}
    58  	return nil
    59  }