diff --git a/pkg/mpio/mpio.go b/pkg/mpio/mpio.go index f16a411c..017ce6de 100644 --- a/pkg/mpio/mpio.go +++ b/pkg/mpio/mpio.go @@ -12,7 +12,9 @@ import ( "io" "os" "sync" + "syscall" + "github.com/creack/pty" "github.com/scripthaus-dev/mshell/pkg/base" "github.com/scripthaus-dev/mshell/pkg/packet" ) @@ -29,6 +31,8 @@ type Multiplexer struct { FdWriters map[int]*FdWriter // synchronized RunData map[int]*FdReader // synchronized CloseAfterStart []*os.File // synchronized + PtyFd *os.File + CmdProc *os.Process Sender *packet.PacketSender Input *packet.PacketParser @@ -51,6 +55,12 @@ func MakeMultiplexer(ck base.CommandKey, upr packet.UnknownPacketReporter) *Mult } } +func (m *Multiplexer) SetPtyFd(ptyFd *os.File) { + m.Lock.Lock() + defer m.Lock.Unlock() + m.PtyFd = ptyFd +} + func (m *Multiplexer) Close() { m.Lock.Lock() defer m.Lock.Unlock() @@ -220,11 +230,36 @@ func (m *Multiplexer) runPacketInputLoop() *packet.CmdDonePacketType { donePacket := pk.(*packet.CmdDonePacketType) return donePacket } + if pk.GetType() == packet.SpecialInputPacketStr { + inputPacket := pk.(*packet.SpecialInputPacketType) + m.processSpecialInputPacket(inputPacket) + } m.UPR.UnknownPacket(pk) } return nil } +func (m *Multiplexer) processSpecialInputPacket(pk *packet.SpecialInputPacketType) { + m.Lock.Lock() + ptyFd := m.PtyFd + cmdProc := m.CmdProc + m.Lock.Unlock() + if ptyFd == nil { + // no pty, maybe send a message back to server, but the server always starts with a pty, so this shouldn't be an issue + return + } + if pk.WinSize != nil { + winSize := &pty.Winsize{ + //Rows: base.BoundInt(pk.WinSize.Rows, shexec.MinTermRows, shexec.MaxTermRows), + //Cols: base.BoundInt(pk.Winsize.Cols, shexec.MinTermCols, shexec.MaxTermCols), + } + pty.Setsize(ptyFd, winSize) + if cmdProc != nil { + cmdProc.Signal(syscall.SIGWINCH) + } + } +} + func (m *Multiplexer) processDataPacket(dataPacket *packet.DataPacketType) error { realData, err := base64.StdEncoding.DecodeString(dataPacket.Data64) if err != nil { diff --git a/pkg/shexec/shexec.go b/pkg/shexec/shexec.go index a7080007..378dafa9 100644 --- a/pkg/shexec/shexec.go +++ b/pkg/shexec/shexec.go @@ -869,6 +869,7 @@ func RunCommandSimple(pk *packet.RunPacketType, sender *packet.PacketSender, fro cmdTty.Close() }() cmd.CmdPty = cmdPty + cmd.Multiplexer.SetPtyFd(cmdPty) UpdateCmdEnv(cmd.Cmd, map[string]string{"TERM": getTermType(pk)}) } if cmdTty != nil { @@ -1050,6 +1051,7 @@ func RunCommandDetached(pk *packet.RunPacketType, sender *packet.PacketSender) ( cmd.CmdPty = cmdPty cmd.Detached = true cmd.MaxPtySize = DefaultMaxPtySize + cmd.Multiplexer.SetPtyFd(cmdPty) if pk.TermOpts != nil && pk.TermOpts.MaxPtySize > 0 { cmd.MaxPtySize = base.BoundInt64(pk.TermOpts.MaxPtySize, MinMaxPtySize, MaxMaxPtySize) }