From c10fdf32b2b0209963c1b3bbf61b2145cfb12daf Mon Sep 17 00:00:00 2001 From: Shane C Date: Thu, 4 Jul 2024 17:14:10 -0400 Subject: [PATCH] add executable check for commands --- linux/interface.go | 7 ++++--- linux/run.go | 12 +++++++++++- linux/utils.go | 21 +++++++++++++++++++++ main.go | 2 +- test.go | 22 ++++++++++++++++++++++ 5 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 test.go diff --git a/linux/interface.go b/linux/interface.go index 9cac60b..384ef94 100644 --- a/linux/interface.go +++ b/linux/interface.go @@ -19,7 +19,8 @@ type CommandOptions struct { // Errors var ( - ErrFetchingCwd = errors.New("error fetching cwd") - ErrRunningCmd = errors.New("error running command") - ErrCommandNotFound = errors.New("error command not found") + ErrFetchingCwd = errors.New("error fetching cwd") + ErrRunningCmd = errors.New("error running command") + ErrCommandNotFound = errors.New("error command not found") + ErrCommandNotExecutable = errors.New("error command not executable") ) diff --git a/linux/run.go b/linux/run.go index 722e508..2bfa888 100644 --- a/linux/run.go +++ b/linux/run.go @@ -30,6 +30,7 @@ func NewCommand(options CommandOptions) (*LinuxCommand, error) { func (cmd *LinuxCommand) Run() error { command := exec.Command(cmd.Options.Shell, "-c", cmd.Options.Command) + command.Path = cmd.Options.Cwd command.Args = append(command.Args, cmd.Options.Args...) // Loop through env to format and add them to the command. @@ -37,6 +38,15 @@ func (cmd *LinuxCommand) Run() error { command.Env = append(command.Env, fmt.Sprintf("%s=%s", key, value)) } + isCommandExecutable, err := cmd.isCommandExecutable(cmd.Options.Command) + if err != nil { + return err + } + + if !isCommandExecutable { + return ErrCommandNotExecutable + } + if err := command.Start(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { @@ -49,7 +59,7 @@ func (cmd *LinuxCommand) Run() error { } } - if err := command.Start(); err != nil { + if err := command.Wait(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { fmt.Println(exitErr.ExitCode()) diff --git a/linux/utils.go b/linux/utils.go index dcc5e87..7bc4bc9 100644 --- a/linux/utils.go +++ b/linux/utils.go @@ -3,9 +3,30 @@ package linux import ( "errors" "fmt" + "golang.org/x/sys/unix" + "io/fs" + "os" "os/exec" ) +func (cmd *LinuxCommand) isCommandExecutable(command string) (bool, error) { + + if _, err := os.Stat(command); errors.Is(err, fs.ErrNotExist) { + return false, err + } + + if err := unix.Access(command, unix.X_OK); err != nil { + if !errors.Is(err, unix.EACCES) { + return false, nil + } else { + return false, err + } + } + + return true, nil + +} + func (cmd *LinuxCommand) doesCommandExist(command string) (bool, error) { shellCmd := exec.Command(cmd.Options.Shell, "-c", fmt.Sprintf("command -v %s", command)) diff --git a/main.go b/main.go index 31c1b00..e5b9d97 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,4 @@ -package shell +package main import ( "bytes" diff --git a/test.go b/test.go new file mode 100644 index 0000000..819deec --- /dev/null +++ b/test.go @@ -0,0 +1,22 @@ +package main + +import ( + "git.shadowhosting.xyz/Eggactyl/shell/linux" + "log" +) + +func main() { + + cmd, err := linux.NewCommand(linux.CommandOptions{ + Command: "./test.sh", + }) + + if err != nil { + log.Fatalln(err) + } + + if err := cmd.Run(); err != nil { + log.Fatalln(err) + } + +}