gitee.com/sasukebo/go-micro/v4@v4.7.1/runtime/local/process/os/os.go (about)

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