diff options
| author | Carlos Amedee <carlos@golang.org> | 2026-01-21 15:45:40 -0500 |
|---|---|---|
| committer | Carlos Amedee <carlos@golang.org> | 2026-01-21 15:56:01 -0500 |
| commit | eec3c0ca956803db8a90dfd92ce4ebffebdaf9b4 (patch) | |
| tree | 14ed37a5aa0fd9e80b547fd43086b2b137457726 /src/os/exec | |
| parent | 4606a931d2b099f2c5e5619b797352607ee42225 (diff) | |
| parent | 2baa1d17628bb2f09757617382b1e61f1f9f0ddd (diff) | |
| download | go-eec3c0ca956803db8a90dfd92ce4ebffebdaf9b4.tar.xz | |
[release-branch.go1.26] all: merge master (2baa1d1) into release-branch.go1.26
For #76474.
Change-Id: Ic50e288f99b731b62af9aa73ce6721f0f2f3596d
Diffstat (limited to 'src/os/exec')
| -rw-r--r-- | src/os/exec/exec_test.go | 24 | ||||
| -rw-r--r-- | src/os/exec/lookpath.go | 30 | ||||
| -rw-r--r-- | src/os/exec/lp_plan9.go | 11 | ||||
| -rw-r--r-- | src/os/exec/lp_unix.go | 10 | ||||
| -rw-r--r-- | src/os/exec/lp_wasm.go | 2 | ||||
| -rw-r--r-- | src/os/exec/lp_windows.go | 26 |
6 files changed, 48 insertions, 55 deletions
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index bf2f3da535..2746ad8783 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -1845,23 +1845,13 @@ func TestStart_twice(t *testing.T) { testenv.MustHaveExec(t) cmd := exec.Command("/bin/nonesuch") - for i, want := range []string{ - cond(runtime.GOOS == "windows", - `exec: "/bin/nonesuch": executable file not found in %PATH%`, - "fork/exec /bin/nonesuch: no such file or directory"), - "exec: already started", - } { - err := cmd.Start() - if got := fmt.Sprint(err); got != want { - t.Errorf("Start call #%d return err %q, want %q", i+1, got, want) - } + if err := cmd.Start(); err == nil { + t.Fatalf("running invalid command succeeded") } -} - -func cond[T any](cond bool, t, f T) T { - if cond { - return t - } else { - return f + err := cmd.Start() + got := fmt.Sprint(err) + want := "exec: already started" + if got != want { + t.Fatalf("Start call returned err %q, want %q", got, want) } } diff --git a/src/os/exec/lookpath.go b/src/os/exec/lookpath.go new file mode 100644 index 0000000000..71f86b994f --- /dev/null +++ b/src/os/exec/lookpath.go @@ -0,0 +1,30 @@ +// Copyright 2026 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package exec + +// LookPath searches for an executable named file in the current path, +// following the conventions of the host operating system. +// If file contains a slash, it is tried directly and the default path is not consulted. +// Otherwise, on success the result is an absolute path. +// +// LookPath returns an error satisfying [errors.Is](err, [ErrDot]) +// if the resolved path is relative to the current directory. +// See the package documentation for more details. +// +// LookPath looks for an executable named file in the +// directories named by the PATH environment variable, +// except as described below. +// +// - On Windows, the file must have an extension named by +// the PATHEXT environment variable. +// When PATHEXT is unset, the file must have +// a ".com", ".exe", ".bat", or ".cmd" extension. +// - On Plan 9, LookPath consults the path environment variable. +// If file begins with "/", "#", "./", or "../", it is tried +// directly and the path is not consulted. +// - On Wasm, LookPath always returns an error. +func LookPath(file string) (string, error) { + return lookPath(file) +} diff --git a/src/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go index f713a6905c..711aad11bd 100644 --- a/src/os/exec/lp_plan9.go +++ b/src/os/exec/lp_plan9.go @@ -26,16 +26,7 @@ func findExecutable(file string) error { return fs.ErrPermission } -// LookPath searches for an executable named file in the -// directories named by the path environment variable. -// If file begins with "/", "#", "./", or "../", it is tried -// directly and the path is not consulted. -// On success, the result is an absolute path. -// -// In older versions of Go, LookPath could return a path relative to the current directory. -// As of Go 1.19, LookPath will instead return that path along with an error satisfying -// [errors.Is](err, [ErrDot]). See the package documentation for more details. -func LookPath(file string) (string, error) { +func lookPath(file string) (string, error) { if err := validateLookPath(filepath.Clean(file)); err != nil { return "", &Error{file, err} } diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go index e5fddbafe2..d3b10cc43d 100644 --- a/src/os/exec/lp_unix.go +++ b/src/os/exec/lp_unix.go @@ -41,15 +41,7 @@ func findExecutable(file string) error { return fs.ErrPermission } -// LookPath searches for an executable named file in the -// directories named by the PATH environment variable. -// If file contains a slash, it is tried directly and the PATH is not consulted. -// Otherwise, on success, the result is an absolute path. -// -// In older versions of Go, LookPath could return a path relative to the current directory. -// As of Go 1.19, LookPath will instead return that path along with an error satisfying -// [errors.Is](err, [ErrDot]). See the package documentation for more details. -func LookPath(file string) (string, error) { +func lookPath(file string) (string, error) { // NOTE(rsc): I wish we could use the Plan 9 behavior here // (only bypass the path if file begins with / or ./ or ../) // but that would not match all the Unix shells. diff --git a/src/os/exec/lp_wasm.go b/src/os/exec/lp_wasm.go index 3c819049ba..1de9076e53 100644 --- a/src/os/exec/lp_wasm.go +++ b/src/os/exec/lp_wasm.go @@ -17,7 +17,7 @@ var ErrNotFound = errors.New("executable file not found in $PATH") // directories named by the PATH environment variable. // If file contains a slash, it is tried directly and the PATH is not consulted. // The result may be an absolute path or a path relative to the current directory. -func LookPath(file string) (string, error) { +func lookPath(file string) (string, error) { // Wasm can not execute processes, so act as if there are no executables at all. return "", &Error{file, ErrNotFound} } diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go index 74537dec68..f58aabc19f 100644 --- a/src/os/exec/lp_windows.go +++ b/src/os/exec/lp_windows.go @@ -56,22 +56,12 @@ func findExecutable(file string, exts []string) (string, error) { return "", ErrNotFound } -// LookPath searches for an executable named file in the -// directories named by the PATH environment variable. -// LookPath also uses PATHEXT environment variable to match -// a suitable candidate. -// If file contains a slash, it is tried directly and the PATH is not consulted. -// Otherwise, on success, the result is an absolute path. -// -// In older versions of Go, LookPath could return a path relative to the current directory. -// As of Go 1.19, LookPath will instead return that path along with an error satisfying -// [errors.Is](err, [ErrDot]). See the package documentation for more details. -func LookPath(file string) (string, error) { +func lookPath(file string) (string, error) { if err := validateLookPath(file); err != nil { return "", &Error{file, err} } - return lookPath(file, pathExt()) + return lookPathExts(file, pathExt()) } // lookExtensions finds windows executable by its dir and path. @@ -101,17 +91,17 @@ func lookExtensions(path, dir string) (string, error) { } } if dir == "" { - return lookPath(path, exts) + return lookPathExts(path, exts) } if filepath.VolumeName(path) != "" { - return lookPath(path, exts) + return lookPathExts(path, exts) } if len(path) > 1 && os.IsPathSeparator(path[0]) { - return lookPath(path, exts) + return lookPathExts(path, exts) } dirandpath := filepath.Join(dir, path) // We assume that LookPath will only add file extension. - lp, err := lookPath(dirandpath, exts) + lp, err := lookPathExts(dirandpath, exts) if err != nil { return "", err } @@ -138,8 +128,8 @@ func pathExt() []string { return exts } -// lookPath implements LookPath for the given PATHEXT list. -func lookPath(file string, exts []string) (string, error) { +// lookPathExts implements LookPath for the given PATHEXT list. +func lookPathExts(file string, exts []string) (string, error) { if strings.ContainsAny(file, `:\/`) { f, err := findExecutable(file, exts) if err == nil { |
