aboutsummaryrefslogtreecommitdiff
path: root/src/internal/execabs/execabs.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/execabs/execabs.go')
-rw-r--r--src/internal/execabs/execabs.go40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/internal/execabs/execabs.go b/src/internal/execabs/execabs.go
index 5f60fbb119..9a05d971da 100644
--- a/src/internal/execabs/execabs.go
+++ b/src/internal/execabs/execabs.go
@@ -12,7 +12,11 @@ package execabs
import (
"context"
+ "fmt"
"os/exec"
+ "path/filepath"
+ "reflect"
+ "unsafe"
)
var ErrNotFound = exec.ErrNotFound
@@ -23,14 +27,44 @@ type (
ExitError = exec.ExitError
)
+func relError(file, path string) error {
+ return fmt.Errorf("%s resolves to executable relative to current directory (.%c%s)", file, filepath.Separator, path)
+}
+
func LookPath(file string) (string, error) {
- return exec.LookPath(file)
+ path, err := exec.LookPath(file)
+ if err != nil {
+ return "", err
+ }
+ if filepath.Base(file) == file && !filepath.IsAbs(path) {
+ return "", relError(file, path)
+ }
+ return path, nil
+}
+
+func fixCmd(name string, cmd *exec.Cmd) {
+ if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) {
+ // exec.Command was called with a bare binary name and
+ // exec.LookPath returned a path which is not absolute.
+ // Set cmd.lookPathErr and clear cmd.Path so that it
+ // cannot be run.
+ lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
+ if *lookPathErr == nil {
+ *lookPathErr = relError(name, cmd.Path)
+ }
+ cmd.Path = ""
+ }
}
func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
- return exec.CommandContext(ctx, name, arg...)
+ cmd := exec.CommandContext(ctx, name, arg...)
+ fixCmd(name, cmd)
+ return cmd
+
}
func Command(name string, arg ...string) *exec.Cmd {
- return exec.Command(name, arg...)
+ cmd := exec.Command(name, arg...)
+ fixCmd(name, cmd)
+ return cmd
}