vendor/golang.org/x/sys/unix/ioctl_linux.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
child 262 8d3354485fc3
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
     3 // license that can be found in the LICENSE file.
     3 // license that can be found in the LICENSE file.
     4 
     4 
     5 package unix
     5 package unix
     6 
     6 
     7 import (
     7 import (
     8 	"runtime"
       
     9 	"unsafe"
     8 	"unsafe"
    10 )
     9 )
    11 
    10 
    12 // IoctlRetInt performs an ioctl operation specified by req on a device
    11 // IoctlRetInt performs an ioctl operation specified by req on a device
    13 // associated with opened file descriptor fd, and returns a non-negative
    12 // associated with opened file descriptor fd, and returns a non-negative
    20 	return int(ret), nil
    19 	return int(ret), nil
    21 }
    20 }
    22 
    21 
    23 func IoctlGetUint32(fd int, req uint) (uint32, error) {
    22 func IoctlGetUint32(fd int, req uint) (uint32, error) {
    24 	var value uint32
    23 	var value uint32
    25 	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
    24 	err := ioctlPtr(fd, req, unsafe.Pointer(&value))
    26 	return value, err
    25 	return value, err
    27 }
    26 }
    28 
    27 
    29 func IoctlGetRTCTime(fd int) (*RTCTime, error) {
    28 func IoctlGetRTCTime(fd int) (*RTCTime, error) {
    30 	var value RTCTime
    29 	var value RTCTime
    31 	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
    30 	err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value))
    32 	return &value, err
    31 	return &value, err
    33 }
    32 }
    34 
    33 
    35 func IoctlSetRTCTime(fd int, value *RTCTime) error {
    34 func IoctlSetRTCTime(fd int, value *RTCTime) error {
    36 	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
    35 	return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value))
    37 	runtime.KeepAlive(value)
       
    38 	return err
       
    39 }
    36 }
    40 
    37 
    41 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
    38 func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
    42 	var value RTCWkAlrm
    39 	var value RTCWkAlrm
    43 	err := ioctl(fd, RTC_WKALM_RD, uintptr(unsafe.Pointer(&value)))
    40 	err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value))
    44 	return &value, err
    41 	return &value, err
    45 }
    42 }
    46 
    43 
    47 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
    44 func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
    48 	err := ioctl(fd, RTC_WKALM_SET, uintptr(unsafe.Pointer(value)))
    45 	return ioctlPtr(fd, RTC_WKALM_SET, 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 }
    46 }
    57 
    47 
    58 // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
    48 // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
    59 // device specified by ifname.
    49 // device specified by ifname.
    60 func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
    50 func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
    61 	// Leave room for terminating NULL byte.
    51 	ifr, err := NewIfreq(ifname)
    62 	if len(ifname) >= IFNAMSIZ {
    52 	if err != nil {
    63 		return nil, EINVAL
    53 		return nil, err
    64 	}
    54 	}
    65 
    55 
    66 	value := EthtoolDrvinfo{
    56 	value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}
    67 		Cmd: ETHTOOL_GDRVINFO,
    57 	ifrd := ifr.withData(unsafe.Pointer(&value))
    68 	}
    58 
    69 	ifreq := ifreqEthtool{
    59 	err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
    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
    60 	return &value, err
    76 }
    61 }
    77 
    62 
    78 // IoctlGetWatchdogInfo fetches information about a watchdog device from the
    63 // IoctlGetWatchdogInfo fetches information about a watchdog device from the
    79 // Linux watchdog API. For more information, see:
    64 // Linux watchdog API. For more information, see:
    80 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
    65 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
    81 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
    66 func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
    82 	var value WatchdogInfo
    67 	var value WatchdogInfo
    83 	err := ioctl(fd, WDIOC_GETSUPPORT, uintptr(unsafe.Pointer(&value)))
    68 	err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value))
    84 	return &value, err
    69 	return &value, err
    85 }
    70 }
    86 
    71 
    87 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
    72 // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
    88 // more information, see:
    73 // more information, see:
    89 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
    74 // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
    90 func IoctlWatchdogKeepalive(fd int) error {
    75 func IoctlWatchdogKeepalive(fd int) error {
       
    76 	// arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr.
    91 	return ioctl(fd, WDIOC_KEEPALIVE, 0)
    77 	return ioctl(fd, WDIOC_KEEPALIVE, 0)
    92 }
    78 }
    93 
    79 
    94 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
    80 // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
    95 // range of data conveyed in value to the file associated with the file
    81 // 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.
    82 // descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
    97 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
    83 func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
    98 	err := ioctl(destFd, FICLONERANGE, uintptr(unsafe.Pointer(value)))
    84 	return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value))
    99 	runtime.KeepAlive(value)
       
   100 	return err
       
   101 }
    85 }
   102 
    86 
   103 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
    87 // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
   104 // associated with the file description srcFd to the file associated with the
    88 // 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.
    89 // file descriptor destFd. See the ioctl_ficlone(2) man page for details.
   146 		rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
   130 		rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
   147 		rawinfo.Status = value.Info[i].Status
   131 		rawinfo.Status = value.Info[i].Status
   148 		rawinfo.Reserved = value.Info[i].Reserved
   132 		rawinfo.Reserved = value.Info[i].Reserved
   149 	}
   133 	}
   150 
   134 
   151 	err := ioctl(srcFd, FIDEDUPERANGE, uintptr(unsafe.Pointer(&buf[0])))
   135 	err := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0]))
   152 
   136 
   153 	// Output
   137 	// Output
   154 	for i := range value.Info {
   138 	for i := range value.Info {
   155 		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
   139 		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
   156 			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
   140 			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
   164 
   148 
   165 	return err
   149 	return err
   166 }
   150 }
   167 
   151 
   168 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
   152 func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
   169 	err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value)))
   153 	return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value))
   170 	runtime.KeepAlive(value)
       
   171 	return err
       
   172 }
   154 }
   173 
   155 
   174 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
   156 func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
   175 	var value HIDRawDevInfo
   157 	var value HIDRawDevInfo
   176 	err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value)))
   158 	err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value))
   177 	return &value, err
   159 	return &value, err
   178 }
   160 }
   179 
   161 
   180 func IoctlHIDGetRawName(fd int) (string, error) {
   162 func IoctlHIDGetRawName(fd int) (string, error) {
   181 	var value [_HIDIOCGRAWNAME_LEN]byte
   163 	var value [_HIDIOCGRAWNAME_LEN]byte
   182 	err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0])))
   164 	err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0]))
   183 	return ByteSliceToString(value[:]), err
   165 	return ByteSliceToString(value[:]), err
   184 }
   166 }
   185 
   167 
   186 func IoctlHIDGetRawPhys(fd int) (string, error) {
   168 func IoctlHIDGetRawPhys(fd int) (string, error) {
   187 	var value [_HIDIOCGRAWPHYS_LEN]byte
   169 	var value [_HIDIOCGRAWPHYS_LEN]byte
   188 	err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0])))
   170 	err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0]))
   189 	return ByteSliceToString(value[:]), err
   171 	return ByteSliceToString(value[:]), err
   190 }
   172 }
   191 
   173 
   192 func IoctlHIDGetRawUniq(fd int) (string, error) {
   174 func IoctlHIDGetRawUniq(fd int) (string, error) {
   193 	var value [_HIDIOCGRAWUNIQ_LEN]byte
   175 	var value [_HIDIOCGRAWUNIQ_LEN]byte
   194 	err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0])))
   176 	err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))
   195 	return ByteSliceToString(value[:]), err
   177 	return ByteSliceToString(value[:]), err
   196 }
   178 }
       
   179 
       
   180 // IoctlIfreq performs an ioctl using an Ifreq structure for input and/or
       
   181 // output. See the netdevice(7) man page for details.
       
   182 func IoctlIfreq(fd int, req uint, value *Ifreq) error {
       
   183 	// It is possible we will add more fields to *Ifreq itself later to prevent
       
   184 	// misuse, so pass the raw *ifreq directly.
       
   185 	return ioctlPtr(fd, req, unsafe.Pointer(&value.raw))
       
   186 }
       
   187 
       
   188 // TODO(mdlayher): export if and when IfreqData is exported.
       
   189 
       
   190 // ioctlIfreqData performs an ioctl using an ifreqData structure for input
       
   191 // and/or output. See the netdevice(7) man page for details.
       
   192 func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
       
   193 	// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are
       
   194 	// identical so pass *IfreqData directly.
       
   195 	return ioctlPtr(fd, req, unsafe.Pointer(value))
       
   196 }
       
   197 
       
   198 // IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
       
   199 // existing KCM socket, returning a structure containing the file descriptor of
       
   200 // the new socket.
       
   201 func IoctlKCMClone(fd int) (*KCMClone, error) {
       
   202 	var info KCMClone
       
   203 	if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
       
   204 		return nil, err
       
   205 	}
       
   206 
       
   207 	return &info, nil
       
   208 }
       
   209 
       
   210 // IoctlKCMAttach attaches a TCP socket and associated BPF program file
       
   211 // descriptor to a multiplexor.
       
   212 func IoctlKCMAttach(fd int, info KCMAttach) error {
       
   213 	return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
       
   214 }
       
   215 
       
   216 // IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
       
   217 func IoctlKCMUnattach(fd int, info KCMUnattach) error {
       
   218 	return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
       
   219 }