From f1e97cdbcc13318cb3de39d9e67bc0241614dfcc Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Fri, 9 Mar 2018 15:57:36 +0100 Subject: Improved PtyMode (eows lib). - renamed PtsMode to PtyMode - used byte array instead of string - allowed terminal echo on/off (PtyMode only) - fixed support escaped and control characters (PtyMode only) Signed-off-by: Sebastien Douheret --- golib/eows/eows.go | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'golib/eows/eows.go') diff --git a/golib/eows/eows.go b/golib/eows/eows.go index 283d673..9d0b520 100644 --- a/golib/eows/eows.go +++ b/golib/eows/eows.go @@ -16,10 +16,10 @@ import ( ) // OnInputCB is the function callback used to receive data -type OnInputCB func(e *ExecOverWS, stdin string) (string, error) +type OnInputCB func(e *ExecOverWS, stdin []byte) ([]byte, error) // EmitOutputCB is the function callback used to emit data -type EmitOutputCB func(e *ExecOverWS, stdout, stderr string) +type EmitOutputCB func(e *ExecOverWS, stdout, stderr []byte) // EmitExitCB is the function callback used to emit exit proc code type EmitExitCB func(e *ExecOverWS, code int, err error) @@ -60,7 +60,8 @@ type ExecOverWS struct { UserData *map[string]interface{} // user data passed to callbacks OutSplit SplitType // split method to tokenize stdout/stderr LineTimeSpan int64 // time span (only used with SplitTime or SplitLineTime) - PtsMode bool // Allocate a pseudo-terminal (allow to execute screen-based program) + PtyMode bool // Allocate a pseudo-terminal (allow to execute screen-based program) + PtyTermEcho bool // Turn on/off terminal echo // Private fields @@ -84,7 +85,8 @@ func New(cmd string, args []string, so *socketio.Socket, soID, cmdID string) *Ex CmdExecTimeout: -1, // default no timeout OutSplit: SplitLineTime, // default split by line with time LineTimeSpan: 500 * time.Millisecond.Nanoseconds(), - PtsMode: false, + PtyMode: false, + PtyTermEcho: true, } cmdIDMap[cmdID] = e @@ -114,7 +116,7 @@ func (e *ExecOverWS) Start() error { e.procExited = false - if e.PtsMode { + if e.PtyMode { e.command = exec.Command(bashArgs[0], bashArgs[1:]...) e.command.Env = append(os.Environ(), e.Env...) @@ -126,7 +128,9 @@ func (e *ExecOverWS) Start() error { e.proc = e.command.Process // Turn off terminal echo - e.terminalEcho(e.ptmx, false) + if !e.PtyTermEcho { + e.terminalEcho(e.ptmx, false) + } } else { @@ -162,15 +166,15 @@ func (e *ExecOverWS) Start() error { go func() { stdoutDone := make(chan struct{}) - if e.PtsMode { + if e.PtyMode { // Make sure to close the pty at the end. defer e.ptmx.Close() // Handle both stdout mixed with stderr - go e.cmdPumpStdout(e.ptmx, stdoutDone) + go e.ptsPumpStdout(e.ptmx, stdoutDone) // Blocking function that poll input or wait for end of process - e.cmdPumpStdin(e.ptmx) + e.pumpStdin(e.ptmx) } else { // Make sure to close all pipes @@ -182,11 +186,11 @@ func (e *ExecOverWS) Start() error { defer inw.Close() // Handle stdout + stderr - go e.cmdPumpStdout(outr, stdoutDone) - go e.cmdPumpStderr(errr) + go e.pipePumpStdout(outr, stdoutDone) + go e.pipePumpStderr(errr) // Blocking function that poll input or wait for end of process - e.cmdPumpStdin(inw) + e.pumpStdin(inw) } if status, err := e.proc.Wait(); err == nil { @@ -222,8 +226,8 @@ exitErr: // TerminalSetSize Set terminal size func (e *ExecOverWS) TerminalSetSize(rows, cols uint16) error { - if !e.PtsMode || e.ptmx == nil { - return fmt.Errorf("PtsMode not set") + if !e.PtyMode || e.ptmx == nil { + return fmt.Errorf("PtyMode not set") } w, err := pty.GetsizeFull(e.ptmx) if err != nil { @@ -234,8 +238,8 @@ func (e *ExecOverWS) TerminalSetSize(rows, cols uint16) error { // TerminalSetSizePos Set terminal size and position func (e *ExecOverWS) TerminalSetSizePos(rows, cols, x, y uint16) error { - if !e.PtsMode || e.ptmx == nil { - return fmt.Errorf("PtsMode not set") + if !e.PtyMode || e.ptmx == nil { + return fmt.Errorf("PtyMode not set") } winSz := pty.Winsize{Rows: rows, Cols: cols, X: x, Y: y} return pty.Setsize(e.ptmx, &winSz) -- cgit 1.2.3-korg