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 ( require (
github.com/chzyer/test v1.0.0 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 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= 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 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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 // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
// +build darwin dragonfly freebsd netbsd openbsd // +build darwin dragonfly freebsd netbsd openbsd
package readline package readline
import ( import (
"syscall" "golang.org/x/sys/unix"
"unsafe"
) )
func getTermios(fd int) (*Termios, error) { func getTermios(fd int) (*Termios, error) {
termios := new(Termios) termios, err := unix.IoctlGetTermios(fd, unix.TIOCGETA)
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) return (*Termios)(termios), err
if err != 0 {
return nil, err
}
return termios, nil
} }
func setTermios(fd int, termios *Termios) error { func setTermios(fd int, termios *Termios) error {
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSETA, uintptr(unsafe.Pointer(termios)), 0, 0, 0) return unix.IoctlSetTermios(fd, unix.TIOCSETA, (*unix.Termios)(termios))
if err != 0 {
return err
}
return nil
} }

View File

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