diff --git a/src/cmd/go/internal/base/base.go b/src/cmd/go/internal/base/base.go index a2c95fb52f..83cbad401e 100644 --- a/src/cmd/go/internal/base/base.go +++ b/src/cmd/go/internal/base/base.go @@ -191,20 +191,28 @@ func GetExitStatus() int { // connected to the go command's own stdout and stderr. // If the command fails, Run reports the error using Errorf. func Run(cmdargs ...any) { + if err := RunErr(cmdargs...); err != nil { + Errorf("%v", err) + } +} + +// Run runs the command, with stdout and stderr +// connected to the go command's own stdout and stderr. +// If the command fails, RunErr returns the error, which +// may be an *exec.ExitError. +func RunErr(cmdargs ...any) error { cmdline := str.StringList(cmdargs...) if cfg.BuildN || cfg.BuildX { fmt.Printf("%s\n", strings.Join(cmdline, " ")) if cfg.BuildN { - return + return nil } } cmd := exec.Command(cmdline[0], cmdline[1:]...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - Errorf("%v", err) - } + return cmd.Run() } // RunStdin is like run but connects Stdin. It retries if it encounters an ETXTBSY. diff --git a/src/cmd/go/internal/doc/doc.go b/src/cmd/go/internal/doc/doc.go index 4156284d1d..7dfa652e15 100644 --- a/src/cmd/go/internal/doc/doc.go +++ b/src/cmd/go/internal/doc/doc.go @@ -9,6 +9,9 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" "context" + "errors" + "os" + "os/exec" "path/filepath" ) @@ -131,5 +134,13 @@ Flags: } func runDoc(ctx context.Context, cmd *base.Command, args []string) { - base.Run(cfg.BuildToolexec, filepath.Join(cfg.GOROOTbin, "go"), "tool", "doc", args) + base.StartSigHandlers() + err := base.RunErr(cfg.BuildToolexec, filepath.Join(cfg.GOROOTbin, "go"), "tool", "doc", args) + if err != nil { + var ee *exec.ExitError + if errors.As(err, &ee) { + os.Exit(ee.ExitCode()) + } + base.Error(err) + } }