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 go.dev and pkg.go.dev.
    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 [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/godebug"
    98  	"internal/syscall/execenv"
    99  	"io"
   100  	"os"
   101  	"path/filepath"
   102  	"runtime"
   103  	"strconv"
   104  	"strings"
   105  	"sync/atomic"
   106  	"syscall"
   107  	"time"
   108  )
   109  
   110  // Error is returned by [LookPath] when it fails to classify a file as an
   111  // executable.
   112  type Error struct {
   113  	// Name is the file name for which the error occurred.
   114  	Name string
   115  	// Err is the underlying error.
   116  	Err error
   117  }
   118  
   119  func (e *Error) Error() string {
   120  	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
   121  }
   122  
   123  func (e *Error) Unwrap() error { return e.Err }
   124  
   125  // ErrWaitDelay is returned by [Cmd.Wait] if the process exits with a
   126  // successful status code but its output pipes are not closed before the
   127  // command's WaitDelay expires.
   128  var ErrWaitDelay = errors.New("exec: WaitDelay expired before I/O complete")
   129  
   130  // wrappedError wraps an error without relying on fmt.Errorf.
   131  type wrappedError struct {
   132  	prefix string
   133  	err    error
   134  }
   135  
   136  func (w wrappedError) Error() string {
   137  	return w.prefix + ": " + w.err.Error()
   138  }
   139  
   140  func (w wrappedError) Unwrap() error {
   141  	return w.err
   142  }
   143  
   144  // Cmd represents an external command being prepared or run.
   145  //
   146  // A Cmd cannot be reused after calling its [Cmd.Start], [Cmd.Run],
   147  // [Cmd.Output], or [Cmd.CombinedOutput] methods.
   148  type Cmd struct {
   149  	// Path is the path of the command to run.
   150  	//
   151  	// This is the only field that must be set to a non-zero
   152  	// value. If Path is relative, it is evaluated relative
   153  	// to Dir.
   154  	Path string
   155  
   156  	// Args holds command line arguments, including the command as Args[0].
   157  	// If the Args field is empty or nil, Run uses {Path}.
   158  	//
   159  	// In typical use, both Path and Args are set by calling Command.
   160  	Args []string
   161  
   162  	// Env specifies the environment of the process.
   163  	// Each entry is of the form "key=value".
   164  	// If Env is nil, the new process uses the current process's
   165  	// environment.
   166  	// If Env contains duplicate environment keys, only the last
   167  	// value in the slice for each duplicate key is used.
   168  	// As a special case on Windows, SYSTEMROOT is always added if
   169  	// missing and not explicitly set to the empty string.
   170  	//
   171  	// See also the Dir field, which may set PWD in the environment.
   172  	Env []string
   173  
   174  	// Dir specifies the working directory of the command.
   175  	// If Dir is the empty string, Run runs the command in the
   176  	// calling process's current directory.
   177  	//
   178  	// On Unix systems, the value of Dir also determines the
   179  	// child process's PWD environment variable if not otherwise
   180  	// specified. A Unix process represents its working directory
   181  	// not by name but as an implicit reference to a node in the
   182  	// file tree. So, if the child process obtains its working
   183  	// directory by calling a function such as C's getcwd, which
   184  	// computes the canonical name by walking up the file tree, it
   185  	// will not recover the original value of Dir if that value
   186  	// was an alias involving symbolic links. However, if the
   187  	// child process calls Go's [os.Getwd] or GNU C's
   188  	// get_current_dir_name, and the value of PWD is an alias for
   189  	// the current directory, those functions will return the
   190  	// value of PWD, which matches the value of Dir.
   191  	Dir string
   192  
   193  	// Stdin specifies the process's standard input.
   194  	//
   195  	// If Stdin is nil, the process reads from the null device (os.DevNull).
   196  	//
   197  	// If Stdin is an *os.File, the process's standard input is connected
   198  	// directly to that file.
   199  	//
   200  	// Otherwise, during the execution of the command a separate
   201  	// goroutine reads from Stdin and delivers that data to the command
   202  	// over a pipe. In this case, Wait does not complete until the goroutine
   203  	// stops copying, either because it has reached the end of Stdin
   204  	// (EOF or a read error), or because writing to the pipe returned an error,
   205  	// or because a nonzero WaitDelay was set and expired.
   206  	//
   207  	// Regardless of WaitDelay, Wait can block until a Read from
   208  	// Stdin completes. If you need to use a blocking io.Reader,
   209  	// use the StdinPipe method to get a pipe, copy from the Reader
   210  	// to the pipe, and arrange to close the Reader after Wait returns.
   211  	Stdin io.Reader
   212  
   213  	// Stdout and Stderr specify the process's standard output and error.
   214  	//
   215  	// If either is nil, Run connects the corresponding file descriptor
   216  	// to the null device (os.DevNull).
   217  	//
   218  	// If either is an *os.File, the corresponding output from the process
   219  	// is connected directly to that file.
   220  	//
   221  	// Otherwise, during the execution of the command a separate goroutine
   222  	// reads from the process over a pipe and delivers that data to the
   223  	// corresponding Writer. In this case, Wait does not complete until the
   224  	// goroutine reaches EOF or encounters an error or a nonzero WaitDelay
   225  	// expires.
   226  	//
   227  	// Regardless of WaitDelay, Wait can block until a Write to
   228  	// Stdout or Stderr completes. If you need to use a blocking io.Writer,
   229  	// use the StdoutPipe or StderrPipe method to get a pipe,
   230  	// copy from the pipe to the Writer, and arrange to close the
   231  	// Writer after Wait returns.
   232  	//
   233  	// If Stdout and Stderr are the same writer, and have a type that can
   234  	// be compared with ==, at most one goroutine at a time will call Write.
   235  	Stdout io.Writer
   236  	Stderr io.Writer
   237  
   238  	// ExtraFiles specifies additional open files to be inherited by the
   239  	// new process. It does not include standard input, standard output, or
   240  	// standard error. If non-nil, entry i becomes file descriptor 3+i.
   241  	//
   242  	// ExtraFiles is not supported on Windows.
   243  	ExtraFiles []*os.File
   244  
   245  	// SysProcAttr holds optional, operating system-specific attributes.
   246  	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
   247  	SysProcAttr *syscall.SysProcAttr
   248  
   249  	// Process is the underlying process, once started.
   250  	Process *os.Process
   251  
   252  	// ProcessState contains information about an exited process.
   253  	// If the process was started successfully, Wait or Run will
   254  	// populate its ProcessState when the command completes.
   255  	ProcessState *os.ProcessState
   256  
   257  	// ctx is the context passed to CommandContext, if any.
   258  	ctx context.Context
   259  
   260  	Err error // LookPath error, if any.
   261  
   262  	// If Cancel is non-nil, the command must have been created with
   263  	// CommandContext and Cancel will be called when the command's
   264  	// Context is done. By default, CommandContext sets Cancel to
   265  	// call the Kill method on the command's Process.
   266  	//
   267  	// Typically a custom Cancel will send a signal to the command's
   268  	// Process, but it may instead take other actions to initiate cancellation,
   269  	// such as closing a stdin or stdout pipe or sending a shutdown request on a
   270  	// network socket.
   271  	//
   272  	// If the command exits with a success status after Cancel is
   273  	// called, and Cancel does not return an error equivalent to
   274  	// os.ErrProcessDone, then Wait and similar methods will return a non-nil
   275  	// error: either an error wrapping the one returned by Cancel,
   276  	// or the error from the Context.
   277  	// (If the command exits with a non-success status, or Cancel
   278  	// returns an error that wraps os.ErrProcessDone, Wait and similar methods
   279  	// continue to return the command's usual exit status.)
   280  	//
   281  	// If Cancel is set to nil, nothing will happen immediately when the command's
   282  	// Context is done, but a nonzero WaitDelay will still take effect. That may
   283  	// be useful, for example, to work around deadlocks in commands that do not
   284  	// support shutdown signals but are expected to always finish quickly.
   285  	//
   286  	// Cancel will not be called if Start returns a non-nil error.
   287  	Cancel func() error
   288  
   289  	// If WaitDelay is non-zero, it bounds the time spent waiting on two sources
   290  	// of unexpected delay in Wait: a child process that fails to exit after the
   291  	// associated Context is canceled, and a child process that exits but leaves
   292  	// its I/O pipes unclosed.
   293  	//
   294  	// The WaitDelay timer starts when either the associated Context is done or a
   295  	// call to Wait observes that the child process has exited, whichever occurs
   296  	// first. When the delay has elapsed, the command shuts down the child process
   297  	// and/or its I/O pipes.
   298  	//
   299  	// If the child process has failed to exit — perhaps because it ignored or
   300  	// failed to receive a shutdown signal from a Cancel function, or because no
   301  	// Cancel function was set — then it will be terminated using os.Process.Kill.
   302  	//
   303  	// Then, if the I/O pipes communicating with the child process are still open,
   304  	// those pipes are closed in order to unblock any goroutines currently blocked
   305  	// on Read or Write calls.
   306  	//
   307  	// If pipes are closed due to WaitDelay, no Cancel call has occurred,
   308  	// and the command has otherwise exited with a successful status, Wait and
   309  	// similar methods will return ErrWaitDelay instead of nil.
   310  	//
   311  	// If WaitDelay is zero (the default), I/O pipes will be read until EOF,
   312  	// which might not occur until orphaned subprocesses of the command have
   313  	// also closed their descriptors for the pipes.
   314  	WaitDelay time.Duration
   315  
   316  	// childIOFiles holds closers for any of the child process's
   317  	// stdin, stdout, and/or stderr files that were opened by the Cmd itself
   318  	// (not supplied by the caller). These should be closed as soon as they
   319  	// are inherited by the child process.
   320  	childIOFiles []io.Closer
   321  
   322  	// parentIOPipes holds closers for the parent's end of any pipes
   323  	// connected to the child's stdin, stdout, and/or stderr streams
   324  	// that were opened by the Cmd itself (not supplied by the caller).
   325  	// These should be closed after Wait sees the command and copying
   326  	// goroutines exit, or after WaitDelay has expired.
   327  	parentIOPipes []io.Closer
   328  
   329  	// goroutine holds a set of closures to execute to copy data
   330  	// to and/or from the command's I/O pipes.
   331  	goroutine []func() error
   332  
   333  	// If goroutineErr is non-nil, it receives the first error from a copying
   334  	// goroutine once all such goroutines have completed.
   335  	// goroutineErr is set to nil once its error has been received.
   336  	goroutineErr <-chan error
   337  
   338  	// If ctxResult is non-nil, it receives the result of watchCtx exactly once.
   339  	ctxResult <-chan ctxResult
   340  
   341  	// The stack saved when the Command was created, if GODEBUG contains
   342  	// execwait=2. Used for debugging leaks.
   343  	createdByStack []byte
   344  
   345  	// For a security release long ago, we created x/sys/execabs,
   346  	// which manipulated the unexported lookPathErr error field
   347  	// in this struct. For Go 1.19 we exported the field as Err error,
   348  	// above, but we have to keep lookPathErr around for use by
   349  	// old programs building against new toolchains.
   350  	// The String and Start methods look for an error in lookPathErr
   351  	// in preference to Err, to preserve the errors that execabs sets.
   352  	//
   353  	// In general we don't guarantee misuse of reflect like this,
   354  	// but the misuse of reflect was by us, the best of various bad
   355  	// options to fix the security problem, and people depend on
   356  	// those old copies of execabs continuing to work.
   357  	// The result is that we have to leave this variable around for the
   358  	// rest of time, a compatibility scar.
   359  	//
   360  	// See https://go.dev/blog/path-security
   361  	// and https://go.dev/issue/43724 for more context.
   362  	lookPathErr error
   363  
   364  	// cachedLookExtensions caches the result of calling lookExtensions.
   365  	// It is set when Command is called with an absolute path, letting it do
   366  	// the work of resolving the extension, so Start doesn't need to do it again.
   367  	// This is only used on Windows.
   368  	cachedLookExtensions struct{ in, out string }
   369  
   370  	// startCalled records that Start was attempted, regardless of outcome.
   371  	// (Until go.dev/issue/77075 is resolved, we use atomic.SwapInt32,
   372  	// not atomic.Bool.Swap, to avoid triggering the copylocks vet check.)
   373  	startCalled int32
   374  }
   375  
   376  // A ctxResult reports the result of watching the Context associated with a
   377  // running command (and sending corresponding signals if needed).
   378  type ctxResult struct {
   379  	err error
   380  
   381  	// If timer is non-nil, it expires after WaitDelay has elapsed after
   382  	// the Context is done.
   383  	//
   384  	// (If timer is nil, that means that the Context was not done before the
   385  	// command completed, or no WaitDelay was set, or the WaitDelay already
   386  	// expired and its effect was already applied.)
   387  	timer *time.Timer
   388  }
   389  
   390  var execwait = godebug.New("#execwait")
   391  var execerrdot = godebug.New("execerrdot")
   392  
   393  // Command returns the [Cmd] struct to execute the named program with
   394  // the given arguments.
   395  //
   396  // It sets only the Path and Args in the returned structure.
   397  //
   398  // If name contains no path separators, Command uses [LookPath] to
   399  // resolve name to a complete path if possible. Otherwise it uses name
   400  // directly as Path.
   401  //
   402  // The returned Cmd's Args field is constructed from the command name
   403  // followed by the elements of arg, so arg should not include the
   404  // command name itself. For example, Command("echo", "hello").
   405  // Args[0] is always name, not the possibly resolved Path.
   406  //
   407  // On Windows, processes receive the whole command line as a single string
   408  // and do their own parsing. Command combines and quotes Args into a command
   409  // line string with an algorithm compatible with applications using
   410  // CommandLineToArgvW (which is the most common way). Notable exceptions are
   411  // msiexec.exe and cmd.exe (and thus, all batch files), which have a different
   412  // unquoting algorithm. In these or other similar cases, you can do the
   413  // quoting yourself and provide the full command line in SysProcAttr.CmdLine,
   414  // leaving Args empty.
   415  func Command(name string, arg ...string) *Cmd {
   416  	cmd := &Cmd{
   417  		Path: name,
   418  		Args: append([]string{name}, arg...),
   419  	}
   420  
   421  	if v := execwait.Value(); v != "" {
   422  		if v == "2" {
   423  			// Obtain the caller stack. (This is equivalent to runtime/debug.Stack,
   424  			// copied to avoid importing the whole package.)
   425  			stack := make([]byte, 1024)
   426  			for {
   427  				n := runtime.Stack(stack, false)
   428  				if n < len(stack) {
   429  					stack = stack[:n]
   430  					break
   431  				}
   432  				stack = make([]byte, 2*len(stack))
   433  			}
   434  
   435  			if i := bytes.Index(stack, []byte("\nos/exec.Command(")); i >= 0 {
   436  				stack = stack[i+1:]
   437  			}
   438  			cmd.createdByStack = stack
   439  		}
   440  
   441  		runtime.SetFinalizer(cmd, func(c *Cmd) {
   442  			if c.Process != nil && c.ProcessState == nil {
   443  				debugHint := ""
   444  				if c.createdByStack == nil {
   445  					debugHint = " (set GODEBUG=execwait=2 to capture stacks for debugging)"
   446  				} else {
   447  					os.Stderr.WriteString("GODEBUG=execwait=2 detected a leaked exec.Cmd created by:\n")
   448  					os.Stderr.Write(c.createdByStack)
   449  					os.Stderr.WriteString("\n")
   450  					debugHint = ""
   451  				}
   452  				panic("exec: Cmd started a Process but leaked without a call to Wait" + debugHint)
   453  			}
   454  		})
   455  	}
   456  
   457  	if filepath.Base(name) == name {
   458  		lp, err := LookPath(name)
   459  		if lp != "" {
   460  			// Update cmd.Path even if err is non-nil.
   461  			// If err is ErrDot (especially on Windows), lp may include a resolved
   462  			// extension (like .exe or .bat) that should be preserved.
   463  			cmd.Path = lp
   464  		}
   465  		if err != nil {
   466  			cmd.Err = err
   467  		}
   468  	} else if runtime.GOOS == "windows" && filepath.IsAbs(name) {
   469  		// We may need to add a filename extension from PATHEXT
   470  		// or verify an extension that is already present.
   471  		// Since the path is absolute, its extension should be unambiguous
   472  		// and independent of cmd.Dir, and we can go ahead and cache the lookup now.
   473  		//
   474  		// Note that we don't cache anything here for relative paths, because
   475  		// cmd.Dir may be set after we return from this function and that may
   476  		// cause the command to resolve to a different extension.
   477  		if lp, err := lookExtensions(name, ""); err == nil {
   478  			cmd.cachedLookExtensions.in, cmd.cachedLookExtensions.out = name, lp
   479  		} else {
   480  			cmd.Err = err
   481  		}
   482  	}
   483  	return cmd
   484  }
   485  
   486  // CommandContext is like [Command] but includes a context.
   487  //
   488  // The provided context is used to interrupt the process
   489  // (by calling cmd.Cancel or [os.Process.Kill])
   490  // if the context becomes done before the command completes on its own.
   491  //
   492  // CommandContext sets the command's Cancel function to invoke the Kill method
   493  // on its Process, and leaves its WaitDelay unset. The caller may change the
   494  // cancellation behavior by modifying those fields before starting the command.
   495  func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
   496  	if ctx == nil {
   497  		panic("nil Context")
   498  	}
   499  	cmd := Command(name, arg...)
   500  	cmd.ctx = ctx
   501  	cmd.Cancel = func() error {
   502  		return cmd.Process.Kill()
   503  	}
   504  	return cmd
   505  }
   506  
   507  // String returns a human-readable description of c.
   508  // It is intended only for debugging.
   509  // In particular, it is not suitable for use as input to a shell.
   510  // The output of String may vary across Go releases.
   511  func (c *Cmd) String() string {
   512  	if c.Err != nil || c.lookPathErr != nil {
   513  		// failed to resolve path; report the original requested path (plus args)
   514  		return strings.Join(c.Args, " ")
   515  	}
   516  	// report the exact executable path (plus args)
   517  	b := new(strings.Builder)
   518  	b.WriteString(c.Path)
   519  	for _, a := range c.Args[1:] {
   520  		b.WriteByte(' ')
   521  		b.WriteString(a)
   522  	}
   523  	return b.String()
   524  }
   525  
   526  // interfaceEqual protects against panics from doing equality tests on
   527  // two interfaces with non-comparable underlying types.
   528  func interfaceEqual(a, b any) bool {
   529  	defer func() {
   530  		recover()
   531  	}()
   532  	return a == b
   533  }
   534  
   535  func (c *Cmd) argv() []string {
   536  	if len(c.Args) > 0 {
   537  		return c.Args
   538  	}
   539  	return []string{c.Path}
   540  }
   541  
   542  func (c *Cmd) childStdin() (*os.File, error) {
   543  	if c.Stdin == nil {
   544  		f, err := os.Open(os.DevNull)
   545  		if err != nil {
   546  			return nil, err
   547  		}
   548  		c.childIOFiles = append(c.childIOFiles, f)
   549  		return f, nil
   550  	}
   551  
   552  	if f, ok := c.Stdin.(*os.File); ok {
   553  		return f, nil
   554  	}
   555  
   556  	pr, pw, err := os.Pipe()
   557  	if err != nil {
   558  		return nil, err
   559  	}
   560  
   561  	c.childIOFiles = append(c.childIOFiles, pr)
   562  	c.parentIOPipes = append(c.parentIOPipes, pw)
   563  	c.goroutine = append(c.goroutine, func() error {
   564  		_, err := io.Copy(pw, c.Stdin)
   565  		if skipStdinCopyError(err) {
   566  			err = nil
   567  		}
   568  		if err1 := pw.Close(); err == nil {
   569  			err = err1
   570  		}
   571  		return err
   572  	})
   573  	return pr, nil
   574  }
   575  
   576  func (c *Cmd) childStdout() (*os.File, error) {
   577  	return c.writerDescriptor(c.Stdout)
   578  }
   579  
   580  func (c *Cmd) childStderr(childStdout *os.File) (*os.File, error) {
   581  	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
   582  		return childStdout, nil
   583  	}
   584  	return c.writerDescriptor(c.Stderr)
   585  }
   586  
   587  // writerDescriptor returns an os.File to which the child process
   588  // can write to send data to w.
   589  //
   590  // If w is nil, writerDescriptor returns a File that writes to os.DevNull.
   591  func (c *Cmd) writerDescriptor(w io.Writer) (*os.File, error) {
   592  	if w == nil {
   593  		f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
   594  		if err != nil {
   595  			return nil, err
   596  		}
   597  		c.childIOFiles = append(c.childIOFiles, f)
   598  		return f, nil
   599  	}
   600  
   601  	if f, ok := w.(*os.File); ok {
   602  		return f, nil
   603  	}
   604  
   605  	pr, pw, err := os.Pipe()
   606  	if err != nil {
   607  		return nil, err
   608  	}
   609  
   610  	c.childIOFiles = append(c.childIOFiles, pw)
   611  	c.parentIOPipes = append(c.parentIOPipes, pr)
   612  	c.goroutine = append(c.goroutine, func() error {
   613  		_, err := io.Copy(w, pr)
   614  		pr.Close() // in case io.Copy stopped due to write error
   615  		return err
   616  	})
   617  	return pw, nil
   618  }
   619  
   620  func closeDescriptors(closers []io.Closer) {
   621  	for _, fd := range closers {
   622  		fd.Close()
   623  	}
   624  }
   625  
   626  // Run starts the specified command and waits for it to complete.
   627  //
   628  // The returned error is nil if the command runs, has no problems
   629  // copying stdin, stdout, and stderr, and exits with a zero exit
   630  // status.
   631  //
   632  // If the command starts but does not complete successfully, the error is of
   633  // type [*ExitError]. Other error types may be returned for other situations.
   634  //
   635  // If the calling goroutine has locked the operating system thread
   636  // with [runtime.LockOSThread] and modified any inheritable OS-level
   637  // thread state (for example, Linux or Plan 9 name spaces), the new
   638  // process will inherit the caller's thread state.
   639  func (c *Cmd) Run() error {
   640  	if err := c.Start(); err != nil {
   641  		return err
   642  	}
   643  	return c.Wait()
   644  }
   645  
   646  // Start starts the specified command but does not wait for it to complete.
   647  //
   648  // If Start returns successfully, the c.Process field will be set.
   649  //
   650  // After a successful call to Start the [Cmd.Wait] method must be called in
   651  // order to release associated system resources.
   652  func (c *Cmd) Start() error {
   653  	// Check for doubled Start calls before we defer failure cleanup. If the prior
   654  	// call to Start succeeded, we don't want to spuriously close its pipes.
   655  	// It is an error to call Start twice even if the first call did not create a process.
   656  	if atomic.SwapInt32(&c.startCalled, 1) != 0 {
   657  		return errors.New("exec: already started")
   658  	}
   659  
   660  	started := false
   661  	defer func() {
   662  		closeDescriptors(c.childIOFiles)
   663  		c.childIOFiles = nil
   664  
   665  		if !started {
   666  			closeDescriptors(c.parentIOPipes)
   667  			c.parentIOPipes = nil
   668  			c.goroutine = nil // aid GC, finalization of pipe fds
   669  		}
   670  	}()
   671  
   672  	if c.Path == "" && c.Err == nil && c.lookPathErr == nil {
   673  		c.Err = errors.New("exec: no command")
   674  	}
   675  	if c.Err != nil || c.lookPathErr != nil {
   676  		if c.lookPathErr != nil {
   677  			return c.lookPathErr
   678  		}
   679  		return c.Err
   680  	}
   681  	lp := c.Path
   682  	if runtime.GOOS == "windows" {
   683  		if c.Path == c.cachedLookExtensions.in {
   684  			// If Command was called with an absolute path, we already resolved
   685  			// its extension and shouldn't need to do so again (provided c.Path
   686  			// wasn't set to another value between the calls to Command and Start).
   687  			lp = c.cachedLookExtensions.out
   688  		} else {
   689  			// If *Cmd was made without using Command at all, or if Command was
   690  			// called with a relative path, we had to wait until now to resolve
   691  			// it in case c.Dir was changed.
   692  			//
   693  			// Unfortunately, we cannot write the result back to c.Path because programs
   694  			// may assume that they can call Start concurrently with reading the path.
   695  			// (It is safe and non-racy to do so on Unix platforms, and users might not
   696  			// test with the race detector on all platforms;
   697  			// see https://go.dev/issue/62596.)
   698  			//
   699  			// So we will pass the fully resolved path to os.StartProcess, but leave
   700  			// c.Path as is: missing a bit of logging information seems less harmful
   701  			// than triggering a surprising data race, and if the user really cares
   702  			// about that bit of logging they can always use LookPath to resolve it.
   703  			var err error
   704  			lp, err = lookExtensions(c.Path, c.Dir)
   705  			if err != nil {
   706  				return err
   707  			}
   708  		}
   709  	}
   710  	if c.Cancel != nil && c.ctx == nil {
   711  		return errors.New("exec: command with a non-nil Cancel was not created with CommandContext")
   712  	}
   713  	if c.ctx != nil {
   714  		select {
   715  		case <-c.ctx.Done():
   716  			return c.ctx.Err()
   717  		default:
   718  		}
   719  	}
   720  
   721  	childFiles := make([]*os.File, 0, 3+len(c.ExtraFiles))
   722  	stdin, err := c.childStdin()
   723  	if err != nil {
   724  		return err
   725  	}
   726  	childFiles = append(childFiles, stdin)
   727  	stdout, err := c.childStdout()
   728  	if err != nil {
   729  		return err
   730  	}
   731  	childFiles = append(childFiles, stdout)
   732  	stderr, err := c.childStderr(stdout)
   733  	if err != nil {
   734  		return err
   735  	}
   736  	childFiles = append(childFiles, stderr)
   737  	childFiles = append(childFiles, c.ExtraFiles...)
   738  
   739  	env, err := c.environ()
   740  	if err != nil {
   741  		return err
   742  	}
   743  
   744  	c.Process, err = os.StartProcess(lp, c.argv(), &os.ProcAttr{
   745  		Dir:   c.Dir,
   746  		Files: childFiles,
   747  		Env:   env,
   748  		Sys:   c.SysProcAttr,
   749  	})
   750  	if err != nil {
   751  		return err
   752  	}
   753  	started = true
   754  
   755  	// Don't allocate the goroutineErr channel unless there are goroutines to start.
   756  	if len(c.goroutine) > 0 {
   757  		goroutineErr := make(chan error, 1)
   758  		c.goroutineErr = goroutineErr
   759  
   760  		type goroutineStatus struct {
   761  			running  int
   762  			firstErr error
   763  		}
   764  		statusc := make(chan goroutineStatus, 1)
   765  		statusc <- goroutineStatus{running: len(c.goroutine)}
   766  		for _, fn := range c.goroutine {
   767  			go func(fn func() error) {
   768  				err := fn()
   769  
   770  				status := <-statusc
   771  				if status.firstErr == nil {
   772  					status.firstErr = err
   773  				}
   774  				status.running--
   775  				if status.running == 0 {
   776  					goroutineErr <- status.firstErr
   777  				} else {
   778  					statusc <- status
   779  				}
   780  			}(fn)
   781  		}
   782  		c.goroutine = nil // Allow the goroutines' closures to be GC'd when they complete.
   783  	}
   784  
   785  	// If we have anything to do when the command's Context expires,
   786  	// start a goroutine to watch for cancellation.
   787  	//
   788  	// (Even if the command was created by CommandContext, a helper library may
   789  	// have explicitly set its Cancel field back to nil, indicating that it should
   790  	// be allowed to continue running after cancellation after all.)
   791  	if (c.Cancel != nil || c.WaitDelay != 0) && c.ctx != nil && c.ctx.Done() != nil {
   792  		resultc := make(chan ctxResult)
   793  		c.ctxResult = resultc
   794  		go c.watchCtx(resultc)
   795  	}
   796  
   797  	return nil
   798  }
   799  
   800  // watchCtx watches c.ctx until it is able to send a result to resultc.
   801  //
   802  // If c.ctx is done before a result can be sent, watchCtx calls c.Cancel,
   803  // and/or kills cmd.Process it after c.WaitDelay has elapsed.
   804  //
   805  // watchCtx manipulates c.goroutineErr, so its result must be received before
   806  // c.awaitGoroutines is called.
   807  func (c *Cmd) watchCtx(resultc chan<- ctxResult) {
   808  	select {
   809  	case resultc <- ctxResult{}:
   810  		return
   811  	case <-c.ctx.Done():
   812  	}
   813  
   814  	var err error
   815  	if c.Cancel != nil {
   816  		if interruptErr := c.Cancel(); interruptErr == nil {
   817  			// We appear to have successfully interrupted the command, so any
   818  			// program behavior from this point may be due to ctx even if the
   819  			// command exits with code 0.
   820  			err = c.ctx.Err()
   821  		} else if errors.Is(interruptErr, os.ErrProcessDone) {
   822  			// The process already finished: we just didn't notice it yet.
   823  			// (Perhaps c.Wait hadn't been called, or perhaps it happened to race with
   824  			// c.ctx being canceled.) Don't inject a needless error.
   825  		} else {
   826  			err = wrappedError{
   827  				prefix: "exec: canceling Cmd",
   828  				err:    interruptErr,
   829  			}
   830  		}
   831  	}
   832  	if c.WaitDelay == 0 {
   833  		resultc <- ctxResult{err: err}
   834  		return
   835  	}
   836  
   837  	timer := time.NewTimer(c.WaitDelay)
   838  	select {
   839  	case resultc <- ctxResult{err: err, timer: timer}:
   840  		// c.Process.Wait returned and we've handed the timer off to c.Wait.
   841  		// It will take care of goroutine shutdown from here.
   842  		return
   843  	case <-timer.C:
   844  	}
   845  
   846  	killed := false
   847  	if killErr := c.Process.Kill(); killErr == nil {
   848  		// We appear to have killed the process. c.Process.Wait should return a
   849  		// non-nil error to c.Wait unless the Kill signal races with a successful
   850  		// exit, and if that does happen we shouldn't report a spurious error,
   851  		// so don't set err to anything here.
   852  		killed = true
   853  	} else if !errors.Is(killErr, os.ErrProcessDone) {
   854  		err = wrappedError{
   855  			prefix: "exec: killing Cmd",
   856  			err:    killErr,
   857  		}
   858  	}
   859  
   860  	if c.goroutineErr != nil {
   861  		select {
   862  		case goroutineErr := <-c.goroutineErr:
   863  			// Forward goroutineErr only if we don't have reason to believe it was
   864  			// caused by a call to Cancel or Kill above.
   865  			if err == nil && !killed {
   866  				err = goroutineErr
   867  			}
   868  		default:
   869  			// Close the child process's I/O pipes, in case it abandoned some
   870  			// subprocess that inherited them and is still holding them open
   871  			// (see https://go.dev/issue/23019).
   872  			//
   873  			// We close the goroutine pipes only after we have sent any signals we're
   874  			// going to send to the process (via Signal or Kill above): if we send
   875  			// SIGKILL to the process, we would prefer for it to die of SIGKILL, not
   876  			// SIGPIPE. (However, this may still cause any orphaned subprocesses to
   877  			// terminate with SIGPIPE.)
   878  			closeDescriptors(c.parentIOPipes)
   879  			// Wait for the copying goroutines to finish, but report ErrWaitDelay for
   880  			// the error: any other error here could result from closing the pipes.
   881  			_ = <-c.goroutineErr
   882  			if err == nil {
   883  				err = ErrWaitDelay
   884  			}
   885  		}
   886  
   887  		// Since we have already received the only result from c.goroutineErr,
   888  		// set it to nil to prevent awaitGoroutines from blocking on it.
   889  		c.goroutineErr = nil
   890  	}
   891  
   892  	resultc <- ctxResult{err: err}
   893  }
   894  
   895  // An ExitError reports an unsuccessful exit by a command.
   896  type ExitError struct {
   897  	*os.ProcessState
   898  
   899  	// Stderr holds a subset of the standard error output from the
   900  	// Cmd.Output method if standard error was not otherwise being
   901  	// collected.
   902  	//
   903  	// If the error output is long, Stderr may contain only a prefix
   904  	// and suffix of the output, with the middle replaced with
   905  	// text about the number of omitted bytes.
   906  	//
   907  	// Stderr is provided for debugging, for inclusion in error messages.
   908  	// Users with other needs should redirect Cmd.Stderr as needed.
   909  	Stderr []byte
   910  }
   911  
   912  func (e *ExitError) Error() string {
   913  	return e.ProcessState.String()
   914  }
   915  
   916  // Wait waits for the command to exit and waits for any copying to
   917  // stdin or copying from stdout or stderr to complete.
   918  //
   919  // The command must have been started by [Cmd.Start].
   920  //
   921  // The returned error is nil if the command runs, has no problems
   922  // copying stdin, stdout, and stderr, and exits with a zero exit
   923  // status.
   924  //
   925  // If the command fails to run or doesn't complete successfully, the
   926  // error is of type [*ExitError]. Other error types may be
   927  // returned for I/O problems.
   928  //
   929  // If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits
   930  // for the respective I/O loop copying to or from the process to complete.
   931  //
   932  // Wait must not be called concurrently from multiple goroutines.
   933  // A custom Cmd.Cancel function should not call Wait.
   934  //
   935  // Wait releases any resources associated with the [Cmd].
   936  func (c *Cmd) Wait() error {
   937  	if c.Process == nil {
   938  		return errors.New("exec: not started")
   939  	}
   940  	if c.ProcessState != nil {
   941  		return errors.New("exec: Wait was already called")
   942  	}
   943  
   944  	state, err := c.Process.Wait()
   945  	if err == nil && !state.Success() {
   946  		err = &ExitError{ProcessState: state}
   947  	}
   948  	c.ProcessState = state
   949  
   950  	var timer *time.Timer
   951  	if c.ctxResult != nil {
   952  		watch := <-c.ctxResult
   953  		timer = watch.timer
   954  		// If c.Process.Wait returned an error, prefer that.
   955  		// Otherwise, report any error from the watchCtx goroutine,
   956  		// such as a Context cancellation or a WaitDelay overrun.
   957  		if err == nil && watch.err != nil {
   958  			err = watch.err
   959  		}
   960  	}
   961  
   962  	if goroutineErr := c.awaitGoroutines(timer); err == nil {
   963  		// Report an error from the copying goroutines only if the program otherwise
   964  		// exited normally on its own. Otherwise, the copying error may be due to the
   965  		// abnormal termination.
   966  		err = goroutineErr
   967  	}
   968  	closeDescriptors(c.parentIOPipes)
   969  	c.parentIOPipes = nil
   970  
   971  	return err
   972  }
   973  
   974  // awaitGoroutines waits for the results of the goroutines copying data to or
   975  // from the command's I/O pipes.
   976  //
   977  // If c.WaitDelay elapses before the goroutines complete, awaitGoroutines
   978  // forcibly closes their pipes and returns ErrWaitDelay.
   979  //
   980  // If timer is non-nil, it must send to timer.C at the end of c.WaitDelay.
   981  func (c *Cmd) awaitGoroutines(timer *time.Timer) error {
   982  	defer func() {
   983  		if timer != nil {
   984  			timer.Stop()
   985  		}
   986  		c.goroutineErr = nil
   987  	}()
   988  
   989  	if c.goroutineErr == nil {
   990  		return nil // No running goroutines to await.
   991  	}
   992  
   993  	if timer == nil {
   994  		if c.WaitDelay == 0 {
   995  			return <-c.goroutineErr
   996  		}
   997  
   998  		select {
   999  		case err := <-c.goroutineErr:
  1000  			// Avoid the overhead of starting a timer.
  1001  			return err
  1002  		default:
  1003  		}
  1004  
  1005  		// No existing timer was started: either there is no Context associated with
  1006  		// the command, or c.Process.Wait completed before the Context was done.
  1007  		timer = time.NewTimer(c.WaitDelay)
  1008  	}
  1009  
  1010  	select {
  1011  	case <-timer.C:
  1012  		closeDescriptors(c.parentIOPipes)
  1013  		// Wait for the copying goroutines to finish, but ignore any error
  1014  		// (since it was probably caused by closing the pipes).
  1015  		_ = <-c.goroutineErr
  1016  		return ErrWaitDelay
  1017  
  1018  	case err := <-c.goroutineErr:
  1019  		return err
  1020  	}
  1021  }
  1022  
  1023  // Output runs the command and returns its standard output.
  1024  // Any returned error will usually be of type [*ExitError].
  1025  // If c.Stderr was nil and the returned error is of type
  1026  // [*ExitError], Output populates the Stderr field of the
  1027  // returned error.
  1028  func (c *Cmd) Output() ([]byte, error) {
  1029  	if c.Stdout != nil {
  1030  		return nil, errors.New("exec: Stdout already set")
  1031  	}
  1032  	var stdout bytes.Buffer
  1033  	c.Stdout = &stdout
  1034  
  1035  	captureErr := c.Stderr == nil
  1036  	if captureErr {
  1037  		c.Stderr = &prefixSuffixSaver{N: 32 << 10}
  1038  	}
  1039  
  1040  	err := c.Run()
  1041  	if err != nil && captureErr {
  1042  		if ee, ok := err.(*ExitError); ok {
  1043  			ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
  1044  		}
  1045  	}
  1046  	return stdout.Bytes(), err
  1047  }
  1048  
  1049  // CombinedOutput runs the command and returns its combined standard
  1050  // output and standard error.
  1051  func (c *Cmd) CombinedOutput() ([]byte, error) {
  1052  	if c.Stdout != nil {
  1053  		return nil, errors.New("exec: Stdout already set")
  1054  	}
  1055  	if c.Stderr != nil {
  1056  		return nil, errors.New("exec: Stderr already set")
  1057  	}
  1058  	var b bytes.Buffer
  1059  	c.Stdout = &b
  1060  	c.Stderr = &b
  1061  	err := c.Run()
  1062  	return b.Bytes(), err
  1063  }
  1064  
  1065  // StdinPipe returns a pipe that will be connected to the command's
  1066  // standard input when the command starts.
  1067  // The pipe will be closed automatically after [Cmd.Wait] sees the command exit.
  1068  // A caller need only call Close to force the pipe to close sooner.
  1069  // For example, if the command being run will not exit until standard input
  1070  // is closed, the caller must close the pipe.
  1071  func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
  1072  	if c.Stdin != nil {
  1073  		return nil, errors.New("exec: Stdin already set")
  1074  	}
  1075  	if c.Process != nil {
  1076  		return nil, errors.New("exec: StdinPipe after process started")
  1077  	}
  1078  	pr, pw, err := os.Pipe()
  1079  	if err != nil {
  1080  		return nil, err
  1081  	}
  1082  	c.Stdin = pr
  1083  	c.childIOFiles = append(c.childIOFiles, pr)
  1084  	c.parentIOPipes = append(c.parentIOPipes, pw)
  1085  	return pw, nil
  1086  }
  1087  
  1088  // StdoutPipe returns a pipe that will be connected to the command's
  1089  // standard output when the command starts.
  1090  //
  1091  // [Cmd.Wait] will close the pipe after seeing the command exit, so most callers
  1092  // need not close the pipe themselves. It is thus incorrect to call Wait
  1093  // before all reads from the pipe have completed.
  1094  // For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe.
  1095  // See the example for idiomatic usage.
  1096  func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
  1097  	if c.Stdout != nil {
  1098  		return nil, errors.New("exec: Stdout already set")
  1099  	}
  1100  	if c.Process != nil {
  1101  		return nil, errors.New("exec: StdoutPipe after process started")
  1102  	}
  1103  	pr, pw, err := os.Pipe()
  1104  	if err != nil {
  1105  		return nil, err
  1106  	}
  1107  	c.Stdout = pw
  1108  	c.childIOFiles = append(c.childIOFiles, pw)
  1109  	c.parentIOPipes = append(c.parentIOPipes, pr)
  1110  	return pr, nil
  1111  }
  1112  
  1113  // StderrPipe returns a pipe that will be connected to the command's
  1114  // standard error when the command starts.
  1115  //
  1116  // [Cmd.Wait] will close the pipe after seeing the command exit, so most callers
  1117  // need not close the pipe themselves. It is thus incorrect to call Wait
  1118  // before all reads from the pipe have completed.
  1119  // For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe.
  1120  // See the StdoutPipe example for idiomatic usage.
  1121  func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
  1122  	if c.Stderr != nil {
  1123  		return nil, errors.New("exec: Stderr already set")
  1124  	}
  1125  	if c.Process != nil {
  1126  		return nil, errors.New("exec: StderrPipe after process started")
  1127  	}
  1128  	pr, pw, err := os.Pipe()
  1129  	if err != nil {
  1130  		return nil, err
  1131  	}
  1132  	c.Stderr = pw
  1133  	c.childIOFiles = append(c.childIOFiles, pw)
  1134  	c.parentIOPipes = append(c.parentIOPipes, pr)
  1135  	return pr, nil
  1136  }
  1137  
  1138  // prefixSuffixSaver is an io.Writer which retains the first N bytes
  1139  // and the last N bytes written to it. The Bytes() methods reconstructs
  1140  // it with a pretty error message.
  1141  type prefixSuffixSaver struct {
  1142  	N         int // max size of prefix or suffix
  1143  	prefix    []byte
  1144  	suffix    []byte // ring buffer once len(suffix) == N
  1145  	suffixOff int    // offset to write into suffix
  1146  	skipped   int64
  1147  
  1148  	// TODO(bradfitz): we could keep one large []byte and use part of it for
  1149  	// the prefix, reserve space for the '... Omitting N bytes ...' message,
  1150  	// then the ring buffer suffix, and just rearrange the ring buffer
  1151  	// suffix when Bytes() is called, but it doesn't seem worth it for
  1152  	// now just for error messages. It's only ~64KB anyway.
  1153  }
  1154  
  1155  func (w *prefixSuffixSaver) Write(p []byte) (n int, err error) {
  1156  	lenp := len(p)
  1157  	p = w.fill(&w.prefix, p)
  1158  
  1159  	// Only keep the last w.N bytes of suffix data.
  1160  	if overage := len(p) - w.N; overage > 0 {
  1161  		p = p[overage:]
  1162  		w.skipped += int64(overage)
  1163  	}
  1164  	p = w.fill(&w.suffix, p)
  1165  
  1166  	// w.suffix is full now if p is non-empty. Overwrite it in a circle.
  1167  	for len(p) > 0 { // 0, 1, or 2 iterations.
  1168  		n := copy(w.suffix[w.suffixOff:], p)
  1169  		p = p[n:]
  1170  		w.skipped += int64(n)
  1171  		w.suffixOff += n
  1172  		if w.suffixOff == w.N {
  1173  			w.suffixOff = 0
  1174  		}
  1175  	}
  1176  	return lenp, nil
  1177  }
  1178  
  1179  // fill appends up to len(p) bytes of p to *dst, such that *dst does not
  1180  // grow larger than w.N. It returns the un-appended suffix of p.
  1181  func (w *prefixSuffixSaver) fill(dst *[]byte, p []byte) (pRemain []byte) {
  1182  	if remain := w.N - len(*dst); remain > 0 {
  1183  		add := min(len(p), remain)
  1184  		*dst = append(*dst, p[:add]...)
  1185  		p = p[add:]
  1186  	}
  1187  	return p
  1188  }
  1189  
  1190  func (w *prefixSuffixSaver) Bytes() []byte {
  1191  	if w.suffix == nil {
  1192  		return w.prefix
  1193  	}
  1194  	if w.skipped == 0 {
  1195  		return append(w.prefix, w.suffix...)
  1196  	}
  1197  	var buf bytes.Buffer
  1198  	buf.Grow(len(w.prefix) + len(w.suffix) + 50)
  1199  	buf.Write(w.prefix)
  1200  	buf.WriteString("\n... omitting ")
  1201  	buf.WriteString(strconv.FormatInt(w.skipped, 10))
  1202  	buf.WriteString(" bytes ...\n")
  1203  	buf.Write(w.suffix[w.suffixOff:])
  1204  	buf.Write(w.suffix[:w.suffixOff])
  1205  	return buf.Bytes()
  1206  }
  1207  
  1208  // environ returns a best-effort copy of the environment in which the command
  1209  // would be run as it is currently configured. If an error occurs in computing
  1210  // the environment, it is returned alongside the best-effort copy.
  1211  func (c *Cmd) environ() ([]string, error) {
  1212  	var err error
  1213  
  1214  	env := c.Env
  1215  	if env == nil {
  1216  		env, err = execenv.Default(c.SysProcAttr)
  1217  		if err != nil {
  1218  			env = os.Environ()
  1219  			// Note that the non-nil err is preserved despite env being overridden.
  1220  		}
  1221  
  1222  		if c.Dir != "" {
  1223  			switch runtime.GOOS {
  1224  			case "windows", "plan9":
  1225  				// Windows and Plan 9 do not use the PWD variable, so we don't need to
  1226  				// keep it accurate.
  1227  			default:
  1228  				// On POSIX platforms, PWD represents “an absolute pathname of the
  1229  				// current working directory.” Since we are changing the working
  1230  				// directory for the command, we should also update PWD to reflect that.
  1231  				//
  1232  				// Unfortunately, we didn't always do that, so (as proposed in
  1233  				// https://go.dev/issue/50599) to avoid unintended collateral damage we
  1234  				// only implicitly update PWD when Env is nil. That way, we're much
  1235  				// less likely to override an intentional change to the variable.
  1236  				if pwd, absErr := filepath.Abs(c.Dir); absErr == nil {
  1237  					env = append(env, "PWD="+pwd)
  1238  				} else if err == nil {
  1239  					err = absErr
  1240  				}
  1241  			}
  1242  		}
  1243  	}
  1244  
  1245  	env, dedupErr := dedupEnv(env)
  1246  	if err == nil {
  1247  		err = dedupErr
  1248  	}
  1249  	return addCriticalEnv(env), err
  1250  }
  1251  
  1252  // Environ returns a copy of the environment in which the command would be run
  1253  // as it is currently configured.
  1254  func (c *Cmd) Environ() []string {
  1255  	//  Intentionally ignore errors: environ returns a best-effort environment no matter what.
  1256  	env, _ := c.environ()
  1257  	return env
  1258  }
  1259  
  1260  // dedupEnv returns a copy of env with any duplicates removed, in favor of
  1261  // later values.
  1262  // Items not of the normal environment "key=value" form are preserved unchanged.
  1263  // Except on Plan 9, items containing NUL characters are removed, and
  1264  // an error is returned along with the remaining values.
  1265  func dedupEnv(env []string) ([]string, error) {
  1266  	return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
  1267  }
  1268  
  1269  // dedupEnvCase is dedupEnv with a case option for testing.
  1270  // If caseInsensitive is true, the case of keys is ignored.
  1271  // If nulOK is false, items containing NUL characters are allowed.
  1272  func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
  1273  	// Construct the output in reverse order, to preserve the
  1274  	// last occurrence of each key.
  1275  	var err error
  1276  	out := make([]string, 0, len(env))
  1277  	saw := make(map[string]bool, len(env))
  1278  	for n := len(env); n > 0; n-- {
  1279  		kv := env[n-1]
  1280  
  1281  		// Reject NUL in environment variables to prevent security issues (#56284);
  1282  		// except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
  1283  		if !nulOK && strings.IndexByte(kv, 0) != -1 {
  1284  			err = errors.New("exec: environment variable contains NUL")
  1285  			continue
  1286  		}
  1287  
  1288  		i := strings.Index(kv, "=")
  1289  		if i == 0 {
  1290  			// We observe in practice keys with a single leading "=" on Windows.
  1291  			// TODO(#49886): Should we consume only the first leading "=" as part
  1292  			// of the key, or parse through arbitrarily many of them until a non-"="?
  1293  			i = strings.Index(kv[1:], "=") + 1
  1294  		}
  1295  		if i < 0 {
  1296  			if kv != "" {
  1297  				// The entry is not of the form "key=value" (as it is required to be).
  1298  				// Leave it as-is for now.
  1299  				// TODO(#52436): should we strip or reject these bogus entries?
  1300  				out = append(out, kv)
  1301  			}
  1302  			continue
  1303  		}
  1304  		k := kv[:i]
  1305  		if caseInsensitive {
  1306  			k = strings.ToLower(k)
  1307  		}
  1308  		if saw[k] {
  1309  			continue
  1310  		}
  1311  
  1312  		saw[k] = true
  1313  		out = append(out, kv)
  1314  	}
  1315  
  1316  	// Now reverse the slice to restore the original order.
  1317  	for i := 0; i < len(out)/2; i++ {
  1318  		j := len(out) - i - 1
  1319  		out[i], out[j] = out[j], out[i]
  1320  	}
  1321  
  1322  	return out, err
  1323  }
  1324  
  1325  // addCriticalEnv adds any critical environment variables that are required
  1326  // (or at least almost always required) on the operating system.
  1327  // Currently this is only used for Windows.
  1328  func addCriticalEnv(env []string) []string {
  1329  	if runtime.GOOS != "windows" {
  1330  		return env
  1331  	}
  1332  	for _, kv := range env {
  1333  		k, _, ok := strings.Cut(kv, "=")
  1334  		if !ok {
  1335  			continue
  1336  		}
  1337  		if strings.EqualFold(k, "SYSTEMROOT") {
  1338  			// We already have it.
  1339  			return env
  1340  		}
  1341  	}
  1342  	return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
  1343  }
  1344  
  1345  // ErrDot indicates that a path lookup resolved to an executable
  1346  // in the current directory due to ‘.’ being in the path, either
  1347  // implicitly or explicitly. See the package documentation for details.
  1348  //
  1349  // Note that functions in this package do not return ErrDot directly.
  1350  // Code should use errors.Is(err, ErrDot), not err == ErrDot,
  1351  // to test whether a returned error err is due to this condition.
  1352  var ErrDot = errors.New("cannot run executable found relative to current directory")
  1353  
  1354  // validateLookPath excludes paths that can't be valid
  1355  // executable names. See issue #74466 and CVE-2025-47906.
  1356  func validateLookPath(s string) error {
  1357  	switch s {
  1358  	case "", ".", "..":
  1359  		return ErrNotFound
  1360  	}
  1361  	return nil
  1362  }
  1363  

View as plain text