github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/communicator/remote/command.go (about)

     1  package remote
     2  
     3  import (
     4  	"io"
     5  	"sync"
     6  )
     7  
     8  // Cmd represents a remote command being prepared or run.
     9  type Cmd struct {
    10  	// Command is the command to run remotely. This is executed as if
    11  	// it were a shell command, so you are expected to do any shell escaping
    12  	// necessary.
    13  	Command string
    14  
    15  	// Stdin specifies the process's standard input. If Stdin is
    16  	// nil, the process reads from an empty bytes.Buffer.
    17  	Stdin io.Reader
    18  
    19  	// Stdout and Stderr represent the process's standard output and
    20  	// error.
    21  	//
    22  	// If either is nil, it will be set to ioutil.Discard.
    23  	Stdout io.Writer
    24  	Stderr io.Writer
    25  
    26  	// This will be set to true when the remote command has exited. It
    27  	// shouldn't be set manually by the user, but there is no harm in
    28  	// doing so.
    29  	Exited bool
    30  
    31  	// Once Exited is true, this will contain the exit code of the process.
    32  	ExitStatus int
    33  
    34  	// Internal fields
    35  	exitCh chan struct{}
    36  
    37  	// This thing is a mutex, lock when making modifications concurrently
    38  	sync.Mutex
    39  }
    40  
    41  // SetExited is a helper for setting that this process is exited. This
    42  // should be called by communicators who are running a remote command in
    43  // order to set that the command is done.
    44  func (r *Cmd) SetExited(status int) {
    45  	r.Lock()
    46  	defer r.Unlock()
    47  
    48  	if r.exitCh == nil {
    49  		r.exitCh = make(chan struct{})
    50  	}
    51  
    52  	r.Exited = true
    53  	r.ExitStatus = status
    54  	close(r.exitCh)
    55  }
    56  
    57  // Wait waits for the remote command to complete.
    58  func (r *Cmd) Wait() {
    59  	// Make sure our condition variable is initialized.
    60  	r.Lock()
    61  	if r.exitCh == nil {
    62  		r.exitCh = make(chan struct{})
    63  	}
    64  	r.Unlock()
    65  
    66  	<-r.exitCh
    67  }