github.com/yang-ricky/air@v1.30.0/runner/util_darwin.go (about)

     1  package runner
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"os/exec"
     7  	"syscall"
     8  	"time"
     9  
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  func (e *Engine) killCmd(cmd *exec.Cmd) (pid int, err error) {
    14  	pid = cmd.Process.Pid
    15  	pgid, err := syscall.Getpgid(cmd.Process.Pid)
    16  	if err != nil {
    17  		return pgid, errors.Wrapf(err, "failed to get pgid, pid %v", pid)
    18  	}
    19  
    20  	if e.config.Build.SendInterrupt {
    21  		// Sending a signal to make it clear to the process that it is time to turn off
    22  		if err = syscall.Kill(-pgid, syscall.SIGINT); err != nil {
    23  			e.mainDebug("trying to send signal failed %v", err)
    24  			return
    25  		}
    26  		time.Sleep(e.config.Build.KillDelay * time.Millisecond)
    27  	}
    28  	err = syscall.Kill(-pgid, syscall.SIGKILL)
    29  	if err != nil {
    30  		return pid, errors.Wrapf(err, "failed to kill process by pgid %v", pgid)
    31  	}
    32  	// Wait releases any resources associated with the Process.
    33  	_, err = cmd.Process.Wait()
    34  	if err != nil {
    35  		return pid, err
    36  	}
    37  
    38  	e.mainDebug("killed process pid %d successed", pid)
    39  	return pid, nil
    40  }
    41  
    42  func (e *Engine) startCmd(cmd string) (*exec.Cmd, io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
    43  	c := exec.Command("/bin/sh", "-c", cmd)
    44  	c.SysProcAttr = &syscall.SysProcAttr{
    45  		Setpgid: true,
    46  	}
    47  
    48  	stderr, err := c.StderrPipe()
    49  	if err != nil {
    50  		return nil, nil, nil, nil, err
    51  	}
    52  	stdout, err := c.StdoutPipe()
    53  	if err != nil {
    54  		return nil, nil, nil, nil, err
    55  	}
    56  	stdin, err := c.StdinPipe()
    57  	if err != nil {
    58  		return nil, nil, nil, nil, err
    59  	}
    60  
    61  	c.Stdout = os.Stdout
    62  	c.Stderr = os.Stderr
    63  
    64  	err = c.Start()
    65  	if err != nil {
    66  		return nil, nil, nil, nil, err
    67  	}
    68  	return c, stdin, stdout, stderr, nil
    69  }