~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/ssh/session.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 
10
10
import (
11
11
        "bytes"
 
12
        "encoding/binary"
12
13
        "errors"
13
14
        "fmt"
14
15
        "io"
281
282
// copying stdin, stdout, and stderr, and exits with a zero exit
282
283
// status.
283
284
//
284
 
// If the command fails to run or doesn't complete successfully, the
285
 
// error is of type *ExitError. Other error types may be
286
 
// returned for I/O problems.
 
285
// If the remote server does not send an exit status, an error of type
 
286
// *ExitMissingError is returned. If the command completes
 
287
// unsuccessfully or is interrupted by a signal, the error is of type
 
288
// *ExitError. Other error types may be returned for I/O problems.
287
289
func (s *Session) Run(cmd string) error {
288
290
        err := s.Start(cmd)
289
291
        if err != nil {
339
341
 
340
342
        ok, err := s.ch.SendRequest("shell", true, nil)
341
343
        if err == nil && !ok {
342
 
                return fmt.Errorf("ssh: cound not start shell")
 
344
                return errors.New("ssh: could not start shell")
343
345
        }
344
346
        if err != nil {
345
347
                return err
370
372
// copying stdin, stdout, and stderr, and exits with a zero exit
371
373
// status.
372
374
//
373
 
// If the command fails to run or doesn't complete successfully, the
374
 
// error is of type *ExitError. Other error types may be
375
 
// returned for I/O problems.
 
375
// If the remote server does not send an exit status, an error of type
 
376
// *ExitMissingError is returned. If the command completes
 
377
// unsuccessfully or is interrupted by a signal, the error is of type
 
378
// *ExitError. Other error types may be returned for I/O problems.
376
379
func (s *Session) Wait() error {
377
380
        if !s.started {
378
381
                return errors.New("ssh: session not started")
400
403
        for msg := range reqs {
401
404
                switch msg.Type {
402
405
                case "exit-status":
403
 
                        d := msg.Payload
404
 
                        wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3])
 
406
                        wm.status = int(binary.BigEndian.Uint32(msg.Payload))
405
407
                case "exit-signal":
406
408
                        var sigval struct {
407
409
                                Signal     string
431
433
        if wm.status == -1 {
432
434
                // exit-status was never sent from server
433
435
                if wm.signal == "" {
434
 
                        return errors.New("wait: remote command exited without exit status or exit signal")
 
436
                        // signal was not sent either.  RFC 4254
 
437
                        // section 6.10 recommends against this
 
438
                        // behavior, but it is allowed, so we let
 
439
                        // clients handle it.
 
440
                        return &ExitMissingError{}
435
441
                }
436
442
                wm.status = 128
437
443
                if _, ok := signals[Signal(wm.signal)]; ok {
438
444
                        wm.status += signals[Signal(wm.signal)]
439
445
                }
440
446
        }
 
447
 
441
448
        return &ExitError{wm}
442
449
}
443
450
 
 
451
// ExitMissingError is returned if a session is torn down cleanly, but
 
452
// the server sends no confirmation of the exit status.
 
453
type ExitMissingError struct{}
 
454
 
 
455
func (e *ExitMissingError) Error() string {
 
456
        return "wait: remote command exited without exit status or exit signal"
 
457
}
 
458
 
444
459
func (s *Session) stdin() {
445
460
        if s.stdinpipe {
446
461
                return
601
616
}
602
617
 
603
618
func (w Waitmsg) String() string {
604
 
        return fmt.Sprintf("Process exited with: %v. Reason was: %v (%v)", w.status, w.msg, w.signal)
 
619
        str := fmt.Sprintf("Process exited with status %v", w.status)
 
620
        if w.signal != "" {
 
621
                str += fmt.Sprintf(" from signal %v", w.signal)
 
622
        }
 
623
        if w.msg != "" {
 
624
                str += fmt.Sprintf(". Reason was: %v", w.msg)
 
625
        }
 
626
        return str
605
627
}