vendor/golang.org/x/sys/unix/ioctl_linux.go
changeset 256 6d9efbef00a9
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
       
     1 // Copyright 2021 The Go Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style
       
     3 // license that can be found in the LICENSE file.
       
     4 
       
     5 package unix
       
     6 
       
     7 import (
       
     8 	"runtime"
       
     9 	"unsafe"
       
    10 )
       
    11 
       
    12 // IoctlRetInt performs an ioctl operation specified by req on a device
       
    13 // associated with opened file descriptor fd, and returns a non-negative
       
    14 // integer that is returned by the ioctl syscall.
       
    15 func IoctlRetInt(fd int, req uint) (int, error) {
       
    16 	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
       
    17 	if err != 0 {
       
    18 		return 0, err
       
    19 	}
       
    20 	return int(ret), nil
       
    21 }
       
    22 
       
    23 func IoctlGetUint32(fd int, req uint) (uint32, error) {
       
    24 	var value uint32
       
    25 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
       
    26 	return value, err
       
    27 }
       
    28 
       
    29 func IoctlGetRTCTime(fd int) (*RTCTime, error) {
       
    30 	var value RTCTime
       
    31 	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
       
    32 	return &value, err
       
    33 }
       
    34 
       
    35 func IoctlSetRTCTime(fd int, value *RTCTime) error {
       
    36 	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
       
    37 	runtime.KeepAlive(value)
       
    38 	return err
       
    39 }
       
    40 
       
    41 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
       
    42 	var value RTCWkAlrm
       
    43 	err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
       
    44 	return &value, err
       
    45 }
       
    46 
       
    47 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
       
    48 	err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
       
    49 	runtime.KeepAlive(value)
       
    50 	return err
       
    51 }
       
    52 
       
    53 type ifreqEthtool struct {
       
    54 	name [IFNAMSIZ]byte
       
    55 	data unsafe.Pointer
       
    56 }
       
    57 
       
    58 // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
       
    59 // device specified by ifname.
       
    60 func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
       
    61 	// Leave room for terminating NULL byte.
       
    62 	if len(ifname) >= IFNAMSIZ {
       
    63 		return nil, EINVAL
       
    64 	}
       
    65 
       
    66 	value := EthtoolDrvinfo{
       
    67 		Cmd: ETHTOOL_GDRVINFO,
       
    68 	}
       
    69 	ifreq := ifreqEthtool{
       
    70 		data: unsafe.Pointer(&value),
       
    71 	}
       
    72 	copy(ifreq.name[:], ifname)
       
    73 	err := ioctl(fd, SIOCETHTOOL, uintptr(unsafe.Pointer(&ifreq)))
       
    74 	runtime.KeepAlive(ifreq)
       
    75 	return &value, err
       
    76 }
       
    77 
       
    78 // IoctlGetWatchdogInfo fetches information about a watchdog device from the
       
    79 // Linux watchdog API. For more information, see:
       
    80 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
       
    81 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
       
    82 	var value WatchdogInfo
       
    83 	err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value)))
       
    84 	return &value, err
       
    85 }
       
    86 
       
    87 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
       
    88 // more information, see:
       
    89 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
       
    90 func IoctlWatchdogKeepalive(fd int) error {
       
    91 	return ioctl(fd, WDIOC_KEEPALIVE, 0)
       
    92 }
       
    93 
       
    94 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
       
    95 // range of data conveyed in value to the file associated with the file
       
    96 // descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
       
    97 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
       
    98 	err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value)))
       
    99 	runtime.KeepAlive(value)
       
   100 	return err
       
   101 }
       
   102 
       
   103 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
       
   104 // associated with the file description srcFd to the file associated with the
       
   105 // file descriptor destFd. See the ioctl_ficlone(2) man page for details.
       
   106 func IoctlFileClone(destFd, srcFd int) error {
       
   107 	return ioctl(destFd, FICLONE, uintptr(srcFd))
       
   108 }
       
   109 
       
   110 type FileDedupeRange struct {
       
   111 	Src_offset uint64
       
   112 	Src_length uint64
       
   113 	Reserved1  uint16
       
   114 	Reserved2  uint32
       
   115 	Info       []FileDedupeRangeInfo
       
   116 }
       
   117 
       
   118 type FileDedupeRangeInfo struct {
       
   119 	Dest_fd       int64
       
   120 	Dest_offset   uint64
       
   121 	Bytes_deduped uint64
       
   122 	Status        int32
       
   123 	Reserved      uint32
       
   124 }
       
   125 
       
   126 // IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
       
   127 // range of data conveyed in value from the file associated with the file
       
   128 // descriptor srcFd to the value.Info destinations. See the
       
   129 // ioctl_fideduperange(2) man page for details.
       
   130 func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
       
   131 	buf := make([]byte, SizeofRawFileDedupeRange+
       
   132 		len(value.Info)*SizeofRawFileDedupeRangeInfo)
       
   133 	rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0]))
       
   134 	rawrange.Src_offset = value.Src_offset
       
   135 	rawrange.Src_length = value.Src_length
       
   136 	rawrange.Dest_count = uint16(len(value.Info))
       
   137 	rawrange.Reserved1 = value.Reserved1
       
   138 	rawrange.Reserved2 = value.Reserved2
       
   139 
       
   140 	for i := range value.Info {
       
   141 		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
       
   142 			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
       
   143 				uintptr(i*SizeofRawFileDedupeRangeInfo)))
       
   144 		rawinfo.Dest_fd = value.Info[i].Dest_fd
       
   145 		rawinfo.Dest_offset = value.Info[i].Dest_offset
       
   146 		rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
       
   147 		rawinfo.Status = value.Info[i].Status
       
   148 		rawinfo.Reserved = value.Info[i].Reserved
       
   149 	}
       
   150 
       
   151 	err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0])))
       
   152 
       
   153 	// Output
       
   154 	for i := range value.Info {
       
   155 		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
       
   156 			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
       
   157 				uintptr(i*SizeofRawFileDedupeRangeInfo)))
       
   158 		value.Info[i].Dest_fd = rawinfo.Dest_fd
       
   159 		value.Info[i].Dest_offset = rawinfo.Dest_offset
       
   160 		value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped
       
   161 		value.Info[i].Status = rawinfo.Status
       
   162 		value.Info[i].Reserved = rawinfo.Reserved
       
   163 	}
       
   164 
       
   165 	return err
       
   166 }
       
   167 
       
   168 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
       
   169 	err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value)))
       
   170 	runtime.KeepAlive(value)
       
   171 	return err
       
   172 }
       
   173 
       
   174 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
       
   175 	var value HIDRawDevInfo
       
   176 	err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value)))
       
   177 	return &value, err
       
   178 }
       
   179 
       
   180 func IoctlHIDGetRawName(fd int) (string, error) {
       
   181 	var value [_HIDIOCGRAWNAME_LEN]byte
       
   182 	err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0])))
       
   183 	return ByteSliceToString(value[:]), err
       
   184 }
       
   185 
       
   186 func IoctlHIDGetRawPhys(fd int) (string, error) {
       
   187 	var value [_HIDIOCGRAWPHYS_LEN]byte
       
   188 	err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0])))
       
   189 	return ByteSliceToString(value[:]), err
       
   190 }
       
   191 
       
   192 func IoctlHIDGetRawUniq(fd int) (string, error) {
       
   193 	var value [_HIDIOCGRAWUNIQ_LEN]byte
       
   194 	err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0])))
       
   195 	return ByteSliceToString(value[:]), err
       
   196 }