From e7d25057f67e87cc0081abf9c0b12aad42ae500f Mon Sep 17 00:00:00 2001 From: Aidan Date: Sun, 28 Jun 2020 18:01:36 -0700 Subject: [PATCH] add jobs, kill commands --- stdlib/call.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ stdlib/stdlib.go | 17 ++++++++++++ stdlib/string.go | 2 +- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/stdlib/call.go b/stdlib/call.go index c158979..0956647 100644 --- a/stdlib/call.go +++ b/stdlib/call.go @@ -21,6 +21,7 @@ import ( "os" "fmt" "bytes" + "strconv" "os/exec" "syscall" "os/signal" @@ -154,6 +155,29 @@ func fg(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { return nil } +func jobs(in *ast.Token, vt ast.VarTable, fg ast.FuncTable) *ast.Token { + ret := &ast.Token{ + Tag: ast.LIST, + Inner: &ast.Token{ + Tag: ast.STRING, + Inner: fmt.Sprintf("Total: %d", len(bgProcs)), + }, + } + + ptr := ret.Inner.(*ast.Token) + iter := &ptr + for i := 0; i < len(bgProcs); i += 1 { + (*iter).Next = &ast.Token{ + Tag: ast.STRING, + Inner: fmt.Sprintf("[%d]: %d", i, bgProcs[i].Process.Pid), + } + + iter = &(*iter).Next + } + + return ret +} + func read_cmd(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { if in == nil { return nil @@ -211,3 +235,46 @@ func read_cmd(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { func get_exit(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { return &ast.Token{Tag: ast.NUMBER, Inner: fmt.Sprintf("%d", LastExitCode)} } + +func kill(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + if in.Tag == ast.LIST { + log.Log(log.ERR, "non-number argument to kill function", "kill") + return nil + } + + pid, err := strconv.ParseInt(in.Inner.(string), 10, 64) + if err != nil { + log.Log(log.ERR, "error parsing arg to kill: " + err.Error(), "kill") + return nil + } + + found := false + newBgProcs := []*exec.Cmd{} + for _, i := range bgProcs { + if i.Process.Pid != int(pid) { + newBgProcs = append(newBgProcs, i) + } else { + found = true + err = i.Process.Kill() + if err != nil { + log.Log(log.ERR, fmt.Sprintf("error killing process %d: %s", + int(pid), err.Error()), "kill") + newBgProcs = append(newBgProcs, i) + } + } + } + + bgProcs = newBgProcs + + if !found { + // docs say no error on unix systems + proc, _ := os.FindProcess(int(pid)) + err = proc.Kill() + if err != nil { + log.Log(log.ERR, fmt.Sprintf("error killing process %d: %s", + int(pid), err.Error()), "kill") + } + } + + return nil +} diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index a7971f4..e4efcde 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -129,6 +129,23 @@ func GenFuncTable() ast.FuncTable { TimesCalled: 0, Args: 0, }, + + /* + USE NATIVE KILL COMMAND. + "kill": &ast.Function{ + Function: kill, + Name: "kill job", + TimesCalled: 0, + Args: 1, + }, + */ + + "jobs": &ast.Function{ + Function: jobs, + Name: "list jobs", + TimesCalled: 0, + Args: 0, + }, } return stdlib diff --git a/stdlib/string.go b/stdlib/string.go index 278bb30..f10ede7 100644 --- a/stdlib/string.go +++ b/stdlib/string.go @@ -39,6 +39,6 @@ func concat(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { } func print_str(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { - fmt.Println(in.Inner.(string)) + fmt.Println(in) return nil }