2019-11-23 08:25:56 +00:00
|
|
|
// +build !windows
|
|
|
|
|
2019-05-31 00:26:34 +01:00
|
|
|
// Package os runs processes locally
|
|
|
|
package os
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
2019-11-14 14:26:21 +00:00
|
|
|
"syscall"
|
2019-05-31 00:26:34 +01:00
|
|
|
|
2020-01-30 14:39:00 +03:00
|
|
|
"github.com/micro/go-micro/v2/runtime/local/process"
|
2019-05-31 00:26:34 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func (p *Process) Exec(exe *process.Executable) error {
|
2019-11-19 16:09:43 +00:00
|
|
|
cmd := exec.Command(exe.Package.Path)
|
2020-04-09 16:44:39 +02:00
|
|
|
cmd.Dir = exe.Dir
|
2019-05-31 00:26:34 +01:00
|
|
|
return cmd.Run()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Process) Fork(exe *process.Executable) (*process.PID, error) {
|
2020-05-13 18:36:45 +01:00
|
|
|
|
2019-09-13 21:33:14 -07:00
|
|
|
// create command
|
2019-11-19 16:09:43 +00:00
|
|
|
cmd := exec.Command(exe.Package.Path, exe.Args...)
|
2020-04-09 16:44:39 +02:00
|
|
|
|
|
|
|
cmd.Dir = exe.Dir
|
2019-09-13 21:33:14 -07:00
|
|
|
// set env vars
|
2020-04-09 16:44:39 +02:00
|
|
|
cmd.Env = append(cmd.Env, os.Environ()...)
|
2019-09-13 21:33:14 -07:00
|
|
|
cmd.Env = append(cmd.Env, exe.Env...)
|
|
|
|
|
2019-11-14 14:26:21 +00:00
|
|
|
// create process group
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
|
|
|
|
2019-05-31 00:26:34 +01:00
|
|
|
in, err := cmd.StdinPipe()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
out, err := cmd.StdoutPipe()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
er, err := cmd.StderrPipe()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-09-13 21:33:14 -07:00
|
|
|
// start the process
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-05-31 00:26:34 +01:00
|
|
|
return &process.PID{
|
|
|
|
ID: fmt.Sprintf("%d", cmd.Process.Pid),
|
|
|
|
Input: in,
|
|
|
|
Output: out,
|
|
|
|
Error: er,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Process) Kill(pid *process.PID) error {
|
|
|
|
id, err := strconv.Atoi(pid.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-05-13 18:36:45 +01:00
|
|
|
if _, err := os.FindProcess(id); err != nil {
|
2019-05-31 00:26:34 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-11-14 14:26:21 +00:00
|
|
|
// now kill it
|
2020-05-13 18:36:45 +01:00
|
|
|
// using -ve PID kills the process group which we created in Fork()
|
2020-06-06 15:04:14 +02:00
|
|
|
return syscall.Kill(-id, syscall.SIGTERM)
|
2019-05-31 00:26:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Process) Wait(pid *process.PID) error {
|
|
|
|
id, err := strconv.Atoi(pid.ID)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
pr, err := os.FindProcess(id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ps, err := pr.Wait()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if ps.Success() {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Errorf(ps.String())
|
|
|
|
}
|