|
|
@@ -282,9 +282,10 @@ func (s *Session) Start(cmd string) error {
|
|
|
// copying stdin, stdout, and stderr, and exits with a zero exit
|
|
|
// status.
|
|
|
//
|
|
|
-// If the command fails to run or doesn't complete successfully, the
|
|
|
-// error is of type *ExitError. Other error types may be
|
|
|
-// returned for I/O problems.
|
|
|
+// If the remote server does not send an exit status, an error of type
|
|
|
+// *ExitMissingError is returned. If the command completes
|
|
|
+// unsuccessfully or is interrupted by a signal, the error is of type
|
|
|
+// *ExitError. Other error types may be returned for I/O problems.
|
|
|
func (s *Session) Run(cmd string) error {
|
|
|
err := s.Start(cmd)
|
|
|
if err != nil {
|
|
|
@@ -371,9 +372,10 @@ func (s *Session) start() error {
|
|
|
// copying stdin, stdout, and stderr, and exits with a zero exit
|
|
|
// status.
|
|
|
//
|
|
|
-// If the command fails to run or doesn't complete successfully, the
|
|
|
-// error is of type *ExitError. Other error types may be
|
|
|
-// returned for I/O problems.
|
|
|
+// If the remote server does not send an exit status, an error of type
|
|
|
+// *ExitMissingError is returned. If the command completes
|
|
|
+// unsuccessfully or is interrupted by a signal, the error is of type
|
|
|
+// *ExitError. Other error types may be returned for I/O problems.
|
|
|
func (s *Session) Wait() error {
|
|
|
if !s.started {
|
|
|
return errors.New("ssh: session not started")
|
|
|
@@ -431,16 +433,29 @@ func (s *Session) wait(reqs <-chan *Request) error {
|
|
|
if wm.status == -1 {
|
|
|
// exit-status was never sent from server
|
|
|
if wm.signal == "" {
|
|
|
- return errors.New("wait: remote command exited without exit status or exit signal")
|
|
|
+ // signal was not sent either. RFC 4254
|
|
|
+ // section 6.10 recommends against this
|
|
|
+ // behavior, but it is allowed, so we let
|
|
|
+ // clients handle it.
|
|
|
+ return &ExitMissingError{}
|
|
|
}
|
|
|
wm.status = 128
|
|
|
if _, ok := signals[Signal(wm.signal)]; ok {
|
|
|
wm.status += signals[Signal(wm.signal)]
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return &ExitError{wm}
|
|
|
}
|
|
|
|
|
|
+// ExitMissingError is returned if a session is torn down cleanly, but
|
|
|
+// the server sends no confirmation of the exit status.
|
|
|
+type ExitMissingError struct{}
|
|
|
+
|
|
|
+func (e *ExitMissingError) Error() string {
|
|
|
+ return "wait: remote command exited without exit status or exit signal"
|
|
|
+}
|
|
|
+
|
|
|
func (s *Session) stdin() {
|
|
|
if s.stdinpipe {
|
|
|
return
|