Source file src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go

     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 "unsafe"
     8  
     9  // IoctlRetInt performs an ioctl operation specified by req on a device
    10  // associated with opened file descriptor fd, and returns a non-negative
    11  // integer that is returned by the ioctl syscall.
    12  func IoctlRetInt(fd int, req uint) (int, error) {
    13  	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
    14  	if err != 0 {
    15  		return 0, err
    16  	}
    17  	return int(ret), nil
    18  }
    19  
    20  func IoctlGetUint32(fd int, req uint) (uint32, error) {
    21  	var value uint32
    22  	err := ioctlPtr(fd, req, unsafe.Pointer(&value))
    23  	return value, err
    24  }
    25  
    26  func IoctlGetRTCTime(fd int) (*RTCTime, error) {
    27  	var value RTCTime
    28  	err := ioctlPtr(fd, RTC_RD_TIME, unsafe.Pointer(&value))
    29  	return &value, err
    30  }
    31  
    32  func IoctlSetRTCTime(fd int, value *RTCTime) error {
    33  	return ioctlPtr(fd, RTC_SET_TIME, unsafe.Pointer(value))
    34  }
    35  
    36  func IoctlGetRTCWkAlrm(fd int) (*RTCWkAlrm, error) {
    37  	var value RTCWkAlrm
    38  	err := ioctlPtr(fd, RTC_WKALM_RD, unsafe.Pointer(&value))
    39  	return &value, err
    40  }
    41  
    42  func IoctlSetRTCWkAlrm(fd int, value *RTCWkAlrm) error {
    43  	return ioctlPtr(fd, RTC_WKALM_SET, unsafe.Pointer(value))
    44  }
    45  
    46  // IoctlGetEthtoolDrvinfo fetches ethtool driver information for the network
    47  // device specified by ifname.
    48  func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) {
    49  	ifr, err := NewIfreq(ifname)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	value := EthtoolDrvinfo{Cmd: ETHTOOL_GDRVINFO}
    55  	ifrd := ifr.withData(unsafe.Pointer(&value))
    56  
    57  	err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
    58  	return &value, err
    59  }
    60  
    61  // IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC
    62  // association for the network device specified by ifname.
    63  func IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) {
    64  	ifr, err := NewIfreq(ifname)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	value := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO}
    70  	ifrd := ifr.withData(unsafe.Pointer(&value))
    71  
    72  	err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd)
    73  	return &value, err
    74  }
    75  
    76  // IoctlGetHwTstamp retrieves the hardware timestamping configuration
    77  // for the network device specified by ifname.
    78  func IoctlGetHwTstamp(fd int, ifname string) (*HwTstampConfig, error) {
    79  	ifr, err := NewIfreq(ifname)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	value := HwTstampConfig{}
    85  	ifrd := ifr.withData(unsafe.Pointer(&value))
    86  
    87  	err = ioctlIfreqData(fd, SIOCGHWTSTAMP, &ifrd)
    88  	return &value, err
    89  }
    90  
    91  // IoctlSetHwTstamp updates the hardware timestamping configuration for
    92  // the network device specified by ifname.
    93  func IoctlSetHwTstamp(fd int, ifname string, cfg *HwTstampConfig) error {
    94  	ifr, err := NewIfreq(ifname)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	ifrd := ifr.withData(unsafe.Pointer(cfg))
    99  	return ioctlIfreqData(fd, SIOCSHWTSTAMP, &ifrd)
   100  }
   101  
   102  // FdToClockID derives the clock ID from the file descriptor number
   103  // - see clock_gettime(3), FD_TO_CLOCKID macros. The resulting ID is
   104  // suitable for system calls like ClockGettime.
   105  func FdToClockID(fd int) int32 { return int32((int(^fd) << 3) | 3) }
   106  
   107  // IoctlPtpClockGetcaps returns the description of a given PTP device.
   108  func IoctlPtpClockGetcaps(fd int) (*PtpClockCaps, error) {
   109  	var value PtpClockCaps
   110  	err := ioctlPtr(fd, PTP_CLOCK_GETCAPS2, unsafe.Pointer(&value))
   111  	return &value, err
   112  }
   113  
   114  // IoctlPtpSysOffsetPrecise returns a description of the clock
   115  // offset compared to the system clock.
   116  func IoctlPtpSysOffsetPrecise(fd int) (*PtpSysOffsetPrecise, error) {
   117  	var value PtpSysOffsetPrecise
   118  	err := ioctlPtr(fd, PTP_SYS_OFFSET_PRECISE2, unsafe.Pointer(&value))
   119  	return &value, err
   120  }
   121  
   122  // IoctlPtpSysOffsetExtended returns an extended description of the
   123  // clock offset compared to the system clock. The samples parameter
   124  // specifies the desired number of measurements.
   125  func IoctlPtpSysOffsetExtended(fd int, samples uint) (*PtpSysOffsetExtended, error) {
   126  	value := PtpSysOffsetExtended{Samples: uint32(samples)}
   127  	err := ioctlPtr(fd, PTP_SYS_OFFSET_EXTENDED2, unsafe.Pointer(&value))
   128  	return &value, err
   129  }
   130  
   131  // IoctlPtpPinGetfunc returns the configuration of the specified
   132  // I/O pin on given PTP device.
   133  func IoctlPtpPinGetfunc(fd int, index uint) (*PtpPinDesc, error) {
   134  	value := PtpPinDesc{Index: uint32(index)}
   135  	err := ioctlPtr(fd, PTP_PIN_GETFUNC2, unsafe.Pointer(&value))
   136  	return &value, err
   137  }
   138  
   139  // IoctlPtpPinSetfunc updates configuration of the specified PTP
   140  // I/O pin.
   141  func IoctlPtpPinSetfunc(fd int, pd *PtpPinDesc) error {
   142  	return ioctlPtr(fd, PTP_PIN_SETFUNC2, unsafe.Pointer(pd))
   143  }
   144  
   145  // IoctlPtpPeroutRequest configures the periodic output mode of the
   146  // PTP I/O pins.
   147  func IoctlPtpPeroutRequest(fd int, r *PtpPeroutRequest) error {
   148  	return ioctlPtr(fd, PTP_PEROUT_REQUEST2, unsafe.Pointer(r))
   149  }
   150  
   151  // IoctlPtpExttsRequest configures the external timestamping mode
   152  // of the PTP I/O pins.
   153  func IoctlPtpExttsRequest(fd int, r *PtpExttsRequest) error {
   154  	return ioctlPtr(fd, PTP_EXTTS_REQUEST2, unsafe.Pointer(r))
   155  }
   156  
   157  // IoctlGetWatchdogInfo fetches information about a watchdog device from the
   158  // Linux watchdog API. For more information, see:
   159  // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
   160  func IoctlGetWatchdogInfo(fd int) (*WatchdogInfo, error) {
   161  	var value WatchdogInfo
   162  	err := ioctlPtr(fd, WDIOC_GETSUPPORT, unsafe.Pointer(&value))
   163  	return &value, err
   164  }
   165  
   166  // IoctlWatchdogKeepalive issues a keepalive ioctl to a watchdog device. For
   167  // more information, see:
   168  // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html.
   169  func IoctlWatchdogKeepalive(fd int) error {
   170  	// arg is ignored and not a pointer, so ioctl is fine instead of ioctlPtr.
   171  	return ioctl(fd, WDIOC_KEEPALIVE, 0)
   172  }
   173  
   174  // IoctlFileCloneRange performs an FICLONERANGE ioctl operation to clone the
   175  // range of data conveyed in value to the file associated with the file
   176  // descriptor destFd. See the ioctl_ficlonerange(2) man page for details.
   177  func IoctlFileCloneRange(destFd int, value *FileCloneRange) error {
   178  	return ioctlPtr(destFd, FICLONERANGE, unsafe.Pointer(value))
   179  }
   180  
   181  // IoctlFileClone performs an FICLONE ioctl operation to clone the entire file
   182  // associated with the file description srcFd to the file associated with the
   183  // file descriptor destFd. See the ioctl_ficlone(2) man page for details.
   184  func IoctlFileClone(destFd, srcFd int) error {
   185  	return ioctl(destFd, FICLONE, uintptr(srcFd))
   186  }
   187  
   188  type FileDedupeRange struct {
   189  	Src_offset uint64
   190  	Src_length uint64
   191  	Reserved1  uint16
   192  	Reserved2  uint32
   193  	Info       []FileDedupeRangeInfo
   194  }
   195  
   196  type FileDedupeRangeInfo struct {
   197  	Dest_fd       int64
   198  	Dest_offset   uint64
   199  	Bytes_deduped uint64
   200  	Status        int32
   201  	Reserved      uint32
   202  }
   203  
   204  // IoctlFileDedupeRange performs an FIDEDUPERANGE ioctl operation to share the
   205  // range of data conveyed in value from the file associated with the file
   206  // descriptor srcFd to the value.Info destinations. See the
   207  // ioctl_fideduperange(2) man page for details.
   208  func IoctlFileDedupeRange(srcFd int, value *FileDedupeRange) error {
   209  	buf := make([]byte, SizeofRawFileDedupeRange+
   210  		len(value.Info)*SizeofRawFileDedupeRangeInfo)
   211  	rawrange := (*RawFileDedupeRange)(unsafe.Pointer(&buf[0]))
   212  	rawrange.Src_offset = value.Src_offset
   213  	rawrange.Src_length = value.Src_length
   214  	rawrange.Dest_count = uint16(len(value.Info))
   215  	rawrange.Reserved1 = value.Reserved1
   216  	rawrange.Reserved2 = value.Reserved2
   217  
   218  	for i := range value.Info {
   219  		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
   220  			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
   221  				uintptr(i*SizeofRawFileDedupeRangeInfo)))
   222  		rawinfo.Dest_fd = value.Info[i].Dest_fd
   223  		rawinfo.Dest_offset = value.Info[i].Dest_offset
   224  		rawinfo.Bytes_deduped = value.Info[i].Bytes_deduped
   225  		rawinfo.Status = value.Info[i].Status
   226  		rawinfo.Reserved = value.Info[i].Reserved
   227  	}
   228  
   229  	err := ioctlPtr(srcFd, FIDEDUPERANGE, unsafe.Pointer(&buf[0]))
   230  
   231  	// Output
   232  	for i := range value.Info {
   233  		rawinfo := (*RawFileDedupeRangeInfo)(unsafe.Pointer(
   234  			uintptr(unsafe.Pointer(&buf[0])) + uintptr(SizeofRawFileDedupeRange) +
   235  				uintptr(i*SizeofRawFileDedupeRangeInfo)))
   236  		value.Info[i].Dest_fd = rawinfo.Dest_fd
   237  		value.Info[i].Dest_offset = rawinfo.Dest_offset
   238  		value.Info[i].Bytes_deduped = rawinfo.Bytes_deduped
   239  		value.Info[i].Status = rawinfo.Status
   240  		value.Info[i].Reserved = rawinfo.Reserved
   241  	}
   242  
   243  	return err
   244  }
   245  
   246  func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error {
   247  	return ioctlPtr(fd, HIDIOCGRDESC, unsafe.Pointer(value))
   248  }
   249  
   250  func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) {
   251  	var value HIDRawDevInfo
   252  	err := ioctlPtr(fd, HIDIOCGRAWINFO, unsafe.Pointer(&value))
   253  	return &value, err
   254  }
   255  
   256  func IoctlHIDGetRawName(fd int) (string, error) {
   257  	var value [_HIDIOCGRAWNAME_LEN]byte
   258  	err := ioctlPtr(fd, _HIDIOCGRAWNAME, unsafe.Pointer(&value[0]))
   259  	return ByteSliceToString(value[:]), err
   260  }
   261  
   262  func IoctlHIDGetRawPhys(fd int) (string, error) {
   263  	var value [_HIDIOCGRAWPHYS_LEN]byte
   264  	err := ioctlPtr(fd, _HIDIOCGRAWPHYS, unsafe.Pointer(&value[0]))
   265  	return ByteSliceToString(value[:]), err
   266  }
   267  
   268  func IoctlHIDGetRawUniq(fd int) (string, error) {
   269  	var value [_HIDIOCGRAWUNIQ_LEN]byte
   270  	err := ioctlPtr(fd, _HIDIOCGRAWUNIQ, unsafe.Pointer(&value[0]))
   271  	return ByteSliceToString(value[:]), err
   272  }
   273  
   274  // IoctlIfreq performs an ioctl using an Ifreq structure for input and/or
   275  // output. See the netdevice(7) man page for details.
   276  func IoctlIfreq(fd int, req uint, value *Ifreq) error {
   277  	// It is possible we will add more fields to *Ifreq itself later to prevent
   278  	// misuse, so pass the raw *ifreq directly.
   279  	return ioctlPtr(fd, req, unsafe.Pointer(&value.raw))
   280  }
   281  
   282  // TODO(mdlayher): export if and when IfreqData is exported.
   283  
   284  // ioctlIfreqData performs an ioctl using an ifreqData structure for input
   285  // and/or output. See the netdevice(7) man page for details.
   286  func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
   287  	// The memory layout of IfreqData (type-safe) and ifreq (not type-safe) are
   288  	// identical so pass *IfreqData directly.
   289  	return ioctlPtr(fd, req, unsafe.Pointer(value))
   290  }
   291  
   292  // IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
   293  // existing KCM socket, returning a structure containing the file descriptor of
   294  // the new socket.
   295  func IoctlKCMClone(fd int) (*KCMClone, error) {
   296  	var info KCMClone
   297  	if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
   298  		return nil, err
   299  	}
   300  
   301  	return &info, nil
   302  }
   303  
   304  // IoctlKCMAttach attaches a TCP socket and associated BPF program file
   305  // descriptor to a multiplexor.
   306  func IoctlKCMAttach(fd int, info KCMAttach) error {
   307  	return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
   308  }
   309  
   310  // IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
   311  func IoctlKCMUnattach(fd int, info KCMUnattach) error {
   312  	return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
   313  }
   314  
   315  // IoctlLoopGetStatus64 gets the status of the loop device associated with the
   316  // file descriptor fd using the LOOP_GET_STATUS64 operation.
   317  func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
   318  	var value LoopInfo64
   319  	if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
   320  		return nil, err
   321  	}
   322  	return &value, nil
   323  }
   324  
   325  // IoctlLoopSetStatus64 sets the status of the loop device associated with the
   326  // file descriptor fd using the LOOP_SET_STATUS64 operation.
   327  func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
   328  	return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
   329  }
   330  
   331  // IoctlLoopConfigure configures all loop device parameters in a single step
   332  func IoctlLoopConfigure(fd int, value *LoopConfig) error {
   333  	return ioctlPtr(fd, LOOP_CONFIGURE, unsafe.Pointer(value))
   334  }
   335  

View as plain text