-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version go1.13 linux/amd64
Does this issue reproduce with the latest release?
At the time of writing, yes, it reproduces with 1.13, which is the latest release.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build361474088=/tmp/go-build -gno-record-gcc-switches"
Issue
x/sys/unix and syscall have a Msghdr structure that looks like the following on 64-bit GOOS=linux, e.g., GOARCH=amd64:
type Msghdr struct {
Name *byte
Namelen uint32
Pad_cgo_0 [4]byte
Iov *Iovec
Iovlen uint64
Control *byte
Controllen uint64
Flags int32
Pad_cgo_1 [4]byte
}
On 32-bit GOOS=linux like GOARCH=386 it looks like:
type Msghdr struct {
Name *byte
Namelen uint32
Iov *Iovec
Iovlen uint32
Control *byte
Controllen uint32
Flags int32
}
The Iovlen and Controllen are of type uint64 on 64-bit GOOS=linux and of type uint32 on 32-bit GOOS=linux.
There is a method for setting the Controllen member given an int. Here is the GOARCH=386 version that converts the int length to uint32. There are corresponding versions for 64-bit Linuxes that convert to uint64.
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
However, there is no corresponding method for setting the Iovlen member. In particular, there is no SetIovlen (GOARCH=386):
func (msghdr *Msghdr) SetIovlen(length int) {
msghdr.Iovlen = uint32(length)
}
This is an inconvenience, as it is difficult to write generic code that fills this structure on any Linux, 32-bit and 64-bit. For the sake of consistency and convenience, I'd expect there to be a setter for the Iovlen member as well.
The missing setter forces to use build tags like the following: internal/socket/msghdr_linux_64bit.go#L5 and maintain lists of which GOARCH are 32-bit and which are 64-bit.