113 lines
2.2 KiB
Go
113 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
)
|
|
|
|
type DaemonExec struct {
|
|
cmd *exec.Cmd
|
|
lockFile string
|
|
running bool
|
|
}
|
|
|
|
func NewDaemonExec(cmd []string, lockFile string) *DaemonExec {
|
|
if lockFile == "" {
|
|
lockFile = ".tmp.daemon.lock"
|
|
}
|
|
return &DaemonExec{
|
|
cmd: exec.Command(cmd[0], cmd[1:]...),
|
|
lockFile: lockFile,
|
|
}
|
|
}
|
|
|
|
func (d *DaemonExec) Start() error {
|
|
if d.cmd == nil {
|
|
return fmt.Errorf("cmd is nil")
|
|
}
|
|
|
|
d.cmd.Stdout = os.Stdout
|
|
d.cmd.Stderr = os.Stderr
|
|
|
|
err := d.cmd.Start()
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("start cmd failed: %v", err)
|
|
}
|
|
|
|
err = ioutil.WriteFile(d.lockFile, []byte(
|
|
fmt.Sprintf("%d", d.cmd.Process.Pid)), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("write lock file failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *DaemonExec) Kill() error {
|
|
if d.cmd == nil {
|
|
return fmt.Errorf("cmd is nil")
|
|
}
|
|
err := d.cmd.Process.Kill()
|
|
if err != nil {
|
|
return fmt.Errorf("kill cmd failed: %v", err)
|
|
}
|
|
err = os.Remove(d.lockFile)
|
|
if err != nil {
|
|
return fmt.Errorf("remove lock file failed: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *DaemonExec) RunWithExec(cmd []string) error {
|
|
if d.running {
|
|
return fmt.Errorf("daemon is running")
|
|
}
|
|
|
|
d.cmd = exec.Command(cmd[0], cmd[1:]...)
|
|
|
|
err := d.cmd.Start()
|
|
if err != nil {
|
|
return fmt.Errorf("start cmd failed: %v", err)
|
|
}
|
|
|
|
for {
|
|
if d.cmd.ProcessState != nil {
|
|
break
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
fmt.Printf("Usage: %s [command]\n", os.Args[0])
|
|
os.Exit(1)
|
|
}
|
|
d := NewDaemonExec(os.Args[1:], "")
|
|
err := d.Start()
|
|
if err != nil {
|
|
fmt.Printf("start daemon failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("start daemon success\n")
|
|
|
|
fmt.Println("press any key to kill daemon")
|
|
|
|
var s string
|
|
_, err = fmt.Scanln(&s)
|
|
if err != nil {
|
|
fmt.Printf("scan input failed: %v\n", err)
|
|
}
|
|
|
|
err = d.Kill()
|
|
if err != nil {
|
|
fmt.Printf("kill daemon failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("kill daemon success\n")
|
|
|
|
}
|