Compare commits
1 Commits
main
...
maisem/ssh
Author | SHA1 | Date |
---|---|---|
![]() |
0b95ace349 |
|
@ -476,7 +476,7 @@ func (ss *sshSession) launchProcess() error {
|
||||||
}
|
}
|
||||||
go resizeWindow(ptyDup /* arbitrary fd */, winCh)
|
go resizeWindow(ptyDup /* arbitrary fd */, winCh)
|
||||||
|
|
||||||
ss.tty = tty
|
ss.childPipes = []io.Closer{tty}
|
||||||
ss.stdin = pty
|
ss.stdin = pty
|
||||||
ss.stdout = os.NewFile(uintptr(ptyDup), pty.Name())
|
ss.stdout = os.NewFile(uintptr(ptyDup), pty.Name())
|
||||||
ss.stderr = nil // not available for pty
|
ss.stderr = nil // not available for pty
|
||||||
|
@ -658,11 +658,16 @@ func (ss *sshSession) startWithPTY() (ptyFile, tty *os.File, err error) {
|
||||||
|
|
||||||
// startWithStdPipes starts cmd with os.Pipe for Stdin, Stdout and Stderr.
|
// startWithStdPipes starts cmd with os.Pipe for Stdin, Stdout and Stderr.
|
||||||
func (ss *sshSession) startWithStdPipes() (err error) {
|
func (ss *sshSession) startWithStdPipes() (err error) {
|
||||||
var stdin io.WriteCloser
|
var (
|
||||||
var stdout, stderr io.ReadCloser
|
stdin io.WriteCloser
|
||||||
|
stdout, stderr io.ReadCloser
|
||||||
|
|
||||||
|
cStdin io.ReadCloser
|
||||||
|
cStdout, cStderr io.WriteCloser
|
||||||
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
for _, c := range []io.Closer{stdin, stdout, stderr} {
|
for _, c := range []io.Closer{stdin, stdout, stderr, cStdin, cStdout, cStderr} {
|
||||||
if c != nil {
|
if c != nil {
|
||||||
c.Close()
|
c.Close()
|
||||||
}
|
}
|
||||||
|
@ -673,24 +678,28 @@ func (ss *sshSession) startWithStdPipes() (err error) {
|
||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
return errors.New("nil cmd")
|
return errors.New("nil cmd")
|
||||||
}
|
}
|
||||||
stdin, err = cmd.StdinPipe()
|
ss.stdin, cStdin, err = os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stdout, err = cmd.StdoutPipe()
|
ss.stdout, cStdout, err = os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cStdin.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stderr, err = cmd.StderrPipe()
|
ss.stderr, cStderr, err = os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cStdin.Close()
|
||||||
|
cStdout.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
cmd.Stdin = cStdin
|
||||||
|
cmd.Stdout = cStdout
|
||||||
|
cmd.Stderr = cStderr
|
||||||
|
ss.childPipes = []io.Closer{cStdin, cStdout, cStderr}
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ss.stdin = stdin
|
|
||||||
ss.stdout = stdout
|
|
||||||
ss.stderr = stderr
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -826,9 +826,14 @@ type sshSession struct {
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
stdin io.WriteCloser
|
stdin io.WriteCloser
|
||||||
stdout io.ReadCloser
|
stdout io.ReadCloser
|
||||||
stderr io.Reader // nil for pty sessions
|
stderr io.ReadCloser // nil for pty sessions
|
||||||
ptyReq *ssh.Pty // non-nil for pty sessions
|
ptyReq *ssh.Pty // non-nil for pty sessions
|
||||||
tty *os.File // non-nil for pty sessions, must be closed after process exits
|
|
||||||
|
// childPipes is a list of pipes that need to be closed when the
|
||||||
|
// process exits.
|
||||||
|
// For pty sessions, this is the tty fd.
|
||||||
|
// For non-pty sessions, this is the stdin,stdout,stderr fds.
|
||||||
|
childPipes []io.Closer
|
||||||
|
|
||||||
// We use this sync.Once to ensure that we only terminate the process once,
|
// We use this sync.Once to ensure that we only terminate the process once,
|
||||||
// either it exits itself or is terminated
|
// either it exits itself or is terminated
|
||||||
|
@ -1146,10 +1151,13 @@ func (ss *sshSession) run() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ss.tty != nil {
|
defer func() {
|
||||||
// If running a tty session, close the tty when the session is done.
|
// It is our responsibility to close the FDs that were passed down to
|
||||||
defer ss.tty.Close()
|
// the child process.
|
||||||
|
for _, c := range ss.childPipes {
|
||||||
|
c.Close()
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
err = ss.cmd.Wait()
|
err = ss.cmd.Wait()
|
||||||
processDone.Store(true)
|
processDone.Store(true)
|
||||||
// This will either make the SSH Termination goroutine be a no-op,
|
// This will either make the SSH Termination goroutine be a no-op,
|
||||||
|
|
Loading…
Reference in New Issue