mirror of
https://github.com/golang/sys.git
synced 2026-02-08 11:46:04 +03:00
ifreq is difficult to use in Go due to the union field in particular. This situation is made worse due to the need to comply with Go's unsafe.Pointer rules. This CL generates the raw ifreq type and also adds an ifreqData type of the same size which is specialized for use with unsafe.Pointer. We also replace the existing ifreqEthtool (which was not padded to the correct size) with the new APIs and add a test to verify that IoctlGetEthtoolDrvinfo functions properly by checking the name of the driver for each network interface. Future uses of ifreq in package unix can expand upon this type with additional getter and setter methods to deal with the unsafe casts to and from the union byte array. We may also consider exporting ifreq and ifreqData if necessary. Change-Id: Ibf73a10e774b4336815c674bb867bbb7ec1b9c71 Reviewed-on: https://go-review.googlesource.com/c/sys/+/340369 Run-TryBot: Matt Layher <mdlayher@gmail.com> Trust: Matt Layher <mdlayher@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
49 lines
1.3 KiB
Go
49 lines
1.3 KiB
Go
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build linux
|
|
// +build linux
|
|
|
|
package unix
|
|
|
|
import "unsafe"
|
|
|
|
// Helpers for dealing with ifreq since it contains a union and thus requires a
|
|
// lot of unsafe.Pointer casts to use properly.
|
|
|
|
// newIfreq creates an ifreq with the input network interface name after
|
|
// validating the name does not exceed IFNAMSIZ-1 (trailing NULL required)
|
|
// bytes.
|
|
func newIfreq(name string) (*ifreq, error) {
|
|
// Leave room for terminating NULL byte.
|
|
if len(name) >= IFNAMSIZ {
|
|
return nil, EINVAL
|
|
}
|
|
|
|
var ifr ifreq
|
|
copy(ifr.Ifrn[:], name)
|
|
|
|
return &ifr, nil
|
|
}
|
|
|
|
// An ifreqData is an ifreq but with a typed unsafe.Pointer field for data in
|
|
// the union. This is required in order to comply with the unsafe.Pointer rules
|
|
// since the "pointer-ness" of data would not be preserved if it were cast into
|
|
// the byte array of a raw ifreq.
|
|
type ifreqData struct {
|
|
name [IFNAMSIZ]byte
|
|
data unsafe.Pointer
|
|
// Pad to the same size as ifreq.
|
|
_ [len(ifreq{}.Ifru) - SizeofPtr]byte
|
|
}
|
|
|
|
// SetData produces an ifreqData with the pointer p set for ioctls which require
|
|
// arbitrary pointer data.
|
|
func (ifr ifreq) SetData(p unsafe.Pointer) ifreqData {
|
|
return ifreqData{
|
|
name: ifr.Ifrn,
|
|
data: p,
|
|
}
|
|
}
|