github.com/yujinakayama/air@v0.0.0-20220811130100-b77a59dfa933/runner/util_darwin.go (about) 1 package runner 2 3 import ( 4 "io" 5 "os" 6 "os/exec" 7 "syscall" 8 "time" 9 ) 10 11 func (e *Engine) killCmd(cmd *exec.Cmd) (pid int, err error) { 12 pid = cmd.Process.Pid 13 14 if e.config.Build.SendInterrupt { 15 // Sending a signal to make it clear to the process that it is time to turn off 16 if err = syscall.Kill(-pid, syscall.SIGINT); err != nil { 17 return 18 } 19 time.Sleep(e.config.Build.KillDelay) 20 } 21 // https://stackoverflow.com/questions/22470193/why-wont-go-kill-a-child-process-correctly 22 err = syscall.Kill(-pid, syscall.SIGKILL) 23 // Wait releases any resources associated with the Process. 24 _, _ = cmd.Process.Wait() 25 return pid, err 26 } 27 28 func (e *Engine) startCmd(cmd string) (*exec.Cmd, io.ReadCloser, io.ReadCloser, error) { 29 c := exec.Command("/bin/sh", "-c", cmd) 30 // because using pty cannot have same pgid 31 c.SysProcAttr = &syscall.SysProcAttr{ 32 Setpgid: true, 33 } 34 35 stderr, err := c.StderrPipe() 36 if err != nil { 37 return nil, nil, nil, err 38 } 39 stdout, err := c.StdoutPipe() 40 if err != nil { 41 return nil, nil, nil, err 42 } 43 44 c.Stdout = os.Stdout 45 c.Stderr = os.Stderr 46 47 err = c.Start() 48 if err != nil { 49 return nil, nil, nil, err 50 } 51 return c, stdout, stderr, nil 52 }