mirror of https://github.com/Hilbis/Hilbish
fix: return other errors from sh runner
makes it so that the sh runner function will return command not found and not executable errors, which makes them able to be handled via lua properlyinsensitive-tab^2
parent
c4eb3ad368
commit
4178b78341
106
exec.go
106
exec.go
|
@ -25,8 +25,63 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var errNotExec = errors.New("not executable")
|
var errNotExec = errors.New("not executable")
|
||||||
|
var errNotFound = errors.New("not found")
|
||||||
var runnerMode rt.Value = rt.StringValue("hybrid")
|
var runnerMode rt.Value = rt.StringValue("hybrid")
|
||||||
|
|
||||||
|
type execError struct{
|
||||||
|
typ string
|
||||||
|
cmd string
|
||||||
|
code int
|
||||||
|
colon bool
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e execError) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %s", e.cmd, e.typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e execError) sprint() error {
|
||||||
|
sep := " "
|
||||||
|
if e.colon {
|
||||||
|
sep = ": "
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("hilbish: %s%s%s", e.cmd, sep, e.err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func isExecError(err error) (execError, bool) {
|
||||||
|
if exErr, ok := err.(execError); ok {
|
||||||
|
return exErr, true
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := strings.Split(err.Error(), ": ")
|
||||||
|
knownTypes := []string{
|
||||||
|
"not-found",
|
||||||
|
"not-executable",
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(fields) > 1 && contains(knownTypes, fields[1]) {
|
||||||
|
var colon bool
|
||||||
|
var e error
|
||||||
|
switch fields[1] {
|
||||||
|
case "not-found":
|
||||||
|
e = errNotFound
|
||||||
|
case "not-executable":
|
||||||
|
colon = true
|
||||||
|
e = errNotExec
|
||||||
|
}
|
||||||
|
|
||||||
|
return execError{
|
||||||
|
cmd: fields[0],
|
||||||
|
typ: fields[1],
|
||||||
|
colon: colon,
|
||||||
|
err: e,
|
||||||
|
}, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return execError{}, false
|
||||||
|
}
|
||||||
|
|
||||||
func runInput(input string, priv bool) {
|
func runInput(input string, priv bool) {
|
||||||
running = true
|
running = true
|
||||||
cmdString := aliases.Resolve(input)
|
cmdString := aliases.Resolve(input)
|
||||||
|
@ -43,10 +98,6 @@ func runInput(input string, priv bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
input, exitCode, err = handleSh(input)
|
input, exitCode, err = handleSh(input)
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, input, priv)
|
|
||||||
case "hybridRev":
|
case "hybridRev":
|
||||||
_, _, err = handleSh(input)
|
_, _, err = handleSh(input)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -54,27 +105,15 @@ func runInput(input string, priv bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
input, exitCode, err = handleLua(cmdString)
|
input, exitCode, err = handleLua(cmdString)
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, input, priv)
|
|
||||||
case "lua":
|
case "lua":
|
||||||
input, exitCode, err = handleLua(cmdString)
|
input, exitCode, err = handleLua(cmdString)
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, input, priv)
|
|
||||||
case "sh":
|
case "sh":
|
||||||
input, exitCode, err = handleSh(input)
|
input, exitCode, err = handleSh(input)
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, input, priv)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// can only be a string or function so
|
// can only be a string or function so
|
||||||
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
|
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
|
||||||
err := rt.Call(l.MainThread(), runnerMode, []rt.Value{rt.StringValue(cmdString)}, term)
|
err = rt.Call(l.MainThread(), runnerMode, []rt.Value{rt.StringValue(cmdString)}, term)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
cmdFinish(124, input, priv)
|
cmdFinish(124, input, priv)
|
||||||
|
@ -85,7 +124,6 @@ func runInput(input string, priv bool) {
|
||||||
luaexitcode := term.Get(1)
|
luaexitcode := term.Get(1)
|
||||||
runErr := term.Get(2)
|
runErr := term.Get(2)
|
||||||
|
|
||||||
var exitCode uint8
|
|
||||||
if code, ok := luaexitcode.TryInt(); ok {
|
if code, ok := luaexitcode.TryInt(); ok {
|
||||||
exitCode = uint8(code)
|
exitCode = uint8(code)
|
||||||
}
|
}
|
||||||
|
@ -94,12 +132,20 @@ func runInput(input string, priv bool) {
|
||||||
input = inp
|
input = inp
|
||||||
}
|
}
|
||||||
|
|
||||||
if runErr != rt.NilValue {
|
if errStr, ok := runErr.TryString(); ok {
|
||||||
fmt.Fprintln(os.Stderr, runErr)
|
err = fmt.Errorf("%s", errStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if exErr, ok := isExecError(err); ok {
|
||||||
|
hooks.Em.Emit("command." + exErr.typ, exErr.cmd)
|
||||||
|
err = exErr.sprint()
|
||||||
|
}
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
}
|
}
|
||||||
cmdFinish(exitCode, input, priv)
|
cmdFinish(exitCode, input, priv)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func handleLua(cmdString string) (string, uint8, error) {
|
func handleLua(cmdString string) (string, uint8, error) {
|
||||||
// First try to load input, essentially compiling to bytecode
|
// First try to load input, essentially compiling to bytecode
|
||||||
|
@ -255,12 +301,20 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
|
||||||
|
|
||||||
err := lookpath(args[0])
|
err := lookpath(args[0])
|
||||||
if err == errNotExec {
|
if err == errNotExec {
|
||||||
hooks.Em.Emit("command.no-perm", args[0])
|
return execError{
|
||||||
hooks.Em.Emit("command.not-executable", args[0])
|
typ: "not-executable",
|
||||||
return interp.NewExitStatus(126)
|
cmd: args[0],
|
||||||
|
code: 126,
|
||||||
|
colon: true,
|
||||||
|
err: errNotExec,
|
||||||
|
}
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
hooks.Em.Emit("command.not-found", args[0])
|
return execError{
|
||||||
return interp.NewExitStatus(127)
|
typ: "not-found",
|
||||||
|
cmd: args[0],
|
||||||
|
code: 127,
|
||||||
|
err: errNotFound,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
killTimeout := 2 * time.Second
|
killTimeout := 2 * time.Second
|
||||||
|
|
Loading…
Reference in New Issue