gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/runtime/process/os/os.go (about) 1 // +build !windows 2 3 // Package os runs processes locally 4 package os 5 6 import ( 7 "fmt" 8 "os" 9 "os/exec" 10 "strconv" 11 "syscall" 12 13 "gitee.com/liuxuezhan/go-micro-v1.18.0/runtime/process" 14 ) 15 16 func (p *Process) Exec(exe *process.Executable) error { 17 cmd := exec.Command(exe.Package.Path) 18 return cmd.Run() 19 } 20 21 func (p *Process) Fork(exe *process.Executable) (*process.PID, error) { 22 // create command 23 cmd := exec.Command(exe.Package.Path, exe.Args...) 24 // set env vars 25 cmd.Env = append(cmd.Env, exe.Env...) 26 27 // create process group 28 cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} 29 30 in, err := cmd.StdinPipe() 31 if err != nil { 32 return nil, err 33 } 34 out, err := cmd.StdoutPipe() 35 if err != nil { 36 return nil, err 37 } 38 er, err := cmd.StderrPipe() 39 if err != nil { 40 return nil, err 41 } 42 43 // start the process 44 if err := cmd.Start(); err != nil { 45 return nil, err 46 } 47 48 return &process.PID{ 49 ID: fmt.Sprintf("%d", cmd.Process.Pid), 50 Input: in, 51 Output: out, 52 Error: er, 53 }, nil 54 } 55 56 func (p *Process) Kill(pid *process.PID) error { 57 id, err := strconv.Atoi(pid.ID) 58 if err != nil { 59 return err 60 } 61 62 pr, err := os.FindProcess(id) 63 if err != nil { 64 return err 65 } 66 67 // now kill it 68 err = pr.Kill() 69 70 // kill the group 71 if pgid, err := syscall.Getpgid(id); err == nil { 72 syscall.Kill(-pgid, syscall.SIGKILL) 73 } 74 75 // return the kill error 76 return err 77 } 78 79 func (p *Process) Wait(pid *process.PID) error { 80 id, err := strconv.Atoi(pid.ID) 81 if err != nil { 82 return err 83 } 84 85 pr, err := os.FindProcess(id) 86 if err != nil { 87 return err 88 } 89 90 ps, err := pr.Wait() 91 if err != nil { 92 return err 93 } 94 95 if ps.Success() { 96 return nil 97 } 98 99 return fmt.Errorf(ps.String()) 100 }