Perform ioctl system calls through x/sys/unix

OpenBSD is removing the syscall(2) interface soon and ioctl operations using
syscall.Syscall6 will fail to link at runtime:

$ go test
tmpdir: /tmp
readline.test:/tmp/go-build2875288623/b001/readline.test: undefined symbol 'syscall'
ld.so: readline.test: lazy binding failed!
signal: killed
FAIL	github.com/chzyer/readline	0.008s

These calls must instead be performed using the golang.org/x/sys/unix package,
which links to the ioctl(2) libc stub instead of the generic syscall(2)
interface.
This commit is contained in:
Josh Rickmar 2023-10-24 20:00:38 +00:00
parent 7f93d88cd5
commit 2eea26bdea
4 changed files with 14 additions and 19 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.15
require (
github.com/chzyer/test v1.0.0
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5
golang.org/x/sys v0.13.0
)
require github.com/chzyer/logex v1.2.1

2
go.sum
View File

@ -4,3 +4,5 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -2,28 +2,20 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd
package readline
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
func getTermios(fd int) (*Termios, error) {
termios := new(Termios)
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 {
return nil, err
}
return termios, nil
termios, err := unix.IoctlGetTermios(fd, unix.TIOCGETA)
return (*Termios)(termios), err
}
func setTermios(fd int, termios *Termios) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0)
if err != 0 {
return err
}
return nil
return unix.IoctlSetTermios(fd, unix.TIOCSETA, (*unix.Termios)(termios))
}

View File

@ -2,23 +2,24 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || (linux && !appengine) || netbsd || openbsd
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
package readline
import (
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
type Termios syscall.Termios
// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (int, int, error) {
var dimensions [4]uint16
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0)
if err != 0 {
winsize, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
}
return int(dimensions[1]), int(dimensions[0]), nil
return int(winsize.Col), int(winsize.Row), nil
}