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