src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/builtin_fn_cmd.go (about)

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