60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
//go:build !windows
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"syscall"
|
|
|
|
"github.com/creack/pty"
|
|
)
|
|
|
|
type unixPty struct {
|
|
f *os.File
|
|
cmd *exec.Cmd
|
|
}
|
|
|
|
func (u *unixPty) Read(p []byte) (int, error) { return u.f.Read(p) }
|
|
func (u *unixPty) Write(p []byte) (int, error) { return u.f.Write(p) }
|
|
|
|
func (u *unixPty) Close() error {
|
|
if u.cmd != nil && u.cmd.Process != nil {
|
|
_ = u.cmd.Process.Kill()
|
|
}
|
|
return u.f.Close()
|
|
}
|
|
|
|
func (u *unixPty) Resize(cols, rows uint16) error {
|
|
return pty.Setsize(u.f, &pty.Winsize{Cols: cols, Rows: rows})
|
|
}
|
|
|
|
func (u *unixPty) Wait() (int, error) {
|
|
if u.cmd == nil {
|
|
return -1, nil
|
|
}
|
|
err := u.cmd.Wait()
|
|
if err != nil {
|
|
if ee, ok := err.(*exec.ExitError); ok {
|
|
if status, ok := ee.Sys().(syscall.WaitStatus); ok {
|
|
return status.ExitStatus(), nil
|
|
}
|
|
return ee.ExitCode(), nil
|
|
}
|
|
return -1, err
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
func startPty(ctx context.Context, shell []string, cols, rows uint16) (ptyHandle, error) {
|
|
cmd := exec.CommandContext(ctx, shell[0], shell[1:]...)
|
|
cmd.Env = append(os.Environ(), "TERM=xterm-256color")
|
|
|
|
f, err := pty.StartWithSize(cmd, &pty.Winsize{Cols: cols, Rows: rows})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &unixPty{f: f, cmd: cmd}, nil
|
|
}
|