elvish/eval/builtin_fn_cmd.go
2018-01-02 23:26:28 +00:00

100 lines
1.9 KiB
Go

package eval
import (
"errors"
"fmt"
"os"
"os/exec"
"github.com/elves/elvish/eval/types"
)
// Command and process control.
var ErrNotInSameGroup = errors.New("not in the same process group")
func init() {
addToBuiltinFns([]*BuiltinFn{
// Command resolution
{"resolve", resolveFn},
{"external", external},
{"has-external", hasExternal},
{"search-external", searchExternal},
// Process control
{"fg", fg},
{"exec", execFn},
{"exit", exit},
})
}
func resolveFn(ec *Frame, args []types.Value, opts map[string]types.Value) {
var cmd types.String
ScanArgs(args, &cmd)
TakeNoOpt(opts)
out := ec.ports[1].Chan
out <- resolve(string(cmd), ec)
}
func external(ec *Frame, args []types.Value, opts map[string]types.Value) {
var cmd types.String
ScanArgs(args, &cmd)
TakeNoOpt(opts)
ec.OutputChan() <- ExternalCmd{string(cmd)}
}
func hasExternal(ec *Frame, args []types.Value, opts map[string]types.Value) {
var cmd types.String
ScanArgs(args, &cmd)
TakeNoOpt(opts)
_, err := exec.LookPath(string(cmd))
ec.OutputChan() <- types.Bool(err == nil)
}
func searchExternal(ec *Frame, args []types.Value, opts map[string]types.Value) {
var cmd types.String
ScanArgs(args, &cmd)
TakeNoOpt(opts)
path, err := exec.LookPath(string(cmd))
maybeThrow(err)
out := ec.ports[1].Chan
out <- types.String(path)
}
func exit(ec *Frame, args []types.Value, opts map[string]types.Value) {
var codes []int
ScanArgsVariadic(args, &codes)
TakeNoOpt(opts)
doexit := func(i int) {
preExit(ec)
os.Exit(i)
}
switch len(codes) {
case 0:
doexit(0)
case 1:
doexit(codes[0])
default:
throw(ErrArgs)
}
}
func preExit(ec *Frame) {
err := ec.DaemonClient.Close()
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
var errNotSupportedOnWindows = errors.New("not supported on Windows")
func notSupportedOnWindows(ec *Frame, args []types.Value, opts map[string]types.Value) {
throw(errNotSupportedOnWindows)
}