2017-12-17 13:20:03 +08:00
|
|
|
package eval
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
2021-06-04 10:51:38 +08:00
|
|
|
|
|
|
|
"src.elv.sh/pkg/eval/errs"
|
2017-12-17 13:20:03 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// Command and process control.
|
|
|
|
|
2020-08-17 01:46:29 +08:00
|
|
|
// TODO(xiaq): Document "fg".
|
|
|
|
|
|
|
|
func init() {
|
2022-03-20 23:50:25 +08:00
|
|
|
addBuiltinFns(map[string]any{
|
2020-08-17 01:46:29 +08:00
|
|
|
// Command resolution
|
|
|
|
"external": external,
|
|
|
|
"has-external": hasExternal,
|
|
|
|
"search-external": searchExternal,
|
|
|
|
|
|
|
|
// Process control
|
|
|
|
"fg": fg,
|
|
|
|
"exec": execFn,
|
|
|
|
"exit": exit,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-01-05 12:07:35 +08:00
|
|
|
func external(cmd string) Callable {
|
|
|
|
return NewExternalCmd(cmd)
|
2020-08-17 01:46:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func hasExternal(cmd string) bool {
|
|
|
|
_, err := exec.LookPath(cmd)
|
|
|
|
return err == nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func searchExternal(cmd string) (string, error) {
|
|
|
|
return exec.LookPath(cmd)
|
|
|
|
}
|
2020-01-18 21:12:50 +08:00
|
|
|
|
2022-06-24 03:22:48 +08:00
|
|
|
// Can be overridden in tests.
|
|
|
|
var osExit = os.Exit
|
|
|
|
|
2018-02-04 12:52:54 +08:00
|
|
|
func exit(fm *Frame, codes ...int) error {
|
|
|
|
code := 0
|
2017-12-17 13:20:03 +08:00
|
|
|
switch len(codes) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
2018-02-04 12:52:54 +08:00
|
|
|
code = codes[0]
|
2017-12-17 13:20:03 +08:00
|
|
|
default:
|
2021-06-04 10:51:38 +08:00
|
|
|
return errs.ArityMismatch{What: "arguments", ValidLow: 0, ValidHigh: 1, Actual: len(codes)}
|
2017-12-17 13:20:03 +08:00
|
|
|
}
|
2018-02-04 12:52:54 +08:00
|
|
|
|
2022-06-20 04:45:36 +08:00
|
|
|
fm.Evaler.PreExit()
|
2022-06-24 03:22:48 +08:00
|
|
|
osExit(code)
|
|
|
|
return nil
|
2017-12-17 13:20:03 +08:00
|
|
|
}
|