add z/OS support

This commit is contained in:
Mac Malainey
2024-10-28 13:11:43 -04:00
parent 2cde18bfb7
commit 13c571dda3
3 changed files with 83 additions and 3 deletions

View File

@@ -12,6 +12,8 @@ import (
"syscall"
"testing"
"time"
"golang.org/x/sys/unix"
)
const (
@@ -106,9 +108,19 @@ func prepare(t *testing.T) (ptmx *os.File, done func()) {
if err != nil {
t.Fatalf("Error: open: %s.\n", err)
}
t.Cleanup(func() { _ = ptmx.Close() })
_ptmx := ptmx
t.Cleanup(func() { _ = _ptmx.Close() })
t.Cleanup(func() { _ = pts.Close() })
// z/OS doesn't open a pollable FD - fix that here
if runtime.GOOS == "zos" {
if _, err = unix.Fcntl(uintptr(ptmx.Fd()), unix.F_SETFL, unix.O_NONBLOCK); err != nil {
t.Fatalf("Error: zos-nonblock: %s.\n", err)
}
ptmx = os.NewFile(ptmx.Fd(), "/dev/ptmx")
t.Cleanup(func() { _ = ptmx.Close() })
}
ctx, done := context.WithCancel(context.Background())
t.Cleanup(done)
go func() {

View File

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

68
pty_zos.go Normal file
View File

@@ -0,0 +1,68 @@
//go:build zos
// +build zos
package pty
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
func open() (pty, tty *os.File, err error) {
ptmxfd, err := unix.Posix_openpt(os.O_RDWR|syscall.O_NOCTTY)
if err != nil {
return nil, nil, err
}
// Needed for z/OS so that the characters are not garbled if ptyp* is untagged
cvtreq := unix.F_cnvrt{Cvtcmd: unix.SETCVTON, Pccsid: 0, Fccsid: 1047}
if _, err = unix.Fcntl(uintptr(ptmxfd), unix.F_CONTROL_CVT, &cvtreq); err != nil {
return nil, nil, err
}
p := os.NewFile(uintptr(ptmxfd), "/dev/ptmx")
if p == nil {
return nil, nil, err
}
// 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 := unix.Ptsname(ptmxfd)
if err != nil {
return nil, nil, err
}
_, err = unix.Grantpt(ptmxfd)
if err != nil {
return nil, nil, err
}
if _, err = unix.Unlockpt(ptmxfd); err != nil {
return nil, nil, err
}
ptsfd, err := syscall.Open(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
if err != nil {
return nil, nil, err
}
if _, err = unix.Fcntl(uintptr(ptsfd), unix.F_CONTROL_CVT, &cvtreq); err != nil {
return nil, nil, err
}
t := os.NewFile(uintptr(ptsfd), sname)
if err != nil {
return nil, nil, err
}
return p, t, nil
}