mirror of
https://github.com/creack/pty.git
synced 2026-03-31 02:27:08 +09:00
add z/OS support
This commit is contained in:
14
io_test.go
14
io_test.go
@@ -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() {
|
||||
|
||||
@@ -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
68
pty_zos.go
Normal 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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user