Skip to content

x/sys/unix: missing Msghdr.SetIovlen #34164

@antong

Description

@antong

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions