1
0
mirror of https://github.com/go-micro/go-micro.git synced 2024-12-18 08:26:38 +02:00
go-micro/runtime/local/process/os/os.go

97 lines
1.6 KiB
Go
Raw Normal View History

2019-11-23 10:25:56 +02:00
// +build !windows
2019-05-31 01:26:34 +02:00
// Package os runs processes locally
package os
import (
"fmt"
"os"
"os/exec"
"strconv"
"syscall"
2019-05-31 01:26:34 +02:00
"github.com/micro/go-micro/v2/runtime/local/process"
2019-05-31 01:26:34 +02:00
)
func (p *Process) Exec(exe *process.Executable) error {
2019-11-19 18:09:43 +02:00
cmd := exec.Command(exe.Package.Path)
cmd.Dir = exe.Dir
2019-05-31 01:26:34 +02:00
return cmd.Run()
}
func (p *Process) Fork(exe *process.Executable) (*process.PID, error) {
2019-09-14 06:33:14 +02:00
// create command
2019-11-19 18:09:43 +02:00
cmd := exec.Command(exe.Package.Path, exe.Args...)
cmd.Dir = exe.Dir
2019-09-14 06:33:14 +02:00
// set env vars
cmd.Env = append(cmd.Env, os.Environ()...)
2019-09-14 06:33:14 +02:00
cmd.Env = append(cmd.Env, exe.Env...)
// create process group
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
2019-05-31 01:26:34 +02: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-14 06:33:14 +02:00
// start the process
if err := cmd.Start(); err != nil {
return nil, err
}
2019-05-31 01:26:34 +02: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
}
if _, err := os.FindProcess(id); err != nil {
2019-05-31 01:26:34 +02:00
return err
}
// now kill it
// using -ve PID kills the process group which we created in Fork()
return syscall.Kill(-id, syscall.SIGKILL)
2019-05-31 01:26:34 +02: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())
}