builtin_fn_cmd.go 941 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package eval
  2. import (
  3. "os"
  4. "os/exec"
  5. "src.elv.sh/pkg/eval/errs"
  6. )
  7. // Command and process control.
  8. // TODO(xiaq): Document "fg".
  9. func init() {
  10. addBuiltinFns(map[string]any{
  11. // Command resolution
  12. "external": external,
  13. "has-external": hasExternal,
  14. "search-external": searchExternal,
  15. // Process control
  16. "fg": fg,
  17. "exec": execFn,
  18. "exit": exit,
  19. })
  20. }
  21. func external(cmd string) Callable {
  22. return NewExternalCmd(cmd)
  23. }
  24. func hasExternal(cmd string) bool {
  25. _, err := exec.LookPath(cmd)
  26. return err == nil
  27. }
  28. func searchExternal(cmd string) (string, error) {
  29. return exec.LookPath(cmd)
  30. }
  31. // Can be overridden in tests.
  32. var osExit = os.Exit
  33. func exit(fm *Frame, codes ...int) error {
  34. code := 0
  35. switch len(codes) {
  36. case 0:
  37. case 1:
  38. code = codes[0]
  39. default:
  40. return errs.ArityMismatch{What: "arguments", ValidLow: 0, ValidHigh: 1, Actual: len(codes)}
  41. }
  42. fm.Evaler.PreExit()
  43. osExit(code)
  44. return nil
  45. }