From 20a4cdb505434e046dc7c875e0dceae774468bb4 Mon Sep 17 00:00:00 2001 From: sammyette <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 16 Mar 2022 19:44:32 -0400 Subject: [PATCH] fix: handle path binaries properly on windows (closes #117, #118) (#120) * fix: handle path binaries properly on windows (closes #117, #118) * refactor: dont return exec name since it isnt needed * fix: return correct error in find exec function and stat always * fix: remove filepath import for exec file check on unix --- exec.go | 24 +++++++----------------- execfile_unix.go | 18 ++++++++++++++++++ execfile_windows.go | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 execfile_unix.go create mode 100644 execfile_windows.go diff --git a/exec.go b/exec.go index f1b7c88..aae0b4d 100644 --- a/exec.go +++ b/exec.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -17,6 +18,8 @@ import ( "mvdan.cc/sh/v3/syntax" ) +var errNotExec = errors.New("not executable") + func runInput(input, origInput string) { running = true cmdString := aliases.Resolve(input) @@ -137,7 +140,7 @@ func execCommand(cmd, old string) error { } err := lookpath(args[0]) - if err == os.ErrPermission { + if err == errNotExec { hooks.Em.Emit("command.no-perm", args[0]) return interp.NewExitStatus(126) } else if err != nil { @@ -156,19 +159,17 @@ func execCommand(cmd, old string) error { return err } -// custom lookpath function so we know if a command is found *and* has execute permission -func lookpath(file string) error { +func lookpath(file string) error { // custom lookpath function so we know if a command is found *and* is executable skip := []string{"./", "/", "../", "~/"} for _, s := range skip { if strings.HasPrefix(file, s) { - err := findExecutable(file) - return err + return findExecutable(file) } } for _, dir := range filepath.SplitList(os.Getenv("PATH")) { path := filepath.Join(dir, file) err := findExecutable(path) - if err == os.ErrPermission { + if err == errNotExec { return err } else if err == nil { return nil @@ -178,17 +179,6 @@ func lookpath(file string) error { return os.ErrNotExist } -func findExecutable(name string) error { - f, err := os.Stat(name) - if err != nil { - return err - } - if m := f.Mode(); !m.IsDir() && m & 0111 != 0 { - return nil - } - return os.ErrPermission -} - func splitInput(input string) ([]string, string) { // end my suffering // TODO: refactor this garbage diff --git a/execfile_unix.go b/execfile_unix.go new file mode 100644 index 0000000..49a337e --- /dev/null +++ b/execfile_unix.go @@ -0,0 +1,18 @@ +// +build linux darwin + +package main + +import ( + "os" +) + +func findExecutable(path string) error { + f, err := os.Stat(path) + if err != nil { + return err + } + if m := f.Mode(); !m.IsDir() && m & 0111 != 0 { + return nil + } + return errNotExec +} diff --git a/execfile_windows.go b/execfile_windows.go new file mode 100644 index 0000000..a11ea86 --- /dev/null +++ b/execfile_windows.go @@ -0,0 +1,27 @@ +// +build windows + +package main + +import ( + "path/filepath" + "os" +) + +func findExecutable(path string) error { + nameExt := filepath.Ext(path) + if nameExt == "" { + for _, ext := range filepath.SplitList(os.Getenv("PATHEXT")) { + _, err := os.Stat(path + ext) + if err == nil { + return nil + } + } + } + + _, err := os.Stat(path) + if err == nil { + return errNotExec + } + + return os.ErrNotExist +}