-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Open
Labels
NeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.help wanted
Milestone
Description
What version of Go are you using (go version)?
$ go version go version go1.20.3 linux/amd64 $ go list -m golang.org/x/sys golang.org/x/sys v0.8.1-0.20230523194307-b5c7a0975ddc
What operating system and processor architecture are you using (go env)?
GOARCH=s390x
GOOS=linux
(using QEMU on an amd64 host)
What did you do?
package main
import (
"fmt"
"os"
"golang.org/x/sys/unix"
)
func main() {
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
panic(err)
}
pgid, err := unix.IoctlGetInt(int(tty.Fd()), unix.TIOCGPGRP)
fmt.Println(pgid, unix.Getpgrp())
}What did you expect to see?
Same number twice, as on amd64:
$ go run pgrp.go
101981 101981
What did you see instead?
$ GOARCH=s390x go run pgrp.go
438060894388224 101994
The first number is 101994<<32. I believe this happens because IoctlGetInt passes a pointer to a Go int to the system call:
func IoctlGetInt(fd int, req uint) (int, error) {
var value int
err := ioctlPtr(fd, req, unsafe.Pointer(&value))
return value, err
}The ioctl system call expects a pointer to a C int. Passing a Go int means it stores the pgid in the upper 32 bits.
Note that IoctlSetPointerInt passes a pointer to an int32:
func IoctlSetPointerInt(fd int, req uint, value int) error {
v := int32(value)
return ioctlPtr(fd, req, unsafe.Pointer(&v))
}Metadata
Metadata
Assignees
Labels
NeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.help wanted
Type
Projects
Status
Todo