Skip to content

Commit

Permalink
one pending read is blocking Run function
Browse files Browse the repository at this point in the history
  • Loading branch information
ivcosla committed Aug 6, 2019
1 parent 88b888b commit 3a6af1b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
21 changes: 18 additions & 3 deletions internal/therealssh/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (sshCh *SSHChannel) Request(requestType RequestType, payload []byte) ([]byt
return nil, fmt.Errorf("request failure: %s", err)
}

data := <-sshCh.msgCh
data := <- sshCh.msgCh
if data[0] == ResponseFail {
return nil, fmt.Errorf("request failure: %s", string(data[1:]))
}
Expand Down Expand Up @@ -117,8 +117,8 @@ func (sshCh *SSHChannel) Serve() error {
err = sshCh.Shell()
case RequestExec:
err = sshCh.Start(string(data[1:]))
//case RequestExecWithoutShell:

case RequestExecWithoutShell:
err = sshCh.Run(string(data[1:]))
case RequestWindowChange:
cols := binary.BigEndian.Uint32(data[1:])
rows := binary.BigEndian.Uint32(data[5:])
Expand Down Expand Up @@ -232,6 +232,21 @@ func (sshCh *SSHChannel) Start(command string) error {
return sshCh.session.Start(command)
}

// Run executes provided command on Channel's PTY session and returns output as []byte.
func (sshCh *SSHChannel) Run(command string) error {
if sshCh.session == nil {
return errors.New("session is not started")
}

out, err := sshCh.session.Run(command)
if err != nil {
return err
}

_, err = sshCh.Write(out)
return err
}

func (sshCh *SSHChannel) serveSession() error {
defer func() {
if err := sshCh.Send(CmdChannelServerClose, nil); err != nil {
Expand Down
11 changes: 9 additions & 2 deletions internal/therealssh/pty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ func TestRunInPTY(t *testing.T) {

server := NewServer(MockAuthorizer{})
go func() {
require.NoError(t, server.Serve(PipeWithRoutingAddr{acceptConn}))
err := server.Serve(PipeWithRoutingAddr{acceptConn})
fmt.Println("server.Serve finished with err: ", err)
require.NoError(t, err)
}()

_, ch, err := client.OpenChannel(cipher.PubKey{})
Expand All @@ -59,9 +61,14 @@ func TestRunInPTY(t *testing.T) {
require.NoError(t, err)
fmt.Println(res)

res, err = ch.Request(RequestExec, []byte("ls"))
res, err = ch.Request(RequestExecWithoutShell, []byte("ls"))
require.NoError(t, err)

b := make([]byte,6024)
_, err = ch.Read(b)
require.NoError(t, err)
fmt.Println(res)
fmt.Println("b: ", b)
}

type MockAuthorizer struct {}
Expand Down
2 changes: 1 addition & 1 deletion internal/therealssh/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const (
// RequestExec represents request for new process.
RequestExec
// RequestExec without shell, for use in integration testing.
// RequestExecWithoutShell
RequestExecWithoutShell
// RequestWindowChange represents request for PTY size change.
RequestWindowChange
)
Expand Down
18 changes: 8 additions & 10 deletions internal/therealssh/session.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package therealssh

import (
"errors"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -90,19 +89,18 @@ func (s *Session) Run(command string) ([]byte, error) {
}

components := strings.Split(command, " ")
cmd := exec.Command(components[0], components[1:]...) // nolint:gosec
err = cmd.Run()

c := exec.Command(components[0],components[1:]...)
ptmx, err := pty.Start(c)
if err != nil {
return nil, err
}
errP, _ := cmd.StderrPipe()
stdErr, _ := ioutil.ReadAll(errP)
out, _ := cmd.StdoutPipe()
res, _ := ioutil.ReadAll(out)

if len(stdErr) > 0 {
return res, errors.New(string(stdErr))
}
// Make sure to close the pty at the end.
defer func() { _ = ptmx.Close() }() // Best effort.

// as stated in https://github.com/creack/pty/issues/21#issuecomment-513069505 we can ignore this error
res, _ := ioutil.ReadAll(ptmx) // nolint: err
return res, nil
}

Expand Down

0 comments on commit 3a6af1b

Please sign in to comment.