Skip to content

Commit

Permalink
add z/OS support
Browse files Browse the repository at this point in the history
  • Loading branch information
MacMalainey committed Oct 28, 2024
1 parent 2cde18b commit 13c571d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
14 changes: 13 additions & 1 deletion io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"syscall"
"testing"
"time"

"golang.org/x/sys/unix"

Check failure on line 16 in io_test.go

View workflow job for this annotation

GitHub Actions / Test go oldstable on ubuntu-latest

no required module provides package golang.org/x/sys/unix; to add it:

Check failure on line 16 in io_test.go

View workflow job for this annotation

GitHub Actions / Test go stable on macos-latest

no required module provides package golang.org/x/sys/unix; to add it:
)

const (
Expand Down Expand Up @@ -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() {
Expand Down
4 changes: 2 additions & 2 deletions pty_unsupported.go
Original file line number Diff line number Diff line change
@@ -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

Expand Down
68 changes: 68 additions & 0 deletions pty_zos.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 13c571d

Please sign in to comment.