├── .gitignore ├── README.md ├── proc.go ├── proc_posix.go ├── proc_windows.go └── tests ├── Procfile ├── flask_main.py ├── main.go └── tests /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kproc 2 | [![GoDoc](https://godoc.org/github.com/codeskyblue/kproc?status.svg)](https://godoc.org/github.com/codeskyblue/kproc) 3 | 4 | # Now have been moved to [kexec](https://github.com/codeskyblue/kexec) 5 | 6 | This lib is not maintained any more. **!!!** 7 | 8 | ---------- 9 | 10 | This is a golang lib, offer a better way to kill all child process. 11 | 12 | Tested on _windows, linux, darwin._ 13 | 14 | This lib has been used in [fswatch](https://github.com/codeskyblue/fswatch). 15 | 16 | ## Usage 17 | 18 | go get -v github.com/codeskyblue/kproc 19 | 20 | example: 21 | 22 | func main() { 23 | p := kproc.ProcString("python flask_main.py") 24 | p.Start() 25 | time.Sleep(3 * time.Second) 26 | err := p.Terminate(syscall.SIGKILL) 27 | if err != nil { 28 | log.Println(err) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /proc.go: -------------------------------------------------------------------------------- 1 | package kproc 2 | 3 | import "os/exec" 4 | 5 | type Process struct { 6 | *exec.Cmd 7 | } 8 | -------------------------------------------------------------------------------- /proc_posix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package kproc 4 | 5 | import ( 6 | "log" 7 | "os" 8 | "os/exec" 9 | "syscall" 10 | ) 11 | 12 | func setupCmd(cmd *exec.Cmd) { 13 | cmd.SysProcAttr = &syscall.SysProcAttr{} 14 | cmd.SysProcAttr.Setsid = true 15 | } 16 | 17 | func ProcCommand(cmd *exec.Cmd) *Process { 18 | setupCmd(cmd) 19 | return &Process{ 20 | Cmd: cmd, 21 | } 22 | } 23 | 24 | func ProcString(command string) *Process { 25 | cmd := exec.Command("/bin/bash", "-c", command) 26 | setupCmd(cmd) 27 | cmd.Stdout = os.Stdout 28 | cmd.Stderr = os.Stderr 29 | return &Process{ 30 | Cmd: cmd, 31 | } 32 | } 33 | 34 | func (p *Process) Terminate(sig os.Signal) (err error) { 35 | if p.Process == nil { 36 | return 37 | } 38 | // find pgid, ref: http://unix.stackexchange.com/questions/14815/process-descendants 39 | group, err := os.FindProcess(-1 * p.Process.Pid) 40 | log.Println(group) 41 | if err == nil { 42 | err = group.Signal(sig) 43 | } 44 | return err 45 | } 46 | -------------------------------------------------------------------------------- /proc_windows.go: -------------------------------------------------------------------------------- 1 | package kproc 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | "strconv" 7 | ) 8 | 9 | func ProcCommand(cmd *exec.Cmd) *Process { 10 | return &Process{ 11 | Cmd: cmd, 12 | } 13 | } 14 | 15 | func ProcString(command string) *Process { 16 | cmd := exec.Command("cmd", "/c", command) 17 | cmd.Stdout = os.Stdout 18 | cmd.Stderr = os.Stderr 19 | return &Process{ 20 | Cmd: cmd, 21 | } 22 | } 23 | 24 | func (p *Process) Terminate(sig os.Signal) (err error) { 25 | if p.Process == nil { 26 | return nil 27 | } 28 | pid := p.Process.Pid 29 | c := exec.Command("taskkill", "/t", "/f", "/pid", strconv.Itoa(pid)) 30 | c.Stdout = os.Stdout 31 | c.Stderr = os.Stderr 32 | return c.Run() 33 | } 34 | -------------------------------------------------------------------------------- /tests/Procfile: -------------------------------------------------------------------------------- 1 | web: python flask_main.py 2 | -------------------------------------------------------------------------------- /tests/flask_main.py: -------------------------------------------------------------------------------- 1 | import flask 2 | 3 | 4 | app = flask.Flask(__name__) 5 | 6 | @app.route('/') 7 | def homepage(): 8 | return 'Home' 9 | 10 | if __name__ == '__main__': 11 | app.run(debug=True, host='0.0.0.0') -------------------------------------------------------------------------------- /tests/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "kproc" 6 | "log" 7 | "os/exec" 8 | "syscall" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | p := kproc.ProcString("python flask_main.py") 14 | p.Start() 15 | time.Sleep(10 * time.Second) 16 | err := p.Terminate(syscall.SIGKILL) 17 | if err != nil { 18 | log.Println(err) 19 | } 20 | out, _ := exec.Command("lsof", "-i:5000").CombinedOutput() 21 | fmt.Println(string(out)) 22 | } 23 | -------------------------------------------------------------------------------- /tests/tests: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeskyblue/kproc/ded6d6ad96cefa26886dd2ebd1a61f9252a4bbd0/tests/tests --------------------------------------------------------------------------------