mirror of https://github.com/liamg/aminal.git
102 lines
2.1 KiB
Go
102 lines
2.1 KiB
Go
//+build !windows
|
|
|
|
package platform
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"syscall"
|
|
"unsafe"
|
|
|
|
"github.com/kr/pty"
|
|
)
|
|
|
|
type unixPty struct {
|
|
pty *os.File
|
|
tty *os.File
|
|
platformDependentSettings PlatformDependentSettings
|
|
}
|
|
|
|
type winsize struct {
|
|
Height uint16
|
|
Width uint16
|
|
x uint16 // ignored, but necessary for ioctl calls
|
|
y uint16 // ignored, but necessary for ioctl calls
|
|
}
|
|
|
|
func (p *unixPty) Read(b []byte) (int, error) {
|
|
if p == nil || p.pty == nil {
|
|
return 0, errors.New("Attempted to read from a deallocated pty")
|
|
}
|
|
return p.pty.Read(b)
|
|
}
|
|
|
|
func (p *unixPty) Write(b []byte) (int, error) {
|
|
if p == nil || p.pty == nil {
|
|
return 0, errors.New("Attempted to write to a deallocated pty")
|
|
}
|
|
return p.pty.Write(b)
|
|
}
|
|
|
|
func (p *unixPty) Close() error {
|
|
if p == nil || p.pty == nil {
|
|
return nil
|
|
}
|
|
ret := p.pty.Close()
|
|
p.pty = nil
|
|
p.tty = nil
|
|
return ret
|
|
}
|
|
|
|
func (p *unixPty) Resize(x, y int) error {
|
|
size := winsize{
|
|
Height: uint16(y),
|
|
Width: uint16(x),
|
|
x: 0,
|
|
y: 0,
|
|
}
|
|
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(p.pty.Fd()),
|
|
uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&size)))
|
|
|
|
if errno != 0 {
|
|
return errors.New(errno.Error())
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *unixPty) CreateGuestProcess(imagePath string) (Process, error) {
|
|
if p == nil || p.tty == nil {
|
|
return nil, errors.New("Attempted to create a process on a deallocated pty")
|
|
}
|
|
shell := newCmdProc(exec.Command(imagePath))
|
|
shell.cmd.Stdout = p.tty
|
|
shell.cmd.Stdin = p.tty
|
|
shell.cmd.Stderr = p.tty
|
|
shell.cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true}
|
|
if err := shell.cmd.Start(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return shell, nil
|
|
}
|
|
|
|
func (pty *unixPty) GetPlatformDependentSettings() PlatformDependentSettings {
|
|
return pty.platformDependentSettings
|
|
}
|
|
|
|
func NewPty(x, y int) (Pty, error) {
|
|
innerPty, innerTty, err := pty.Open()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &unixPty{
|
|
pty: innerPty,
|
|
tty: innerTty,
|
|
platformDependentSettings: PlatformDependentSettings{
|
|
OSCTerminators: map[rune]struct{}{0x07: {}, 0x5c: {}},
|
|
},
|
|
}, nil
|
|
}
|