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  }