diff --git a/next/main.go b/next/main.go new file mode 100644 index 0000000..ca1cb40 --- /dev/null +++ b/next/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "XProxy/next/process" + "time" +) + +func main() { + + //cmd := exec.Command("ls", "-al") + //cmd.Stdout = os.Stdout + //cmd.Stderr = os.Stderr + //err := cmd.Start() + //fmt.Println(err) + //err = cmd.Wait() + //fmt.Println(err) + + p := process.NewDaemon("demo", []string{"sleep", "3"}, map[string]string{"DEBUG": "TRUE"}) + p.Start() + + time.Sleep(10 * time.Second) + +} diff --git a/next/process/daemon.go b/next/process/daemon.go new file mode 100644 index 0000000..1b270e4 --- /dev/null +++ b/next/process/daemon.go @@ -0,0 +1,83 @@ +package process + +import ( + "fmt" + "os" + "os/exec" + "sync" +) + +const ( + Ready = iota // process ready to start + Running // process is running for now + Death // process exited and waiting for restart + Stopped // process has been stopped +) + +type Process struct { + name string + args []string + envs []string + mutex sync.Mutex + proc *exec.Cmd + status int +} + +func NewDaemon(name string, command []string, env map[string]string) *Process { + fmt.Printf("Create new daemon task %s -> %v %v\n", name, command, env) + var envs []string + for k, v := range env { + envs = append(envs, fmt.Sprintf("%s=%s", k, v)) + } + return &Process{ + name: name, + envs: envs, + args: command, + status: Ready, + } +} + +func (p *Process) boot() bool { + p.proc = exec.Command(p.args[0], p.args[1:]...) + p.proc.Stdout = os.Stdout + p.proc.Stderr = os.Stderr + if len(p.envs) != 0 { // with custom env variables + p.proc.Env = p.envs + } + err := p.proc.Start() + if err != nil { + fmt.Printf("Failed to boot process %s -> %v\n", p.name, err) + p.status = Stopped + return false + } + fmt.Printf("Successfully executed process %s -> PID = %d\n", p.name, p.proc.Process.Pid) + p.status = Running + return true +} + +func (p *Process) wait() { + for p.proc.ProcessState == nil { // wait until exit + p.proc.Wait() + } + fmt.Printf("Catch process %s exit", p.name) +} + +func (p *Process) Start() { + if !p.mutex.TryLock() { + fmt.Printf("already running") + return + } + + // TODO: daemon logical + p.boot() + p.wait() + +} + +func (p *Process) Status() int { + return p.status +} + +func (p *Process) Stop() { + // TODO: stop daemon and kill process +}