Files
cloudpods/pkg/webconsole/session/pty_session.go
邱剑 46dc114e76 Merge pull request #376 in YUNIONIO/onecloud from ~QUXUAN/onecloud:release/2.2.0 to release/2.2.0
* commit 'd525cea91689fcd47e68d836c1900bab1563a7bf':
  避免instance 缓存disk数据
2018-10-29 22:37:29 +08:00

88 lines
1.7 KiB
Go

package session
import (
"os"
"os/exec"
"os/signal"
"syscall"
"github.com/kr/pty"
"yunion.io/x/log"
)
type Pty struct {
Session *SSession
Cmd *exec.Cmd
Pty *os.File
sizeCh chan os.Signal
size *pty.Winsize
OriginSize *pty.Winsize
Show bool
IsOk bool
Buffer string
Output string
Command string
Exit bool
}
func NewPty(session *SSession) (p *Pty, err error) {
cmd := session.GetCommand()
p = &Pty{
Session: session,
Cmd: cmd,
Show: true,
IsOk: true,
Exit: false,
Pty: nil,
}
log.Debugf("[session %s] Start command: %#v", session.Id, cmd)
if cmd != nil {
p.Pty, err = pty.Start(p.Cmd)
if err != nil {
return
}
}
p.sizeCh = make(chan os.Signal, 1)
p.size = &pty.Winsize{}
p.startResizeMonitor()
signal.Notify(p.sizeCh, syscall.SIGWINCH) // Initail resize
return
}
func (p *Pty) startResizeMonitor() {
go func() {
for range p.sizeCh {
if p.Pty != nil {
if err := pty.Setsize(p.Pty, p.size); err != nil {
log.Errorf("Resize pty error: %v", err)
} else {
log.Debugf("Resize pty to %#v, cmd: %#v", p.size, p.Cmd)
}
}
p.OriginSize = p.size
}
}()
}
func (p *Pty) Resize(size *pty.Winsize) {
p.size = size
p.sizeCh <- syscall.SIGWINCH
}
func (p *Pty) Stop() {
if p.Pty != nil {
if err := p.Pty.Close(); err != nil {
log.Errorf("Close PTY error: %v", err)
}
}
if p.Cmd != nil && p.Cmd.Process != nil {
if err := p.Cmd.Process.Signal(os.Kill); err != nil {
log.Errorf("Kill command process error: %v", err)
} else if err := p.Cmd.Wait(); err != nil {
log.Errorf("Wait command error: %v", err)
}
}
p.Session.Close()
}