// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gosh

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"sync"
	"syscall"
	"time"

	"v.io/x/lib/lookpath"
)

var (
	errAlreadyCalledStart = errors.New("gosh: already called Cmd.Start")
	errAlreadyCalledWait  = errors.New("gosh: already called Cmd.Wait")
	errAlreadySetStdin    = errors.New("gosh: already set stdin")
	errDidNotCallStart    = errors.New("gosh: did not call Cmd.Start")
	errProcessExited      = errors.New("gosh: process exited")
)

// Cmd represents a command. Not thread-safe.
// Public fields should not be modified after calling Start.
type Cmd struct {
	// Err is the most recent error from this Cmd (may be nil).
	Err error
	// Path is the path of the command to run.
	Path string
	// Vars is the map of env vars for this Cmd.
	Vars map[string]string
	// Args is the list of args for this Cmd, starting with the resolved path.
	// Note, we set Args[0] to the resolved path (rather than the user-specified
	// name) so that a command started by Shell can reliably determine the path to
	// its executable.
	Args []string
	// IgnoreParentExit, if true, makes it so the child process does not exit when
	// its parent exits. Only takes effect if the child process was spawned via
	// Shell.FuncCmd or explicitly calls InitChildMain.
	IgnoreParentExit bool
	// ExitAfter, if non-zero, specifies that the child process should exit after
	// the given duration has elapsed. Only takes effect if the child process was
	// spawned via Shell.FuncCmd or explicitly calls InitChildMain.
	ExitAfter time.Duration
	// PropagateOutput is inherited from Shell.Opts.PropagateChildOutput.
	PropagateOutput bool
	// OutputDir is inherited from Shell.Opts.ChildOutputDir.
	OutputDir string
	// ExitErrorIsOk specifies whether an *exec.ExitError should be reported via
	// Shell.HandleError.
	ExitErrorIsOk bool
	// IgnoreClosedPipeError, if true, causes errors from read/write on a closed
	// pipe to be indistinguishable from success. These errors often occur in
	// command pipelines, e.g. "yes | head -1", where "yes" will receive a closed
	// pipe error when it tries to write on stdout, after "head" has exited. If a
	// closed pipe error occurs, Cmd.Err will be nil, and no err is reported to
	// Shell.HandleError.
	IgnoreClosedPipeError bool
	// ExtraFiles is used to populate ExtraFiles in the underlying exec.Cmd
	// object.  Does not get cloned.
	ExtraFiles []*os.File
	// Internal state.
	sh                *Shell
	c                 *exec.Cmd
	calledStart       bool
	calledWait        bool
	cond              *sync.Cond
	waitChan          chan error
	stdinDoneChan     chan error
	started           bool // protected by sh.cleanupMu
	exited            bool // protected by cond.L
	stdoutWriters     []io.Writer
	stderrWriters     []io.Writer
	afterStartClosers []io.Closer
	afterWaitClosers  []io.Closer
	recvVars          map[string]string // protected by cond.L
}

// Shell returns the shell that this Cmd was created from.
func (c *Cmd) Shell() *Shell {
	return c.sh
}

// Clone returns a new Cmd with a copy of this Cmd's configuration.
func (c *Cmd) Clone() *Cmd {
	c.sh.Ok()
	res, err := c.clone()
	c.handleError(err)
	return res
}

// StdinPipe returns a WriteCloser backed by an unlimited-size pipe for the
// command's stdin. The pipe will be closed when the process exits, but may also
// be closed earlier by the caller, e.g. if the command does not exit until its
// stdin is closed. Must be called before Start. Only one call may be made to
// StdinPipe or SetStdinReader; subsequent calls will fail.
func (c *Cmd) StdinPipe() io.WriteCloser {
	c.sh.Ok()
	res, err := c.stdinPipe()
	c.handleError(err)
	return res
}

// StdoutPipe returns a ReadCloser backed by an unlimited-size pipe for the
// command's stdout. The pipe will be closed when the process exits, but may
// also be closed earlier by the caller, e.g. if all expected output has been
// received. Must be called before Start. May be called more than once; each
// call creates a new pipe.
func (c *Cmd) StdoutPipe() io.ReadCloser {
	c.sh.Ok()
	res, err := c.stdoutPipe()
	c.handleError(err)
	return res
}

// StderrPipe returns a ReadCloser backed by an unlimited-size pipe for the
// command's stderr. The pipe will be closed when the process exits, but may
// also be closed earlier by the caller, e.g. if all expected output has been
// received. Must be called before Start. May be called more than once; each
// call creates a new pipe.
func (c *Cmd) StderrPipe() io.ReadCloser {
	c.sh.Ok()
	res, err := c.stderrPipe()
	c.handleError(err)
	return res
}

// SetStdinReader configures this Cmd to read stdin from the given Reader. Must
// be called before Start. Only one call may be made to StdinPipe or
// SetStdinReader; subsequent calls will fail.
func (c *Cmd) SetStdinReader(r io.Reader) {
	c.sh.Ok()
	c.handleError(c.setStdinReader(r))
}

// AddStdoutWriter configures this Cmd to tee stdout to the given Writer. Must
// be called before Start. If the same Writer is passed to both AddStdoutWriter
// and AddStderrWriter, Cmd will ensure that Write is never called concurrently.
func (c *Cmd) AddStdoutWriter(w io.Writer) {
	c.sh.Ok()
	c.handleError(c.addStdoutWriter(w))
}

// AddStderrWriter configures this Cmd to tee stderr to the given Writer. Must
// be called before Start. If the same Writer is passed to both AddStdoutWriter
// and AddStderrWriter, Cmd will ensure that Write is never called concurrently.
func (c *Cmd) AddStderrWriter(w io.Writer) {
	c.sh.Ok()
	c.handleError(c.addStderrWriter(w))
}

// Start starts the command.
func (c *Cmd) Start() {
	c.sh.Ok()
	c.handleError(c.start())
}

// AwaitVars waits for the child process to send values for the given vars
// (e.g. using SendVars). Must not be called before Start or after Wait.
func (c *Cmd) AwaitVars(keys ...string) map[string]string {
	c.sh.Ok()
	res, err := c.awaitVars(keys...)
	c.handleError(err)
	return res
}

// Wait waits for the command to exit.
func (c *Cmd) Wait() {
	c.sh.Ok()
	c.handleError(c.wait())
}

// Signal sends a signal to the underlying process.
func (c *Cmd) Signal(sig os.Signal) {
	c.sh.Ok()
	c.handleError(c.signal(sig))
}

// Terminate sends a signal to the underlying process, then waits for it to
// exit. Terminate is different from Signal followed by Wait: Terminate succeeds
// as long as the process exits, whereas Wait fails if the exit code isn't 0.
func (c *Cmd) Terminate(sig os.Signal) {
	c.sh.Ok()
	c.handleError(c.terminate(sig))
}

// Run calls Start followed by Wait.
func (c *Cmd) Run() {
	c.sh.Ok()
	c.handleError(c.run())
}

// Stdout calls Start followed by Wait, then returns the command's stdout.
func (c *Cmd) Stdout() string {
	c.sh.Ok()
	res, err := c.stdout()
	c.handleError(err)
	return res
}

// StdoutStderr calls Start followed by Wait, then returns the command's stdout
// and stderr.
func (c *Cmd) StdoutStderr() (string, string) {
	c.sh.Ok()
	stdout, stderr, err := c.stdoutStderr()
	c.handleError(err)
	return stdout, stderr
}

// CombinedOutput calls Start followed by Wait, then returns the command's
// combined stdout and stderr.
func (c *Cmd) CombinedOutput() string {
	c.sh.Ok()
	res, err := c.combinedOutput()
	c.handleError(err)
	return res
}

// Pid returns the command's PID, or -1 if the command has not been started.
func (c *Cmd) Pid() int {
	if !c.started {
		return -1
	}
	return c.c.Process.Pid
}

////////////////////////////////////////
// Internals

func newCmdInternal(sh *Shell, vars map[string]string, path string, args []string) (*Cmd, error) {
	c := &Cmd{
		Path:     path,
		Vars:     vars,
		Args:     append([]string{path}, args...),
		sh:       sh,
		c:        &exec.Cmd{},
		cond:     sync.NewCond(&sync.Mutex{}),
		waitChan: make(chan error, 1),
		recvVars: map[string]string{},
	}
	// Protect against concurrent signal-triggered Shell.cleanup().
	sh.cleanupMu.Lock()
	defer sh.cleanupMu.Unlock()
	if sh.calledCleanup {
		return nil, errAlreadyCalledCleanup
	}
	sh.cmds = append(sh.cmds, c)
	return c, nil
}

func newCmd(sh *Shell, vars map[string]string, name string, args ...string) (*Cmd, error) {
	// Mimics https://golang.org/src/os/exec/exec.go Command.
	if filepath.Base(name) == name {
		dirs := splitTokens(sh.Vars["PATH"], ":")
		lp := lookpath.Look(dirs, name)
		if lp == "" {
			return nil, fmt.Errorf("gosh: failed to locate executable: %s", name)
		}
		name = lp
	}
	return newCmdInternal(sh, vars, name, args)
}

func (c *Cmd) errorIsOk(err error) bool {
	if c.ExitErrorIsOk {
		if _, ok := err.(*exec.ExitError); ok {
			return true
		}
	}
	return err == nil
}

// An explanation of closed pipe errors. Consider the pipeline "yes | head -1",
// where yes keeps writing "y\n" to stdout, and head succeeds after it reads the
// first line. There is an os pipe connecting the two commands, and when head
// exits, it causes yes to receive a closed pipe error on its next write. Should
// we consider such a pipeline to have succeeded or failed?
//
// Bash only looks at the exit status of the last command by default, thus the
// pipeline succeeds. But that's dangerous, since yes could have crashed and we
// wouldn't know. It's recommended to run "set -o pipefail" to tell bash to
// check the exit status of all commands. But that causes the pipeline to fail.
//
// IgnoreClosedPipeError handles this case. gosh.Pipeline sets this option to
// true, so that by default the pipeline above will succeed, but will fail on
// any other error. Note that the exec package always returns an ExitError if
// the child process exited with a non-zero exit code; the closed pipe error is
// only returned if the child process exited with a zero exit code, and Write on
// the io.MultiWriter in the parent process received the closed pipe error.
//
// TODO(toddw): We could adopt the convention that exit code 141 indicates
// "closed pipe", and use IgnoreClosedPipeError to also ignore that case. We
// choose 141 because it's 128 + 13, where SIGPIPE is 13, and there is an
// existing convention for this. By default Go programs ignore SIGPIPE, so we
// might also want to add code to InitChildMain to exit the program with 141 if
// it receives SIGPIPE.

func (c *Cmd) handleError(err error) {
	if c.IgnoreClosedPipeError && isClosedPipeError(err) {
		err = nil
	}
	c.Err = err
	if !c.errorIsOk(err) {
		c.sh.HandleError(err)
	}
}

func (c *Cmd) isRunning() bool {
	if !c.started {
		return false
	}
	c.cond.L.Lock()
	defer c.cond.L.Unlock()
	return !c.exited
}

// recvWriter listens for gosh vars from a child process.
type recvWriter struct {
	c             *Cmd
	buf           []byte
	matchedPrefix int
	matchedSuffix int
}

func (w *recvWriter) Write(p []byte) (n int, err error) {
	for i, b := range p {
		if w.matchedPrefix < len(varsPrefix) {
			// Look for matching prefix.
			if b != varsPrefix[w.matchedPrefix] {
				w.matchedPrefix = 0
			}
			if b == varsPrefix[w.matchedPrefix] {
				w.matchedPrefix++
			}
			continue
		}
		w.buf = append(w.buf, b)
		// Look for matching suffix.
		if b != varsSuffix[w.matchedSuffix] {
			w.matchedSuffix = 0
		}
		if b == varsSuffix[w.matchedSuffix] {
			w.matchedSuffix++
		}
		if w.matchedSuffix != len(varsSuffix) {
			continue
		}
		// Found matching suffix.
		data := w.buf[:len(w.buf)-len(varsSuffix)]
		w.buf = w.buf[:0]
		w.matchedPrefix, w.matchedSuffix = 0, 0
		vars := make(map[string]string)
		if err := json.Unmarshal(data, &vars); err != nil {
			return i, err
		}
		w.c.cond.L.Lock()
		w.c.recvVars = mergeMaps(w.c.recvVars, vars)
		w.c.cond.Signal()
		w.c.cond.L.Unlock()
	}
	return len(p), nil
}

func (c *Cmd) makeStdoutStderr() (io.Writer, io.Writer, error) {
	c.stderrWriters = append(c.stderrWriters, &recvWriter{c: c})
	if c.PropagateOutput {
		c.stdoutWriters = append(c.stdoutWriters, os.Stdout)
		c.stderrWriters = append(c.stderrWriters, os.Stderr)
	}
	if c.OutputDir != "" {
		t := time.Now().Format("20060102.150405.000000")
		name := filepath.Join(c.OutputDir, filepath.Base(c.Path)+"."+t)
		const flags = os.O_WRONLY | os.O_CREATE | os.O_EXCL
		switch file, err := os.OpenFile(name+".stdout", flags, 0600); {
		case err != nil:
			return nil, nil, err
		default:
			c.stdoutWriters = append(c.stdoutWriters, file)
			c.afterWaitClosers = append(c.afterWaitClosers, file)
		}
		switch file, err := os.OpenFile(name+".stderr", flags, 0600); {
		case err != nil:
			return nil, nil, err
		default:
			c.stderrWriters = append(c.stderrWriters, file)
			c.afterWaitClosers = append(c.afterWaitClosers, file)
		}
	}
	switch hasOut, hasErr := len(c.stdoutWriters) > 0, len(c.stderrWriters) > 0; {
	case hasOut && hasErr:
		// Make writes synchronous between stdout and stderr. This ensures all
		// writers that capture both will see the same ordering, and don't need to
		// worry about concurrent writes.
		sharedMu := &sync.Mutex{}
		stdout := &sharedLockWriter{sharedMu, io.MultiWriter(c.stdoutWriters...)}
		stderr := &sharedLockWriter{sharedMu, io.MultiWriter(c.stderrWriters...)}
		return stdout, stderr, nil
	case hasOut:
		return io.MultiWriter(c.stdoutWriters...), nil, nil
	case hasErr:
		return nil, io.MultiWriter(c.stderrWriters...), nil
	}
	return nil, nil, nil
}

type sharedLockWriter struct {
	mu *sync.Mutex
	w  io.Writer
}

func (w *sharedLockWriter) Write(p []byte) (int, error) {
	w.mu.Lock()
	n, err := w.w.Write(p)
	w.mu.Unlock()
	return n, err
}

func (c *Cmd) clone() (*Cmd, error) {
	args := make([]string, len(c.Args))
	copy(args, c.Args)
	res, err := newCmdInternal(c.sh, copyMap(c.Vars), c.Path, args[1:])
	if err != nil {
		return nil, err
	}
	res.IgnoreParentExit = c.IgnoreParentExit
	res.ExitAfter = c.ExitAfter
	res.PropagateOutput = c.PropagateOutput
	res.OutputDir = c.OutputDir
	res.ExitErrorIsOk = c.ExitErrorIsOk
	res.IgnoreClosedPipeError = c.IgnoreClosedPipeError
	return res, nil
}

func (c *Cmd) stdinPipe() (io.WriteCloser, error) {
	switch {
	case c.calledStart:
		return nil, errAlreadyCalledStart
	case c.c.Stdin != nil:
		return nil, errAlreadySetStdin
	}
	// We want to provide an unlimited-size pipe to the user. If we set
	// c.c.Stdin directly to the newBufferedPipe, the os/exec package will
	// create an os.Pipe for us, along with a goroutine to copy data over. And
	// exec.Cmd.Wait will wait for this goroutine to exit before returning, even
	// if the process has already exited. That means the user will be forced to
	// call Close on the returned WriteCloser, which is annoying.
	//
	// Instead, we set c.c.Stdin to our own os.Pipe, so that os/exec won't create
	// the pipe nor the goroutine. We chain our newBufferedPipe in front of this,
	// with our own copier goroutine. This gives the user a pipe that never blocks
	// on Write, and which they don't need to Close if the process exits.
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.c.Stdin = pr
	c.afterStartClosers = append(c.afterStartClosers, pr)
	bp := newBufferedPipe()
	c.afterWaitClosers = append(c.afterWaitClosers, bp)
	c.stdinDoneChan = make(chan error, 1)
	go c.stdinPipeCopier(pw, bp) // pw is closed by stdinPipeCopier
	return bp, nil
}

func (c *Cmd) stdinPipeCopier(dst io.WriteCloser, src io.Reader) {
	var firstErr error
	if _, err := io.Copy(dst, src); err != nil && !isClosedPipeError(err) {
		firstErr = err
	}
	if err := dst.Close(); err != nil && firstErr == nil {
		firstErr = err
	}
	c.stdinDoneChan <- firstErr
}

// isClosedPipeError returns true iff the error indicates a closed pipe. This
// typically occurs with a pipeline of commands "A | B"; if B exits first, the
// next write by A will receive a closed pipe error. Also see:
// https://github.com/golang/go/issues/9173
func isClosedPipeError(err error) bool {
	if err == io.ErrClosedPipe {
		return true
	}
	// Closed pipe on os.Pipe; mirrors logic in os/exec/exec_posix.go.
	if pe, ok := err.(*os.PathError); ok && pe.Op == "write" && pe.Path == "|1" && pe.Err == syscall.EPIPE {
		return true
	}
	return false
}

func (c *Cmd) setStdinReader(r io.Reader) error {
	switch {
	case c.calledStart:
		return errAlreadyCalledStart
	case c.c.Stdin != nil:
		return errAlreadySetStdin
	}
	c.c.Stdin = r
	return nil
}

func (c *Cmd) stdoutPipe() (io.ReadCloser, error) {
	if c.calledStart {
		return nil, errAlreadyCalledStart
	}
	p := newBufferedPipe()
	c.stdoutWriters = append(c.stdoutWriters, p)
	c.afterWaitClosers = append(c.afterWaitClosers, p)
	return p, nil
}

func (c *Cmd) stderrPipe() (io.ReadCloser, error) {
	if c.calledStart {
		return nil, errAlreadyCalledStart
	}
	p := newBufferedPipe()
	c.stderrWriters = append(c.stderrWriters, p)
	c.afterWaitClosers = append(c.afterWaitClosers, p)
	return p, nil
}

func (c *Cmd) addStdoutWriter(w io.Writer) error {
	if c.calledStart {
		return errAlreadyCalledStart
	}
	c.stdoutWriters = append(c.stdoutWriters, w)
	return nil
}

func (c *Cmd) addStderrWriter(w io.Writer) error {
	if c.calledStart {
		return errAlreadyCalledStart
	}
	c.stderrWriters = append(c.stderrWriters, w)
	return nil
}

// TODO(sadovsky): Maybe wrap every child process with a "supervisor" process
// that calls InitChildMain.

func (c *Cmd) start() (e error) {
	defer func() {
		// Always close afterStartClosers upon return. Only close afterWaitClosers
		// if start failed; if start succeeds, they're closed in the startExitWaiter
		// goroutine. Only the first error is reported.
		if err := closeClosers(c.afterStartClosers); e == nil {
			e = err
		}
		if !c.started {
			if err := closeClosers(c.afterWaitClosers); e == nil {
				e = err
			}
		}
	}()
	if c.calledStart {
		return errAlreadyCalledStart
	}
	c.calledStart = true
	// Protect against Cmd.start() writing to c.c.Process concurrently with
	// signal-triggered Shell.cleanup() reading from it.
	c.sh.cleanupMu.Lock()
	defer c.sh.cleanupMu.Unlock()
	if c.sh.calledCleanup {
		return errAlreadyCalledCleanup
	}
	// Configure the command.
	c.c.Path = c.Path
	vars := copyMap(c.Vars)
	if c.IgnoreParentExit {
		delete(vars, envWatchParent)
	} else {
		vars[envWatchParent] = "1"
	}
	if c.ExitAfter == 0 {
		delete(vars, envExitAfter)
	} else {
		vars[envExitAfter] = c.ExitAfter.String()
	}
	c.c.Env = mapToSlice(vars)
	c.c.Args = c.Args
	var err error
	if c.c.Stdout, c.c.Stderr, err = c.makeStdoutStderr(); err != nil {
		return err
	}
	c.c.ExtraFiles = c.ExtraFiles
	// Start the command.
	if err = c.c.Start(); err != nil {
		return err
	}
	c.started = true
	c.startExitWaiter()
	return nil
}

// startExitWaiter spawns a goroutine that calls exec.Cmd.Wait, waiting for the
// process to exit. Calling exec.Cmd.Wait here rather than in gosh.Cmd.Wait
// ensures that the child process is reaped once it exits. Note, gosh.Cmd.wait
// blocks on waitChan.
func (c *Cmd) startExitWaiter() {
	go func() {
		waitErr := c.c.Wait()
		c.cond.L.Lock()
		c.exited = true
		c.cond.Signal()
		c.cond.L.Unlock()
		if err := closeClosers(c.afterWaitClosers); waitErr == nil {
			waitErr = err
		}
		if c.stdinDoneChan != nil {
			// Wait for the stdinPipeCopier goroutine to finish.
			if err := <-c.stdinDoneChan; waitErr == nil {
				waitErr = err
			}
		}
		c.waitChan <- waitErr
	}()
}

func closeClosers(closers []io.Closer) error {
	var firstErr error
	for _, closer := range closers {
		if err := closer.Close(); firstErr == nil {
			firstErr = err
		}
	}
	return firstErr
}

// TODO(sadovsky): Maybe add optional timeouts for Cmd.{awaitVars,wait}.

func (c *Cmd) awaitVars(keys ...string) (map[string]string, error) {
	switch {
	case !c.started:
		return nil, errDidNotCallStart
	case c.calledWait:
		return nil, errAlreadyCalledWait
	}
	wantKeys := map[string]bool{}
	for _, key := range keys {
		wantKeys[key] = true
	}
	res := map[string]string{}
	updateRes := func() {
		for k, v := range c.recvVars {
			if _, ok := wantKeys[k]; ok {
				res[k] = v
			}
		}
	}
	c.cond.L.Lock()
	defer c.cond.L.Unlock()
	updateRes()
	for !c.exited && len(res) < len(wantKeys) {
		c.cond.Wait()
		updateRes()
	}
	// Return nil error if both conditions triggered simultaneously.
	if len(res) < len(wantKeys) {
		return nil, errProcessExited
	}
	return res, nil
}

func (c *Cmd) wait() error {
	switch {
	case !c.started:
		return errDidNotCallStart
	case c.calledWait:
		return errAlreadyCalledWait
	}
	c.calledWait = true
	return <-c.waitChan
}

// Note: We check for this particular error message to handle the unavoidable
// race between sending a signal to a process and the process exiting.
// https://golang.org/src/os/exec_unix.go
// https://golang.org/src/os/exec_windows.go
const errFinished = "os: process already finished"

// NOTE(sadovsky): Technically speaking, Process.Signal(os.Kill) is different
// from Process.Kill. Currently, gosh.Cmd does not provide a way to trigger
// Process.Kill. If it proves necessary, we'll add a "gosh.Kill" implementation
// of the os.Signal interface, and have the signal and terminate methods map
// that to Process.Kill.
func (c *Cmd) signal(sig os.Signal) error {
	switch {
	case !c.started:
		return errDidNotCallStart
	case c.calledWait:
		return errAlreadyCalledWait
	}
	if !c.isRunning() {
		return nil
	}
	if err := c.c.Process.Signal(sig); err != nil && err.Error() != errFinished {
		return err
	}
	return nil
}

func (c *Cmd) terminate(sig os.Signal) error {
	if err := c.signal(sig); err != nil {
		return err
	}
	if err := c.wait(); err != nil {
		// Succeed as long as the process exited, regardless of the exit code.
		if _, ok := err.(*exec.ExitError); !ok {
			return err
		}
	}
	return nil
}

func (c *Cmd) run() error {
	if err := c.start(); err != nil {
		return err
	}
	return c.wait()
}

func (c *Cmd) stdout() (string, error) {
	if c.calledStart {
		return "", errAlreadyCalledStart
	}
	var stdout bytes.Buffer
	c.stdoutWriters = append(c.stdoutWriters, &stdout)
	err := c.run()
	return stdout.String(), err
}

func (c *Cmd) stdoutStderr() (string, string, error) {
	if c.calledStart {
		return "", "", errAlreadyCalledStart
	}
	var stdout, stderr bytes.Buffer
	c.stdoutWriters = append(c.stdoutWriters, &stdout)
	c.stderrWriters = append(c.stderrWriters, &stderr)
	err := c.run()
	return stdout.String(), stderr.String(), err
}

func (c *Cmd) combinedOutput() (string, error) {
	if c.calledStart {
		return "", errAlreadyCalledStart
	}
	var output bytes.Buffer
	c.stdoutWriters = append(c.stdoutWriters, &output)
	c.stderrWriters = append(c.stderrWriters, &output)
	err := c.run()
	return output.String(), err
}
