Browse Source

Simplify solaris implementation. (#120)

Remove golang.org/x/sys/unix dependency for solaris
Add new go build tag directives
Guillaume J. Charmes 1 year ago
parent
commit
f73a158a9a

+ 18 - 0
asm_solaris_amd64.s

@@ -0,0 +1,18 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc
+//+build gc
+
+#include "textflag.h"
+
+//
+// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go
+//
+
+TEXT ·sysvicall6(SB),NOSPLIT,$0-88
+	JMP	syscall·sysvicall6(SB)
+
+TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88
+	JMP	syscall·rawSysvicall6(SB)

+ 0 - 1
go.mod

@@ -1,4 +1,3 @@
 module github.com/creack/pty
 
 go 1.13
-

+ 7 - 1
ioctl.go

@@ -1,9 +1,15 @@
-// +build !windows,!solaris
+//go:build !windows && !solaris
+//+build !windows,!solaris
 
 package pty
 
 import "syscall"
 
+const (
+	TIOCGWINSZ = syscall.TIOCGWINSZ
+	TIOCSWINSZ = syscall.TIOCSWINSZ
+)
+
 func ioctl(fd, cmd, ptr uintptr) error {
 	_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
 	if e != 0 {

+ 2 - 1
ioctl_bsd.go

@@ -1,4 +1,5 @@
-// +build darwin dragonfly freebsd netbsd openbsd
+//go:build (darwin || dragonfly || freebsd || netbsd || openbsd)
+//+build darwin dragonfly freebsd netbsd openbsd
 
 package pty
 

+ 24 - 7
ioctl_solaris.go

@@ -1,31 +1,48 @@
+//go:build solaris
+//+build solaris
+
 package pty
 
 import (
+	"syscall"
 	"unsafe"
-
-	"golang.org/x/sys/unix"
 )
 
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+//go:linkname procioctl libc_ioctl
+var procioctl uintptr
+
 const (
 	// see /usr/include/sys/stropts.h
 	I_PUSH = uintptr((int32('S')<<8 | 002))
 	I_STR  = uintptr((int32('S')<<8 | 010))
 	I_FIND = uintptr((int32('S')<<8 | 013))
+
 	// see /usr/include/sys/ptms.h
 	ISPTM   = (int32('P') << 8) | 1
 	UNLKPT  = (int32('P') << 8) | 2
 	PTSSTTY = (int32('P') << 8) | 3
 	ZONEPT  = (int32('P') << 8) | 4
 	OWNERPT = (int32('P') << 8) | 5
+
+	// see /usr/include/sys/termios.h
+	TIOCSWINSZ = (uint32('T') << 8) | 103
+	TIOCGWINSZ = (uint32('T') << 8) | 104
 )
 
 type strioctl struct {
-	ic_cmd    int32
-	ic_timout int32
-	ic_len    int32
-	ic_dp     unsafe.Pointer
+	icCmd     int32
+	icTimeout int32
+	icLen     int32
+	icDP      unsafe.Pointer
 }
 
+// Defined in asm_solaris_amd64.s.
+func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
 func ioctl(fd, cmd, ptr uintptr) error {
-	return unix.IoctlSetInt(int(fd), uint(cmd), int(ptr))
+	if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 {
+		return errno
+	}
+	return nil
 }

+ 3 - 0
pty_darwin.go

@@ -1,3 +1,6 @@
+//go:build darwin
+//+build darwin
+
 package pty
 
 import (

+ 3 - 0
pty_dragonfly.go

@@ -1,3 +1,6 @@
+//go:build dragonfly
+//+build dragonfly
+
 package pty
 
 import (

+ 3 - 0
pty_freebsd.go

@@ -1,3 +1,6 @@
+//go:build freebsd
+//+build freebsd
+
 package pty
 
 import (

+ 6 - 3
pty_linux.go

@@ -1,3 +1,6 @@
+//go:build linux
+//+build linux
+
 package pty
 
 import (
@@ -28,7 +31,7 @@ func open() (pty, tty *os.File, err error) {
 		return nil, nil, err
 	}
 
-	t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
+	t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) //nolint:gosec // Expected Open from a variable.
 	if err != nil {
 		return nil, nil, err
 	}
@@ -37,7 +40,7 @@ func open() (pty, tty *os.File, err error) {
 
 func ptsname(f *os.File) (string, error) {
 	var n _C_uint
-	err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
+	err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) //nolint:gosec // Expected unsafe pointer for Syscall call.
 	if err != nil {
 		return "", err
 	}
@@ -47,5 +50,5 @@ func ptsname(f *os.File) (string, error) {
 func unlockpt(f *os.File) error {
 	var u _C_int
 	// use TIOCSPTLCK with a pointer to zero to clear the lock
-	return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
+	return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) //nolint:gosec // Expected unsafe pointer for Syscall call.
 }

+ 3 - 0
pty_netbsd.go

@@ -1,3 +1,6 @@
+//go:build netbsd
+//+build netbsd
+
 package pty
 
 import (

+ 3 - 0
pty_openbsd.go

@@ -1,3 +1,6 @@
+//go:build openbsd
+//+build openbsd
+
 package pty
 
 import (

+ 80 - 68
pty_solaris.go

@@ -1,3 +1,6 @@
+//go:build solaris
+//+build solaris
+
 package pty
 
 /* based on:
@@ -10,45 +13,50 @@ import (
 	"strconv"
 	"syscall"
 	"unsafe"
-
-	"golang.org/x/sys/unix"
 )
 
-const NODEV = ^uint64(0)
-
 func open() (pty, tty *os.File, err error) {
-	masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|unix.O_NOCTTY, 0)
-	//masterfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC|unix.O_NOCTTY, 0)
+	ptmxfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY, 0)
 	if err != nil {
 		return nil, nil, err
 	}
-	p := os.NewFile(uintptr(masterfd), "/dev/ptmx")
+	p := os.NewFile(uintptr(ptmxfd), "/dev/ptmx")
+	// In case of error after this point, make sure we close the ptmx fd.
+	defer func() {
+		if err != nil {
+			_ = p.Close() // Best effort.
+		}
+	}()
 
 	sname, err := ptsname(p)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	err = grantpt(p)
-	if err != nil {
+	if err := grantpt(p); err != nil {
 		return nil, nil, err
 	}
 
-	err = unlockpt(p)
-	if err != nil {
+	if err := unlockpt(p); err != nil {
 		return nil, nil, err
 	}
 
-	slavefd, err := syscall.Open(sname, os.O_RDWR|unix.O_NOCTTY, 0)
+	ptsfd, err := syscall.Open(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
 	if err != nil {
 		return nil, nil, err
 	}
-	t := os.NewFile(uintptr(slavefd), sname)
+	t := os.NewFile(uintptr(ptsfd), sname)
+
+	// In case of error after this point, make sure we close the pts fd.
+	defer func() {
+		if err != nil {
+			_ = t.Close() // Best effort.
+		}
+	}()
 
 	// pushing terminal driver STREAMS modules as per pts(7)
 	for _, mod := range []string{"ptem", "ldterm", "ttcompat"} {
-		err = streams_push(t, mod)
-		if err != nil {
+		if err := streamsPush(t, mod); err != nil {
 			return nil, nil, err
 		}
 	}
@@ -56,73 +64,79 @@ func open() (pty, tty *os.File, err error) {
 	return p, t, nil
 }
 
-func minor(x uint64) uint64 {
-	return x & 0377
-}
-
-func ptsdev(fd uintptr) uint64 {
-	istr := strioctl{ISPTM, 0, 0, nil}
-	err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr)))
+func ptsname(f *os.File) (string, error) {
+	dev, err := ptsdev(f.Fd())
 	if err != nil {
-		return NODEV
+		return "", err
 	}
-	var status unix.Stat_t
-	err = unix.Fstat(int(fd), &status)
-	if err != nil {
-		return NODEV
+	fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10)
+
+	if err := syscall.Access(fn, 0); err != nil {
+		return "", err
 	}
-	return uint64(minor(status.Rdev))
+	return fn, nil
 }
 
-func ptsname(f *os.File) (string, error) {
-	dev := ptsdev(f.Fd())
-	if dev == NODEV {
-		return "", errors.New("not a master pty")
+func unlockpt(f *os.File) error {
+	istr := strioctl{
+		icCmd:     UNLKPT,
+		icTimeout: 0,
+		icLen:     0,
+		icDP:      nil,
 	}
-	fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10)
-	// access(2) creates the slave device (if the pty exists)
-	// F_OK == 0 (unistd.h)
-	err := unix.Access(fn, 0)
-	if err != nil {
-		return "", err
+	return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr)))
+}
+
+func minor(x uint64) uint64 { return x & 0377 }
+
+func ptsdev(fd uintptr) (uint64, error) {
+	istr := strioctl{
+		icCmd:     ISPTM,
+		icTimeout: 0,
+		icLen:     0,
+		icDP:      nil,
 	}
-	return fn, nil
+
+	if err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr))); err != nil {
+		return 0, err
+	}
+	var status syscall.Stat_t
+	if err := syscall.Fstat(int(fd), &status); err != nil {
+		return 0, err
+	}
+	return uint64(minor(status.Rdev)), nil
 }
 
-type pt_own struct {
-	pto_ruid int32
-	pto_rgid int32
+type ptOwn struct {
+	rUID int32
+	rGID int32
 }
 
 func grantpt(f *os.File) error {
-	if ptsdev(f.Fd()) == NODEV {
-		return errors.New("not a master pty")
-	}
-	var pto pt_own
-	pto.pto_ruid = int32(os.Getuid())
-	// XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty"
-	pto.pto_rgid = int32(os.Getgid())
-	var istr strioctl
-	istr.ic_cmd = OWNERPT
-	istr.ic_timout = 0
-	istr.ic_len = int32(unsafe.Sizeof(istr))
-	istr.ic_dp = unsafe.Pointer(&pto)
-	err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr)))
-	if err != nil {
+	if _, err := ptsdev(f.Fd()); err != nil {
+		return err
+	}
+	pto := ptOwn{
+		rUID: int32(os.Getuid()),
+		// XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty"
+		rGID: int32(os.Getgid()),
+	}
+	istr := strioctl{
+		icCmd:     OWNERPT,
+		icTimeout: 0,
+		icLen:     int32(unsafe.Sizeof(strioctl{})),
+		icDP:      unsafe.Pointer(&pto),
+	}
+	if err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))); err != nil {
 		return errors.New("access denied")
 	}
 	return nil
 }
 
-func unlockpt(f *os.File) error {
-	istr := strioctl{UNLKPT, 0, 0, nil}
-	return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr)))
-}
-
-// push STREAMS modules if not already done so
-func streams_push(f *os.File, mod string) error {
-	var err error
+// streamsPush pushes STREAMS modules if not already done so.
+func streamsPush(f *os.File, mod string) error {
 	buf := []byte(mod)
+
 	// XXX I_FIND is not returning an error when the module
 	// is already pushed even though truss reports a return
 	// value of 1. A bug in the Go Solaris syscall interface?
@@ -131,10 +145,8 @@ func streams_push(f *os.File, mod string) error {
 	// but since we are not using libc or XPG4.2, we should not be
 	// double-pushing modules
 
-	err = ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0])))
-	if err != nil {
+	if err := ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0]))); err != nil {
 		return nil
 	}
-	err = ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0])))
-	return err
+	return ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0])))
 }

+ 2 - 1
pty_unsupported.go

@@ -1,4 +1,5 @@
-// +build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris
+//go:build !linux && !darwin && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris
+//+build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris
 
 package pty
 

+ 14 - 13
run.go

@@ -1,4 +1,5 @@
-// +build !windows
+//go:build !windows
+//+build !windows
 
 package pty
 
@@ -13,8 +14,8 @@ import (
 // corresponding pty.
 //
 // Starts the process in a new session and sets the controlling terminal.
-func Start(c *exec.Cmd) (pty *os.File, err error) {
-	return StartWithSize(c, nil)
+func Start(cmd *exec.Cmd) (*os.File, error) {
+	return StartWithSize(cmd, nil)
 }
 
 // StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
@@ -23,13 +24,13 @@ func Start(c *exec.Cmd) (pty *os.File, err error) {
 //
 // This will resize the pty to the specified size before starting the command.
 // Starts the process in a new session and sets the controlling terminal.
-func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) {
-	if c.SysProcAttr == nil {
-		c.SysProcAttr = &syscall.SysProcAttr{}
+func StartWithSize(cmd *exec.Cmd, ws *Winsize) (*os.File, error) {
+	if cmd.SysProcAttr == nil {
+		cmd.SysProcAttr = &syscall.SysProcAttr{}
 	}
-	c.SysProcAttr.Setsid = true
-	c.SysProcAttr.Setctty = true
-	return StartWithAttrs(c, sz, c.SysProcAttr)
+	cmd.SysProcAttr.Setsid = true
+	cmd.SysProcAttr.Setctty = true
+	return StartWithAttrs(cmd, ws, cmd.SysProcAttr)
 }
 
 // StartWithAttrs assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout,
@@ -41,16 +42,16 @@ func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) {
 //
 // This should generally not be needed. Used in some edge cases where it is needed to create a pty
 // without a controlling terminal.
-func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (pty *os.File, err error) {
+func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (*os.File, error) {
 	pty, tty, err := Open()
 	if err != nil {
 		return nil, err
 	}
-	defer tty.Close()
+	defer func() { _ = tty.Close() }() // Best effort.
 
 	if sz != nil {
 		if err := Setsize(pty, sz); err != nil {
-			pty.Close()
+			_ = pty.Close() // Best effort.
 			return nil, err
 		}
 	}
@@ -67,7 +68,7 @@ func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (pty *
 	c.SysProcAttr = attrs
 
 	if err := c.Start(); err != nil {
-		_ = pty.Close()
+		_ = pty.Close() // Best effort.
 		return nil, err
 	}
 	return pty, err

+ 2 - 1
types.go

@@ -1,4 +1,5 @@
-// +build ignore
+//go:build ignore
+//+build ignore
 
 package pty
 

+ 2 - 1
types_dragonfly.go

@@ -1,4 +1,5 @@
-// +build ignore
+//go:build ignore
+//+build ignore
 
 package pty
 

+ 2 - 1
types_freebsd.go

@@ -1,4 +1,5 @@
-// +build ignore
+//go:build ignore
+//+build ignore
 
 package pty
 

+ 6 - 3
types_netbsd.go

@@ -1,4 +1,5 @@
-// +build ignore
+//go:build ignore
+//+build ignore
 
 package pty
 
@@ -11,5 +12,7 @@ import "C"
 
 type ptmget C.struct_ptmget
 
-var ioctl_TIOCPTSNAME = C.TIOCPTSNAME
-var ioctl_TIOCGRANTPT = C.TIOCGRANTPT
+var (
+	ioctl_TIOCPTSNAME = C.TIOCPTSNAME
+	ioctl_TIOCGRANTPT = C.TIOCGRANTPT
+)

+ 2 - 1
types_openbsd.go

@@ -1,4 +1,5 @@
-// +build ignore
+//go:build ignore
+//+build ignore
 
 package pty
 

+ 0 - 64
util.go

@@ -1,64 +0,0 @@
-// +build !windows,!solaris
-
-package pty
-
-import (
-	"os"
-	"syscall"
-	"unsafe"
-)
-
-// InheritSize applies the terminal size of pty to tty. This should be run
-// in a signal handler for syscall.SIGWINCH to automatically resize the tty when
-// the pty receives a window size change notification.
-func InheritSize(pty, tty *os.File) error {
-	size, err := GetsizeFull(pty)
-	if err != nil {
-		return err
-	}
-	err = Setsize(tty, size)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-// Setsize resizes t to s.
-func Setsize(t *os.File, ws *Winsize) error {
-	return windowRectCall(ws, t.Fd(), syscall.TIOCSWINSZ)
-}
-
-// GetsizeFull returns the full terminal size description.
-func GetsizeFull(t *os.File) (size *Winsize, err error) {
-	var ws Winsize
-	err = windowRectCall(&ws, t.Fd(), syscall.TIOCGWINSZ)
-	return &ws, err
-}
-
-// Getsize returns the number of rows (lines) and cols (positions
-// in each line) in terminal t.
-func Getsize(t *os.File) (rows, cols int, err error) {
-	ws, err := GetsizeFull(t)
-	return int(ws.Rows), int(ws.Cols), err
-}
-
-// Winsize describes the terminal size.
-type Winsize struct {
-	Rows uint16 // ws_row: Number of rows (in cells)
-	Cols uint16 // ws_col: Number of columns (in cells)
-	X    uint16 // ws_xpixel: Width in pixels
-	Y    uint16 // ws_ypixel: Height in pixels
-}
-
-func windowRectCall(ws *Winsize, fd, a2 uintptr) error {
-	_, _, errno := syscall.Syscall(
-		syscall.SYS_IOCTL,
-		fd,
-		a2,
-		uintptr(unsafe.Pointer(ws)),
-	)
-	if errno != 0 {
-		return syscall.Errno(errno)
-	}
-	return nil
-}

+ 0 - 67
util_solaris.go

@@ -1,67 +0,0 @@
-//
-
-package pty
-
-import (
-	"os"
-
-	"golang.org/x/sys/unix"
-)
-
-const (
-	TIOCGWINSZ = 21608 // 'T' << 8 | 104
-	TIOCSWINSZ = 21607 // 'T' << 8 | 103
-)
-
-// Winsize describes the terminal size.
-type Winsize struct {
-	Rows uint16 // ws_row: Number of rows (in cells)
-	Cols uint16 // ws_col: Number of columns (in cells)
-	X    uint16 // ws_xpixel: Width in pixels
-	Y    uint16 // ws_ypixel: Height in pixels
-}
-
-// GetsizeFull returns the full terminal size description.
-func GetsizeFull(t *os.File) (size *Winsize, err error) {
-	var wsz *unix.Winsize
-	wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ)
-
-	if err != nil {
-		return nil, err
-	} else {
-		return &Winsize{wsz.Row, wsz.Col, wsz.Xpixel, wsz.Ypixel}, nil
-	}
-}
-
-// Get Windows Size
-func Getsize(t *os.File) (rows, cols int, err error) {
-	var wsz *unix.Winsize
-	wsz, err = unix.IoctlGetWinsize(int(t.Fd()), TIOCGWINSZ)
-
-	if err != nil {
-		return 80, 25, err
-	} else {
-		return int(wsz.Row), int(wsz.Col), nil
-	}
-}
-
-// InheritSize applies the terminal size of pty to tty. This should be run
-// in a signal handler for syscall.SIGWINCH to automatically resize the tty when
-// the pty receives a window size change notification.
-func InheritSize(pty, tty *os.File) error {
-	size, err := GetsizeFull(pty)
-	if err != nil {
-		return err
-	}
-	err = Setsize(tty, size)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-// Setsize resizes t to s.
-func Setsize(t *os.File, ws *Winsize) error {
-	wsz := unix.Winsize{ws.Rows, ws.Cols, ws.X, ws.Y}
-	return unix.IoctlSetWinsize(int(t.Fd()), TIOCSWINSZ, &wsz)
-}

+ 24 - 0
winsize.go

@@ -0,0 +1,24 @@
+package pty
+
+import "os"
+
+// InheritSize applies the terminal size of pty to tty. This should be run
+// in a signal handler for syscall.SIGWINCH to automatically resize the tty when
+// the pty receives a window size change notification.
+func InheritSize(pty, tty *os.File) error {
+	size, err := GetsizeFull(pty)
+	if err != nil {
+		return err
+	}
+	if err := Setsize(tty, size); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Getsize returns the number of rows (lines) and cols (positions
+// in each line) in terminal t.
+func Getsize(t *os.File) (rows, cols int, err error) {
+	ws, err := GetsizeFull(t)
+	return int(ws.Rows), int(ws.Cols), err
+}

+ 35 - 0
winsize_unix.go

@@ -0,0 +1,35 @@
+//go:build !windows
+//+build !windows
+
+package pty
+
+import (
+	"os"
+	"syscall"
+	"unsafe"
+)
+
+// Winsize describes the terminal size.
+type Winsize struct {
+	Rows uint16 // ws_row: Number of rows (in cells)
+	Cols uint16 // ws_col: Number of columns (in cells)
+	X    uint16 // ws_xpixel: Width in pixels
+	Y    uint16 // ws_ypixel: Height in pixels
+}
+
+// Setsize resizes t to s.
+func Setsize(t *os.File, ws *Winsize) error {
+	//nolint:gosec // Expected unsafe pointer for Syscall call.
+	return ioctl(t.Fd(), syscall.TIOCSWINSZ, uintptr(unsafe.Pointer(ws)))
+}
+
+// GetsizeFull returns the full terminal size description.
+func GetsizeFull(t *os.File) (size *Winsize, err error) {
+	var ws Winsize
+
+	//nolint:gosec // Expected unsafe pointer for Syscall call.
+	if err := ioctl(t.Fd(), syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws))); err != nil {
+		return nil, err
+	}
+	return &ws, nil
+}

+ 23 - 0
winsize_unsupported.go

@@ -0,0 +1,23 @@
+//go:build windows
+//+build windows
+
+package pty
+
+import (
+	"os"
+)
+
+// Winsize is a dummy struct to enable compilation on unsupported platforms.
+type Winsize struct {
+	Rows, Cols, X, Y uint
+}
+
+// Setsize resizes t to s.
+func Setsize(*os.File, *Winsize) error {
+	return ErrUnsupported
+}
+
+// GetsizeFull returns the full terminal size description.
+func GetsizeFull(*os.File) (*Winsize, error) {
+	return nil, ErrUnsupported
+}

+ 3 - 0
ztypes_386.go

@@ -1,3 +1,6 @@
+//go:build 386
+//+build 386
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 

+ 3 - 0
ztypes_amd64.go

@@ -1,3 +1,6 @@
+//go:build amd64
+//+build amd64
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 

+ 3 - 0
ztypes_arm.go

@@ -1,3 +1,6 @@
+//go:build arm
+//+build arm
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 

+ 3 - 2
ztypes_arm64.go

@@ -1,8 +1,9 @@
+//go:build arm64
+//+build arm64
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 
-// +build arm64
-
 package pty
 
 type (

+ 3 - 0
ztypes_dragonfly_amd64.go

@@ -1,3 +1,6 @@
+//go:build amd64 && dragonfly
+//+build amd64,dragonfly
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_dragonfly.go
 

+ 3 - 0
ztypes_freebsd_386.go

@@ -1,3 +1,6 @@
+//go:build 386 && freebsd
+//+build 386,freebsd
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_freebsd.go
 

+ 3 - 0
ztypes_freebsd_amd64.go

@@ -1,3 +1,6 @@
+//go:build amd64 && freebsd
+//+build amd64,freebsd
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_freebsd.go
 

+ 3 - 0
ztypes_freebsd_arm.go

@@ -1,3 +1,6 @@
+//go:build arm && freebsd
+//+build arm,freebsd
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_freebsd.go
 

+ 3 - 0
ztypes_freebsd_arm64.go

@@ -1,3 +1,6 @@
+//go:build arm64 && freebsd
+//+build arm64,freebsd
+
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs types_freebsd.go
 

+ 4 - 3
ztypes_loongarchx.go

@@ -1,9 +1,10 @@
+//go:build (loongarch32 || loongarch64) && linux
+//+build linux
+//+build loongarch32 loongarch64
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 
-// +build linux
-// +build loongarch32 loongarch64
-
 package pty
 
 type (

+ 4 - 3
ztypes_mipsx.go

@@ -1,9 +1,10 @@
+//go:build (mips || mipsle || mips64 || mips64le) && linux
+//+build linux
+//+build mips mipsle mips64 mips64le
+
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go
 
-// +build linux
-// +build mips mipsle mips64 mips64le
-
 package pty
 
 type (

+ 7 - 4
ztypes_netbsd_32bit_int.go

@@ -1,5 +1,6 @@
-// +build netbsd
-// +build 386 amd64 arm arm64
+//go:build (386 || amd64 || arm || arm64) && netbsd
+//+build netbsd
+//+build 386 amd64 arm arm64
 
 package pty
 
@@ -10,5 +11,7 @@ type ptmget struct {
 	Sn  [1024]int8
 }
 
-var ioctl_TIOCPTSNAME = 0x48087448
-var ioctl_TIOCGRANTPT = 0x20007447
+var (
+	ioctl_TIOCPTSNAME = 0x48087448
+	ioctl_TIOCGRANTPT = 0x20007447
+)

+ 3 - 2
ztypes_openbsd_32bit_int.go

@@ -1,5 +1,6 @@
-// +build openbsd
-// +build 386 amd64 arm arm64
+//go:build (386 || amd64 || arm || arm64) && solaris
+//+build openbsd
+//+build 386 amd64 arm arm64
 
 package pty
 

+ 2 - 1
ztypes_ppc64.go

@@ -1,4 +1,5 @@
-// +build ppc64
+//go:build ppc64
+//+build ppc64
 
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go

+ 2 - 1
ztypes_ppc64le.go

@@ -1,4 +1,5 @@
-// +build ppc64le
+//go:build ppc64le
+//+build ppc64le
 
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go

+ 3 - 2
ztypes_riscvx.go

@@ -1,8 +1,9 @@
+//go:build riscv || riscv64
+//+build riscv riscv64
+
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
 // cgo -godefs types.go
 
-// +build riscv riscv64
-
 package pty
 
 type (

+ 2 - 1
ztypes_s390x.go

@@ -1,4 +1,5 @@
-// +build s390x
+//go:build s390x
+//+build s390x
 
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types.go