Source file src/os/exec/exec.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package exec runs external commands. It wraps os.StartProcess to make it
     6  // easier to remap stdin and stdout, connect I/O with pipes, and do other
     7  // adjustments.
     8  //
     9  // Unlike the "system" library call from C and other languages, the
    10  // os/exec package intentionally does not invoke the system shell and
    11  // does not expand any glob patterns or handle other expansions,
    12  // pipelines, or redirections typically done by shells. The package
    13  // behaves more like C's "exec" family of functions. To expand glob
    14  // patterns, either call the shell directly, taking care to escape any
    15  // dangerous input, or use the path/filepath package's Glob function.
    16  // To expand environment variables, use package os's ExpandEnv.
    17  //
    18  // Note that the examples in this package assume a Unix system.
    19  // They may not run on Windows, and they do not run in the Go Playground
    20  // used by golang.org and godoc.org.
    21  //
    22  // # Executables in the current directory
    23  //
    24  // The functions Command and LookPath look for a program
    25  // in the directories listed in the current path, following the
    26  // conventions of the host operating system.
    27  // Operating systems have for decades included the current
    28  // directory in this search, sometimes implicitly and sometimes
    29  // configured explicitly that way by default.
    30  // Modern practice is that including the current directory
    31  // is usually unexpected and often leads to security problems.
    32  //
    33  // To avoid those security problems, as of Go 1.19, this package will not resolve a program
    34  // using an implicit or explicit path entry relative to the current directory.
    35  // That is, if you run exec.LookPath("go"), it will not successfully return
    36  // ./go on Unix nor .\go.exe on Windows, no matter how the path is configured.
    37  // Instead, if the usual path algorithms would result in that answer,
    38  // these functions return an error err satisfying errors.Is(err, ErrDot).
    39  //
    40  // For example, consider these two program snippets:
    41  //
    42  //	path, err := exec.LookPath("prog")
    43  //	if err != nil {
    44  //		log.Fatal(err)
    45  //	}
    46  //	use(path)
    47  //
    48  // and
    49  //
    50  //	cmd := exec.Command("prog")
    51  //	if err := cmd.Run(); err != nil {
    52  //		log.Fatal(err)
    53  //	}
    54  //
    55  // These will not find and run ./prog or .\prog.exe,
    56  // no matter how the current path is configured.
    57  //
    58  // Code that always wants to run a program from the current directory
    59  // can be rewritten to say "./prog" instead of "prog".
    60  //
    61  // Code that insists on including results from relative path entries
    62  // can instead override the error using an errors.Is check:
    63  //
    64  //	path, err := exec.LookPath("prog")
    65  //	if errors.Is(err, exec.ErrDot) {
    66  //		err = nil
    67  //	}
    68  //	if err != nil {
    69  //		log.Fatal(err)
    70  //	}
    71  //	use(path)
    72  //
    73  // and
    74  //
    75  //	cmd := exec.Command("prog")
    76  //	if errors.Is(cmd.Err, exec.ErrDot) {
    77  //		cmd.Err = nil
    78  //	}
    79  //	if err := cmd.Run(); err != nil {
    80  //		log.Fatal(err)
    81  //	}
    82  //
    83  // Setting the environment variable GODEBUG=execerrdot=0
    84  // disables generation of ErrDot entirely, temporarily restoring the pre-Go 1.19
    85  // behavior for programs that are unable to apply more targeted fixes.
    86  // A future version of Go may remove support for this variable.
    87  //
    88  // Before adding such overrides, make sure you understand the
    89  // security implications of doing so.
    90  // See https://go.dev/blog/path-security for more information.
    91  package exec
    92  
    93  import (
    94  	"bytes"
    95  	"context"
    96  	"errors"
    97  	"internal/syscall/execenv"
    98  	"io"
    99  	"os"
   100  	"path/filepath"
   101  	"runtime"
   102  	"strconv"
   103  	"strings"
   104  	"sync"
   105  	"syscall"
   106  )
   107  
   108  // Error is returned by LookPath when it fails to classify a file as an
   109  // executable.
   110  type Error struct {
   111  	// Name is the file name for which the error occurred.
   112  	Name string
   113  	// Err is the underlying error.
   114  	Err error
   115  }
   116  
   117  func (e *Error) Error() string {
   118  	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
   119  }
   120  
   121  func (e *Error) Unwrap() error { return e.Err }
   122  
   123  // wrappedError wraps an error without relying on fmt.Errorf.
   124  type wrappedError struct {
   125  	prefix string
   126  	err    error
   127  }
   128  
   129  func (w wrappedError) Error() string {
   130  	return w.prefix + ": " + w.err.Error()
   131  }
   132  
   133  func (w wrappedError) Unwrap() error {
   134  	return w.err
   135  }
   136  
   137  // Cmd represents an external command being prepared or run.
   138  //
   139  // A Cmd cannot be reused after calling its Run, Output or CombinedOutput
   140  // methods.
   141  type Cmd struct {
   142  	// Path is the path of the command to run.
   143  	//
   144  	// This is the only field that must be set to a non-zero
   145  	// value. If Path is relative, it is evaluated relative
   146  	// to Dir.
   147  	Path string
   148  
   149  	// Args holds command line arguments, including the command as Args[0].
   150  	// If the Args field is empty or nil, Run uses {Path}.
   151  	//
   152  	// In typical use, both Path and Args are set by calling Command.
   153  	Args []string
   154  
   155  	// Env specifies the environment of the process.
   156  	// Each entry is of the form "key=value".
   157  	// If Env is nil, the new process uses the current process's
   158  	// environment.
   159  	// If Env contains duplicate environment keys, only the last
   160  	// value in the slice for each duplicate key is used.
   161  	// As a special case on Windows, SYSTEMROOT is always added if
   162  	// missing and not explicitly set to the empty string.
   163  	Env []string
   164  
   165  	// Dir specifies the working directory of the command.
   166  	// If Dir is the empty string, Run runs the command in the
   167  	// calling process's current directory.
   168  	Dir string
   169  
   170  	// Stdin specifies the process's standard input.
   171  	//
   172  	// If Stdin is nil, the process reads from the null device (os.DevNull).
   173  	//
   174  	// If Stdin is an *os.File, the process's standard input is connected
   175  	// directly to that file.
   176  	//
   177  	// Otherwise, during the execution of the command a separate
   178  	// goroutine reads from Stdin and delivers that data to the command
   179  	// over a pipe. In this case, Wait does not complete until the goroutine
   180  	// stops copying, either because it has reached the end of Stdin
   181  	// (EOF or a read error) or because writing to the pipe returned an error.
   182  	Stdin io.Reader
   183  
   184  	// Stdout and Stderr specify the process's standard output and error.
   185  	//
   186  	// If either is nil, Run connects the corresponding file descriptor
   187  	// to the null device (os.DevNull).
   188  	//
   189  	// If either is an *os.File, the corresponding output from the process
   190  	// is connected directly to that file.
   191  	//
   192  	// Otherwise, during the execution of the command a separate goroutine
   193  	// reads from the process over a pipe and delivers that data to the
   194  	// corresponding Writer. In this case, Wait does not complete until the
   195  	// goroutine reaches EOF or encounters an error.
   196  	//
   197  	// If Stdout and Stderr are the same writer, and have a type that can
   198  	// be compared with ==, at most one goroutine at a time will call Write.
   199  	Stdout io.Writer
   200  	Stderr io.Writer
   201  
   202  	// ExtraFiles specifies additional open files to be inherited by the
   203  	// new process. It does not include standard input, standard output, or
   204  	// standard error. If non-nil, entry i becomes file descriptor 3+i.
   205  	//
   206  	// ExtraFiles is not supported on Windows.
   207  	ExtraFiles []*os.File
   208  
   209  	// SysProcAttr holds optional, operating system-specific attributes.
   210  	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
   211  	SysProcAttr *syscall.SysProcAttr
   212  
   213  	// Process is the underlying process, once started.
   214  	Process *os.Process
   215  
   216  	// ProcessState contains information about an exited process,
   217  	// available after a call to Wait or Run.
   218  	ProcessState *os.ProcessState
   219  
   220  	ctx             context.Context // nil means none
   221  	Err             error           // LookPath error, if any.
   222  	childFiles      []*os.File
   223  	closeAfterStart []io.Closer
   224  	closeAfterWait  []io.Closer
   225  	goroutine       []func() error
   226  	goroutineErrs   <-chan error // one receive per goroutine
   227  	ctxErr          <-chan error // if non nil, receives the error from watchCtx exactly once
   228  
   229  	// For a security release long ago, we created x/sys/execabs,
   230  	// which manipulated the unexported lookPathErr error field
   231  	// in this struct. For Go 1.19 we exported the field as Err error,
   232  	// above, but we have to keep lookPathErr around for use by
   233  	// old programs building against new toolchains.
   234  	// The String and Start methods look for an error in lookPathErr
   235  	// in preference to Err, to preserve the errors that execabs sets.
   236  	//
   237  	// In general we don't guarantee misuse of reflect like this,
   238  	// but the misuse of reflect was by us, the best of various bad
   239  	// options to fix the security problem, and people depend on
   240  	// those old copies of execabs continuing to work.
   241  	// The result is that we have to leave this variable around for the
   242  	// rest of time, a compatibility scar.
   243  	//
   244  	// See https://go.dev/blog/path-security
   245  	// and https://go.dev/issue/43724 for more context.
   246  	lookPathErr error
   247  }
   248  
   249  // Command returns the Cmd struct to execute the named program with
   250  // the given arguments.
   251  //
   252  // It sets only the Path and Args in the returned structure.
   253  //
   254  // If name contains no path separators, Command uses LookPath to
   255  // resolve name to a complete path if possible. Otherwise it uses name
   256  // directly as Path.
   257  //
   258  // The returned Cmd's Args field is constructed from the command name
   259  // followed by the elements of arg, so arg should not include the
   260  // command name itself. For example, Command("echo", "hello").
   261  // Args[0] is always name, not the possibly resolved Path.
   262  //
   263  // On Windows, processes receive the whole command line as a single string
   264  // and do their own parsing. Command combines and quotes Args into a command
   265  // line string with an algorithm compatible with applications using
   266  // CommandLineToArgvW (which is the most common way). Notable exceptions are
   267  // msiexec.exe and cmd.exe (and thus, all batch files), which have a different
   268  // unquoting algorithm. In these or other similar cases, you can do the
   269  // quoting yourself and provide the full command line in SysProcAttr.CmdLine,
   270  // leaving Args empty.
   271  func Command(name string, arg ...string) *Cmd {
   272  	cmd := &Cmd{
   273  		Path: name,
   274  		Args: append([]string{name}, arg...),
   275  	}
   276  	if filepath.Base(name) == name {
   277  		lp, err := LookPath(name)
   278  		if lp != "" {
   279  			// Update cmd.Path even if err is non-nil.
   280  			// If err is ErrDot (especially on Windows), lp may include a resolved
   281  			// extension (like .exe or .bat) that should be preserved.
   282  			cmd.Path = lp
   283  		}
   284  		if err != nil {
   285  			cmd.Err = err
   286  		}
   287  	}
   288  	return cmd
   289  }
   290  
   291  // CommandContext is like Command but includes a context.
   292  //
   293  // The provided context is used to kill the process (by calling
   294  // os.Process.Kill) if the context becomes done before the command
   295  // completes on its own.
   296  func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
   297  	if ctx == nil {
   298  		panic("nil Context")
   299  	}
   300  	cmd := Command(name, arg...)
   301  	cmd.ctx = ctx
   302  	return cmd
   303  }
   304  
   305  // String returns a human-readable description of c.
   306  // It is intended only for debugging.
   307  // In particular, it is not suitable for use as input to a shell.
   308  // The output of String may vary across Go releases.
   309  func (c *Cmd) String() string {
   310  	if c.Err != nil || c.lookPathErr != nil {
   311  		// failed to resolve path; report the original requested path (plus args)
   312  		return strings.Join(c.Args, " ")
   313  	}
   314  	// report the exact executable path (plus args)
   315  	b := new(strings.Builder)
   316  	b.WriteString(c.Path)
   317  	for _, a := range c.Args[1:] {
   318  		b.WriteByte(' ')
   319  		b.WriteString(a)
   320  	}
   321  	return b.String()
   322  }
   323  
   324  // interfaceEqual protects against panics from doing equality tests on
   325  // two interfaces with non-comparable underlying types.
   326  func interfaceEqual(a, b any) bool {
   327  	defer func() {
   328  		recover()
   329  	}()
   330  	return a == b
   331  }
   332  
   333  func (c *Cmd) argv() []string {
   334  	if len(c.Args) > 0 {
   335  		return c.Args
   336  	}
   337  	return []string{c.Path}
   338  }
   339  
   340  func (c *Cmd) stdin() (f *os.File, err error) {
   341  	if c.Stdin == nil {
   342  		f, err = os.Open(os.DevNull)
   343  		if err != nil {
   344  			return
   345  		}
   346  		c.closeAfterStart = append(c.closeAfterStart, f)
   347  		return
   348  	}
   349  
   350  	if f, ok := c.Stdin.(*os.File); ok {
   351  		return f, nil
   352  	}
   353  
   354  	pr, pw, err := os.Pipe()
   355  	if err != nil {
   356  		return
   357  	}
   358  
   359  	c.closeAfterStart = append(c.closeAfterStart, pr)
   360  	c.closeAfterWait = append(c.closeAfterWait, pw)
   361  	c.goroutine = append(c.goroutine, func() error {
   362  		_, err := io.Copy(pw, c.Stdin)
   363  		if skipStdinCopyError(err) {
   364  			err = nil
   365  		}
   366  		if err1 := pw.Close(); err == nil {
   367  			err = err1
   368  		}
   369  		return err
   370  	})
   371  	return pr, nil
   372  }
   373  
   374  func (c *Cmd) stdout() (f *os.File, err error) {
   375  	return c.writerDescriptor(c.Stdout)
   376  }
   377  
   378  func (c *Cmd) stderr() (f *os.File, err error) {
   379  	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
   380  		return c.childFiles[1], nil
   381  	}
   382  	return c.writerDescriptor(c.Stderr)
   383  }
   384  
   385  func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
   386  	if w == nil {
   387  		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
   388  		if err != nil {
   389  			return
   390  		}
   391  		c.closeAfterStart = append(c.closeAfterStart, f)
   392  		return
   393  	}
   394  
   395  	if f, ok := w.(*os.File); ok {
   396  		return f, nil
   397  	}
   398  
   399  	pr, pw, err := os.Pipe()
   400  	if err != nil {
   401  		return
   402  	}
   403  
   404  	c.closeAfterStart = append(c.closeAfterStart, pw)
   405  	c.closeAfterWait = append(c.closeAfterWait, pr)
   406  	c.goroutine = append(c.goroutine, func() error {
   407  		_, err := io.Copy(w, pr)
   408  		pr.Close() // in case io.Copy stopped due to write error
   409  		return err
   410  	})
   411  	return pw, nil
   412  }
   413  
   414  func (c *Cmd) closeDescriptors(closers []io.Closer) {
   415  	for _, fd := range closers {
   416  		fd.Close()
   417  	}
   418  }
   419  
   420  // Run starts the specified command and waits for it to complete.
   421  //
   422  // The returned error is nil if the command runs, has no problems
   423  // copying stdin, stdout, and stderr, and exits with a zero exit
   424  // status.
   425  //
   426  // If the command starts but does not complete successfully, the error is of
   427  // type *ExitError. Other error types may be returned for other situations.
   428  //
   429  // If the calling goroutine has locked the operating system thread
   430  // with runtime.LockOSThread and modified any inheritable OS-level
   431  // thread state (for example, Linux or Plan 9 name spaces), the new
   432  // process will inherit the caller's thread state.
   433  func (c *Cmd) Run() error {
   434  	if err := c.Start(); err != nil {
   435  		return err
   436  	}
   437  	return c.Wait()
   438  }
   439  
   440  // lookExtensions finds windows executable by its dir and path.
   441  // It uses LookPath to try appropriate extensions.
   442  // lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
   443  func lookExtensions(path, dir string) (string, error) {
   444  	if filepath.Base(path) == path {
   445  		path = "." + string(filepath.Separator) + path
   446  	}
   447  	if dir == "" {
   448  		return LookPath(path)
   449  	}
   450  	if filepath.VolumeName(path) != "" {
   451  		return LookPath(path)
   452  	}
   453  	if len(path) > 1 && os.IsPathSeparator(path[0]) {
   454  		return LookPath(path)
   455  	}
   456  	dirandpath := filepath.Join(dir, path)
   457  	// We assume that LookPath will only add file extension.
   458  	lp, err := LookPath(dirandpath)
   459  	if err != nil {
   460  		return "", err
   461  	}
   462  	ext := strings.TrimPrefix(lp, dirandpath)
   463  	return path + ext, nil
   464  }
   465  
   466  // Start starts the specified command but does not wait for it to complete.
   467  //
   468  // If Start returns successfully, the c.Process field will be set.
   469  //
   470  // After a successful call to Start the Wait method must be called in
   471  // order to release associated system resources.
   472  func (c *Cmd) Start() error {
   473  	if c.Path == "" && c.Err == nil && c.lookPathErr == nil {
   474  		c.Err = errors.New("exec: no command")
   475  	}
   476  	if c.Err != nil || c.lookPathErr != nil {
   477  		c.closeDescriptors(c.closeAfterStart)
   478  		c.closeDescriptors(c.closeAfterWait)
   479  		if c.lookPathErr != nil {
   480  			return c.lookPathErr
   481  		}
   482  		return c.Err
   483  	}
   484  	if runtime.GOOS == "windows" {
   485  		lp, err := lookExtensions(c.Path, c.Dir)
   486  		if err != nil {
   487  			c.closeDescriptors(c.closeAfterStart)
   488  			c.closeDescriptors(c.closeAfterWait)
   489  			return err
   490  		}
   491  		c.Path = lp
   492  	}
   493  	if c.Process != nil {
   494  		return errors.New("exec: already started")
   495  	}
   496  	if c.ctx != nil {
   497  		select {
   498  		case <-c.ctx.Done():
   499  			c.closeDescriptors(c.closeAfterStart)
   500  			c.closeDescriptors(c.closeAfterWait)
   501  			return c.ctx.Err()
   502  		default:
   503  		}
   504  	}
   505  
   506  	c.childFiles = make([]*os.File, 0, 3+len(c.ExtraFiles))
   507  	type F func(*Cmd) (*os.File, error)
   508  	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
   509  		fd, err := setupFd(c)
   510  		if err != nil {
   511  			c.closeDescriptors(c.closeAfterStart)
   512  			c.closeDescriptors(c.closeAfterWait)
   513  			return err
   514  		}
   515  		c.childFiles = append(c.childFiles, fd)
   516  	}
   517  	c.childFiles = append(c.childFiles, c.ExtraFiles...)
   518  
   519  	env, err := c.environ()
   520  	if err != nil {
   521  		return err
   522  	}
   523  
   524  	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
   525  		Dir:   c.Dir,
   526  		Files: c.childFiles,
   527  		Env:   env,
   528  		Sys:   c.SysProcAttr,
   529  	})
   530  	if err != nil {
   531  		c.closeDescriptors(c.closeAfterStart)
   532  		c.closeDescriptors(c.closeAfterWait)
   533  		return err
   534  	}
   535  
   536  	c.closeDescriptors(c.closeAfterStart)
   537  
   538  	// Don't allocate the goroutineErrs channel unless there are goroutines to fire.
   539  	if len(c.goroutine) > 0 {
   540  		errc := make(chan error, len(c.goroutine))
   541  		c.goroutineErrs = errc
   542  		for _, fn := range c.goroutine {
   543  			go func(fn func() error) {
   544  				errc <- fn()
   545  			}(fn)
   546  		}
   547  	}
   548  
   549  	c.ctxErr = c.watchCtx()
   550  
   551  	return nil
   552  }
   553  
   554  // An ExitError reports an unsuccessful exit by a command.
   555  type ExitError struct {
   556  	*os.ProcessState
   557  
   558  	// Stderr holds a subset of the standard error output from the
   559  	// Cmd.Output method if standard error was not otherwise being
   560  	// collected.
   561  	//
   562  	// If the error output is long, Stderr may contain only a prefix
   563  	// and suffix of the output, with the middle replaced with
   564  	// text about the number of omitted bytes.
   565  	//
   566  	// Stderr is provided for debugging, for inclusion in error messages.
   567  	// Users with other needs should redirect Cmd.Stderr as needed.
   568  	Stderr []byte
   569  }
   570  
   571  func (e *ExitError) Error() string {
   572  	return e.ProcessState.String()
   573  }
   574  
   575  // Wait waits for the command to exit and waits for any copying to
   576  // stdin or copying from stdout or stderr to complete.
   577  //
   578  // The command must have been started by Start.
   579  //
   580  // The returned error is nil if the command runs, has no problems
   581  // copying stdin, stdout, and stderr, and exits with a zero exit
   582  // status.
   583  //
   584  // If the command fails to run or doesn't complete successfully, the
   585  // error is of type *ExitError. Other error types may be
   586  // returned for I/O problems.
   587  //
   588  // If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits
   589  // for the respective I/O loop copying to or from the process to complete.
   590  //
   591  // Wait releases any resources associated with the Cmd.
   592  func (c *Cmd) Wait() error {
   593  	if c.Process == nil {
   594  		return errors.New("exec: not started")
   595  	}
   596  	if c.ProcessState != nil {
   597  		return errors.New("exec: Wait was already called")
   598  	}
   599  	state, err := c.Process.Wait()
   600  	if err == nil && !state.Success() {
   601  		err = &ExitError{ProcessState: state}
   602  	}
   603  	c.ProcessState = state
   604  
   605  	// Wait for the pipe-copying goroutines to complete.
   606  	var copyError error
   607  	for range c.goroutine {
   608  		if err := <-c.goroutineErrs; err != nil && copyError == nil {
   609  			copyError = err
   610  		}
   611  	}
   612  	c.goroutine = nil // Allow the goroutines' closures to be GC'd.
   613  
   614  	if c.ctxErr != nil {
   615  		interruptErr := <-c.ctxErr
   616  		// If c.Process.Wait returned an error, prefer that.
   617  		// Otherwise, report any error from the interrupt goroutine.
   618  		if interruptErr != nil && err == nil {
   619  			err = interruptErr
   620  		}
   621  	}
   622  	// Report errors from the copying goroutines only if the program otherwise
   623  	// exited normally on its own. Otherwise, the copying error may be due to the
   624  	// abnormal termination.
   625  	if err == nil {
   626  		err = copyError
   627  	}
   628  
   629  	c.closeDescriptors(c.closeAfterWait)
   630  	c.closeAfterWait = nil
   631  
   632  	return err
   633  }
   634  
   635  // watchCtx conditionally starts a goroutine that waits until either c.ctx is
   636  // done or c.Process.Wait has completed (called from Wait).
   637  // If c.ctx is done first, the goroutine terminates c.Process.
   638  //
   639  // If a goroutine was started, watchCtx returns a channel on which its result
   640  // must be received.
   641  func (c *Cmd) watchCtx() <-chan error {
   642  	if c.ctx == nil {
   643  		return nil
   644  	}
   645  
   646  	errc := make(chan error)
   647  	go func() {
   648  		select {
   649  		case errc <- nil:
   650  			return
   651  		case <-c.ctx.Done():
   652  		}
   653  
   654  		var err error
   655  		if killErr := c.Process.Kill(); killErr == nil {
   656  			// We appear to have successfully delivered a kill signal, so any
   657  			// program behavior from this point may be due to ctx.
   658  			err = c.ctx.Err()
   659  		} else if !errors.Is(killErr, os.ErrProcessDone) {
   660  			err = wrappedError{
   661  				prefix: "exec: error sending signal to Cmd",
   662  				err:    killErr,
   663  			}
   664  		}
   665  		errc <- err
   666  	}()
   667  
   668  	return errc
   669  }
   670  
   671  // Output runs the command and returns its standard output.
   672  // Any returned error will usually be of type *ExitError.
   673  // If c.Stderr was nil, Output populates ExitError.Stderr.
   674  func (c *Cmd) Output() ([]byte, error) {
   675  	if c.Stdout != nil {
   676  		return nil, errors.New("exec: Stdout already set")
   677  	}
   678  	var stdout bytes.Buffer
   679  	c.Stdout = &stdout
   680  
   681  	captureErr := c.Stderr == nil
   682  	if captureErr {
   683  		c.Stderr = &prefixSuffixSaver{N: 32 << 10}
   684  	}
   685  
   686  	err := c.Run()
   687  	if err != nil && captureErr {
   688  		if ee, ok := err.(*ExitError); ok {
   689  			ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
   690  		}
   691  	}
   692  	return stdout.Bytes(), err
   693  }
   694  
   695  // CombinedOutput runs the command and returns its combined standard
   696  // output and standard error.
   697  func (c *Cmd) CombinedOutput() ([]byte, error) {
   698  	if c.Stdout != nil {
   699  		return nil, errors.New("exec: Stdout already set")
   700  	}
   701  	if c.Stderr != nil {
   702  		return nil, errors.New("exec: Stderr already set")
   703  	}
   704  	var b bytes.Buffer
   705  	c.Stdout = &b
   706  	c.Stderr = &b
   707  	err := c.Run()
   708  	return b.Bytes(), err
   709  }
   710  
   711  // StdinPipe returns a pipe that will be connected to the command's
   712  // standard input when the command starts.
   713  // The pipe will be closed automatically after Wait sees the command exit.
   714  // A caller need only call Close to force the pipe to close sooner.
   715  // For example, if the command being run will not exit until standard input
   716  // is closed, the caller must close the pipe.
   717  func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
   718  	if c.Stdin != nil {
   719  		return nil, errors.New("exec: Stdin already set")
   720  	}
   721  	if c.Process != nil {
   722  		return nil, errors.New("exec: StdinPipe after process started")
   723  	}
   724  	pr, pw, err := os.Pipe()
   725  	if err != nil {
   726  		return nil, err
   727  	}
   728  	c.Stdin = pr
   729  	c.closeAfterStart = append(c.closeAfterStart, pr)
   730  	wc := &closeOnce{File: pw}
   731  	c.closeAfterWait = append(c.closeAfterWait, wc)
   732  	return wc, nil
   733  }
   734  
   735  type closeOnce struct {
   736  	*os.File
   737  
   738  	once sync.Once
   739  	err  error
   740  }
   741  
   742  func (c *closeOnce) Close() error {
   743  	c.once.Do(c.close)
   744  	return c.err
   745  }
   746  
   747  func (c *closeOnce) close() {
   748  	c.err = c.File.Close()
   749  }
   750  
   751  // StdoutPipe returns a pipe that will be connected to the command's
   752  // standard output when the command starts.
   753  //
   754  // Wait will close the pipe after seeing the command exit, so most callers
   755  // need not close the pipe themselves. It is thus incorrect to call Wait
   756  // before all reads from the pipe have completed.
   757  // For the same reason, it is incorrect to call Run when using StdoutPipe.
   758  // See the example for idiomatic usage.
   759  func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
   760  	if c.Stdout != nil {
   761  		return nil, errors.New("exec: Stdout already set")
   762  	}
   763  	if c.Process != nil {
   764  		return nil, errors.New("exec: StdoutPipe after process started")
   765  	}
   766  	pr, pw, err := os.Pipe()
   767  	if err != nil {
   768  		return nil, err
   769  	}
   770  	c.Stdout = pw
   771  	c.closeAfterStart = append(c.closeAfterStart, pw)
   772  	c.closeAfterWait = append(c.closeAfterWait, pr)
   773  	return pr, nil
   774  }
   775  
   776  // StderrPipe returns a pipe that will be connected to the command's
   777  // standard error when the command starts.
   778  //
   779  // Wait will close the pipe after seeing the command exit, so most callers
   780  // need not close the pipe themselves. It is thus incorrect to call Wait
   781  // before all reads from the pipe have completed.
   782  // For the same reason, it is incorrect to use Run when using StderrPipe.
   783  // See the StdoutPipe example for idiomatic usage.
   784  func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
   785  	if c.Stderr != nil {
   786  		return nil, errors.New("exec: Stderr already set")
   787  	}
   788  	if c.Process != nil {
   789  		return nil, errors.New("exec: StderrPipe after process started")
   790  	}
   791  	pr, pw, err := os.Pipe()
   792  	if err != nil {
   793  		return nil, err
   794  	}
   795  	c.Stderr = pw
   796  	c.closeAfterStart = append(c.closeAfterStart, pw)
   797  	c.closeAfterWait = append(c.closeAfterWait, pr)
   798  	return pr, nil
   799  }
   800  
   801  // prefixSuffixSaver is an io.Writer which retains the first N bytes
   802  // and the last N bytes written to it. The Bytes() methods reconstructs
   803  // it with a pretty error message.
   804  type prefixSuffixSaver struct {
   805  	N         int // max size of prefix or suffix
   806  	prefix    []byte
   807  	suffix    []byte // ring buffer once len(suffix) == N
   808  	suffixOff int    // offset to write into suffix
   809  	skipped   int64
   810  
   811  	// TODO(bradfitz): we could keep one large []byte and use part of it for
   812  	// the prefix, reserve space for the '... Omitting N bytes ...' message,
   813  	// then the ring buffer suffix, and just rearrange the ring buffer
   814  	// suffix when Bytes() is called, but it doesn't seem worth it for
   815  	// now just for error messages. It's only ~64KB anyway.
   816  }
   817  
   818  func (w *prefixSuffixSaver) Write(p []byte) (n int, err error) {
   819  	lenp := len(p)
   820  	p = w.fill(&w.prefix, p)
   821  
   822  	// Only keep the last w.N bytes of suffix data.
   823  	if overage := len(p) - w.N; overage > 0 {
   824  		p = p[overage:]
   825  		w.skipped += int64(overage)
   826  	}
   827  	p = w.fill(&w.suffix, p)
   828  
   829  	// w.suffix is full now if p is non-empty. Overwrite it in a circle.
   830  	for len(p) > 0 { // 0, 1, or 2 iterations.
   831  		n := copy(w.suffix[w.suffixOff:], p)
   832  		p = p[n:]
   833  		w.skipped += int64(n)
   834  		w.suffixOff += n
   835  		if w.suffixOff == w.N {
   836  			w.suffixOff = 0
   837  		}
   838  	}
   839  	return lenp, nil
   840  }
   841  
   842  // fill appends up to len(p) bytes of p to *dst, such that *dst does not
   843  // grow larger than w.N. It returns the un-appended suffix of p.
   844  func (w *prefixSuffixSaver) fill(dst *[]byte, p []byte) (pRemain []byte) {
   845  	if remain := w.N - len(*dst); remain > 0 {
   846  		add := minInt(len(p), remain)
   847  		*dst = append(*dst, p[:add]...)
   848  		p = p[add:]
   849  	}
   850  	return p
   851  }
   852  
   853  func (w *prefixSuffixSaver) Bytes() []byte {
   854  	if w.suffix == nil {
   855  		return w.prefix
   856  	}
   857  	if w.skipped == 0 {
   858  		return append(w.prefix, w.suffix...)
   859  	}
   860  	var buf bytes.Buffer
   861  	buf.Grow(len(w.prefix) + len(w.suffix) + 50)
   862  	buf.Write(w.prefix)
   863  	buf.WriteString("\n... omitting ")
   864  	buf.WriteString(strconv.FormatInt(w.skipped, 10))
   865  	buf.WriteString(" bytes ...\n")
   866  	buf.Write(w.suffix[w.suffixOff:])
   867  	buf.Write(w.suffix[:w.suffixOff])
   868  	return buf.Bytes()
   869  }
   870  
   871  func minInt(a, b int) int {
   872  	if a < b {
   873  		return a
   874  	}
   875  	return b
   876  }
   877  
   878  // environ returns a best-effort copy of the environment in which the command
   879  // would be run as it is currently configured. If an error occurs in computing
   880  // the environment, it is returned alongside the best-effort copy.
   881  func (c *Cmd) environ() ([]string, error) {
   882  	var err error
   883  
   884  	env := c.Env
   885  	if env == nil {
   886  		env, err = execenv.Default(c.SysProcAttr)
   887  		if err != nil {
   888  			env = os.Environ()
   889  			// Note that the non-nil err is preserved despite env being overridden.
   890  		}
   891  
   892  		if c.Dir != "" {
   893  			switch runtime.GOOS {
   894  			case "windows", "plan9":
   895  				// Windows and Plan 9 do not use the PWD variable, so we don't need to
   896  				// keep it accurate.
   897  			default:
   898  				// On POSIX platforms, PWD represents β€œan absolute pathname of the
   899  				// current working directory.” Since we are changing the working
   900  				// directory for the command, we should also update PWD to reflect that.
   901  				//
   902  				// Unfortunately, we didn't always do that, so (as proposed in
   903  				// https://go.dev/issue/50599) to avoid unintended collateral damage we
   904  				// only implicitly update PWD when Env is nil. That way, we're much
   905  				// less likely to override an intentional change to the variable.
   906  				if pwd, absErr := filepath.Abs(c.Dir); absErr == nil {
   907  					env = append(env, "PWD="+pwd)
   908  				} else if err == nil {
   909  					err = absErr
   910  				}
   911  			}
   912  		}
   913  	}
   914  
   915  	env, dedupErr := dedupEnv(env)
   916  	if err == nil {
   917  		err = dedupErr
   918  	}
   919  	return addCriticalEnv(env), err
   920  }
   921  
   922  // Environ returns a copy of the environment in which the command would be run
   923  // as it is currently configured.
   924  func (c *Cmd) Environ() []string {
   925  	//  Intentionally ignore errors: environ returns a best-effort environment no matter what.
   926  	env, _ := c.environ()
   927  	return env
   928  }
   929  
   930  // dedupEnv returns a copy of env with any duplicates removed, in favor of
   931  // later values.
   932  // Items not of the normal environment "key=value" form are preserved unchanged.
   933  // Except on Plan 9, items containing NUL characters are removed, and
   934  // an error is returned along with the remaining values.
   935  func dedupEnv(env []string) ([]string, error) {
   936  	return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
   937  }
   938  
   939  // dedupEnvCase is dedupEnv with a case option for testing.
   940  // If caseInsensitive is true, the case of keys is ignored.
   941  // If nulOK is false, items containing NUL characters are allowed.
   942  func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
   943  	// Construct the output in reverse order, to preserve the
   944  	// last occurrence of each key.
   945  	var err error
   946  	out := make([]string, 0, len(env))
   947  	saw := make(map[string]bool, len(env))
   948  	for n := len(env); n > 0; n-- {
   949  		kv := env[n-1]
   950  
   951  		// Reject NUL in environment variables to prevent security issues (#56284);
   952  		// except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
   953  		if !nulOK && strings.IndexByte(kv, 0) != -1 {
   954  			err = errors.New("exec: environment variable contains NUL")
   955  			continue
   956  		}
   957  
   958  		i := strings.Index(kv, "=")
   959  		if i == 0 {
   960  			// We observe in practice keys with a single leading "=" on Windows.
   961  			// TODO(#49886): Should we consume only the first leading "=" as part
   962  			// of the key, or parse through arbitrarily many of them until a non-"="?
   963  			i = strings.Index(kv[1:], "=") + 1
   964  		}
   965  		if i < 0 {
   966  			if kv != "" {
   967  				// The entry is not of the form "key=value" (as it is required to be).
   968  				// Leave it as-is for now.
   969  				// TODO(#52436): should we strip or reject these bogus entries?
   970  				out = append(out, kv)
   971  			}
   972  			continue
   973  		}
   974  		k := kv[:i]
   975  		if caseInsensitive {
   976  			k = strings.ToLower(k)
   977  		}
   978  		if saw[k] {
   979  			continue
   980  		}
   981  
   982  		saw[k] = true
   983  		out = append(out, kv)
   984  	}
   985  
   986  	// Now reverse the slice to restore the original order.
   987  	for i := 0; i < len(out)/2; i++ {
   988  		j := len(out) - i - 1
   989  		out[i], out[j] = out[j], out[i]
   990  	}
   991  
   992  	return out, err
   993  }
   994  
   995  // addCriticalEnv adds any critical environment variables that are required
   996  // (or at least almost always required) on the operating system.
   997  // Currently this is only used for Windows.
   998  func addCriticalEnv(env []string) []string {
   999  	if runtime.GOOS != "windows" {
  1000  		return env
  1001  	}
  1002  	for _, kv := range env {
  1003  		k, _, ok := strings.Cut(kv, "=")
  1004  		if !ok {
  1005  			continue
  1006  		}
  1007  		if strings.EqualFold(k, "SYSTEMROOT") {
  1008  			// We already have it.
  1009  			return env
  1010  		}
  1011  	}
  1012  	return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
  1013  }
  1014  
  1015  // ErrDot indicates that a path lookup resolved to an executable
  1016  // in the current directory due to β€˜.’ being in the path, either
  1017  // implicitly or explicitly. See the package documentation for details.
  1018  //
  1019  // Note that functions in this package do not return ErrDot directly.
  1020  // Code should use errors.Is(err, ErrDot), not err == ErrDot,
  1021  // to test whether a returned error err is due to this condition.
  1022  var ErrDot = errors.New("cannot run executable found relative to current directory")
  1023  

View as plain text