diff --git a/linux/events.go b/linux/events.go index df2c37c..f8168b5 100644 --- a/linux/events.go +++ b/linux/events.go @@ -2,9 +2,16 @@ package linux const ( EventOutput = iota - EventStderr + EventExit ) type EventOutputData struct { - Output string + Output string + CmdOptions CommandOptions +} + +type EventExitData struct { + HasSucceeded bool + ExitCode int + CmdOptions CommandOptions } diff --git a/linux/interface.go b/linux/interface.go index b0267d0..2e7950c 100644 --- a/linux/interface.go +++ b/linux/interface.go @@ -32,4 +32,5 @@ var ( ErrCommandNotFound = errors.New("error command not found") ErrCommandNotExecutable = errors.New("error command not executable") ErrInvalidHandler = errors.New("invalid handler") + ErrRunningEvt = errors.New("error running event") ) diff --git a/linux/run.go b/linux/run.go index 68dc1b7..308d28e 100644 --- a/linux/run.go +++ b/linux/run.go @@ -39,6 +39,8 @@ func (cmd *LinuxCommand) AddHandler(handler interface{}) error { case func(data EventOutputData) error: cmd.handlers[EventOutput] = h break + case func(data EventExitData) error: + cmd.handlers[EventExit] = h default: return ErrInvalidHandler } @@ -94,6 +96,7 @@ func (cmd *LinuxCommand) Run() error { if err := command.Start(); err != nil { var exitErr *exec.ExitError if errors.As(err, &exitErr) { + fmt.Println(exitErr.String()) if exitErr.ExitCode() == 127 { return ErrCommandNotFound } else if _, ok := cmd.Options.CustomErrors[int8(exitErr.ExitCode())]; ok { @@ -113,7 +116,8 @@ func (cmd *LinuxCommand) Run() error { line := scanner.Text() if h, ok := cmd.handlers[EventOutput]; ok { if err := h.(func(data EventOutputData) error)(EventOutputData{ - Output: line, + Output: line, + CmdOptions: cmd.Options, }); err != nil { return } @@ -129,7 +133,8 @@ func (cmd *LinuxCommand) Run() error { line := scanner.Text() if h, ok := cmd.handlers[EventOutput]; ok { if err := h.(func(data EventOutputData) error)(EventOutputData{ - Output: line, + Output: line, + CmdOptions: cmd.Options, }); err != nil { return } @@ -165,19 +170,61 @@ func (cmd *LinuxCommand) Run() error { return ErrCommandNotExecutable } + var exitInfo *EventExitData + + if _, ok := cmd.handlers[EventExit]; ok { + exitInfo = &EventExitData{ + HasSucceeded: true, + CmdOptions: cmd.Options, + } + } + if err := command.Wait(); err != nil { var exitErr *exec.ExitError - if errors.As(err, &exitErr) { + if errors.As(err, &exitErr) && exitErr.String() != "signal: interrupt" { if exitErr.ExitCode() == 127 { return ErrCommandNotFound } else if _, ok := cmd.Options.CustomErrors[int8(exitErr.ExitCode())]; ok { + if h, ok := cmd.handlers[EventExit]; ok { + if exitInfo == nil { + return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err) + } + exitInfo.HasSucceeded = false + exitInfo.ExitCode = exitErr.ExitCode() + err := h.(func(data EventExitData) error)(*exitInfo) + if err != nil { + return fmt.Errorf("%s: %w", ErrRunningEvt.Error(), err) + } + } return cmd.Options.CustomErrors[int8(exitErr.ExitCode())] } else { + if h, ok := cmd.handlers[EventExit]; ok { + if exitInfo == nil { + return fmt.Errorf("%s: %w", ErrRunningEvt.Error(), err) + } + exitInfo.HasSucceeded = false + exitInfo.ExitCode = exitErr.ExitCode() + err := h.(func(data EventExitData) error)(*exitInfo) + if err != nil { + return fmt.Errorf("%s: %w", ErrRunningEvt.Error(), err) + } + } return fmt.Errorf("%s: %w", ErrRunningCmd.Error(), err) } } } + if h, ok := cmd.handlers[EventExit]; ok { + if exitInfo == nil { + return nil + } + exitInfo.ExitCode = 0 + err := h.(func(data EventExitData) error)(*exitInfo) + if err != nil { + return fmt.Errorf("%s: %w", ErrRunningEvt.Error(), err) + } + } + close(signalChannel) signal.Stop(signalChannel) cmd.wg.Wait()