From e1ca8a8148f46b28dfa319d209c0d28d9ceb21aa Mon Sep 17 00:00:00 2001 From: chenjia404 Date: Sat, 29 Apr 2023 13:44:44 +0800 Subject: [PATCH] =?UTF-8?q?0.0.2:=E5=A2=9E=E5=8A=A0=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E5=AE=88=E6=8A=A4=EF=BC=8C=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E9=87=8A=E6=94=BE=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 42 ++++++++++- pRuntime/pRuntime.go | 169 +++++++++++++++++++++++++++++++++++++++++++ pRuntime/proc.go | 47 ++++++++++++ 3 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 pRuntime/pRuntime.go create mode 100644 pRuntime/proc.go diff --git a/main.go b/main.go index bc5e698..ded00d9 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "runtime" "time" + "github.com/chenjia404/go-p2ptunnel/pRuntime" "github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peerstore" @@ -191,7 +192,7 @@ func createLibp2pHost(ctx context.Context, priv crypto.PrivKey) (host.Host, erro } var ( - version = "0.0.1" + version = "0.0.2" gitRev = "" buildTime = "" ) @@ -207,6 +208,45 @@ func main() { networkType := flag.String("type", "tcp", "network type tcp/udp") flag.Parse() +RE: + proc, err := pRuntime.NewProc() + if err != nil { + fmt.Println("up proc fail........") + } + //如果proc为nil表示当前进程已经是子进程了 + //不为空表示当前进程为主进程 + if proc != nil { + go func() { + pRuntime.HandleEndSignal(func() { + if err := proc.Kill(); err != nil { + fmt.Println(err) + } + fmt.Println("main proc exit....") + + os.Exit(0) + }) + }() + //等待子进程退出后 重启 + err = proc.Wait() + if err != nil { + fmt.Println("proc wait err........") + } else { + goto RE + } + return + } else { + + go func() { + now := time.Now() + next := now.Add(time.Hour * 4) + timer := time.NewTimer(next.Sub(now)) + t := <-timer.C //从定时器拿数据 + fmt.Println("restart time:", t) + os.Exit(0) + }() + + } + ctx, cancel := context.WithCancel(context.Background()) priv, _ := loadUserPrivKey() diff --git a/pRuntime/pRuntime.go b/pRuntime/pRuntime.go new file mode 100644 index 0000000..ca60f0b --- /dev/null +++ b/pRuntime/pRuntime.go @@ -0,0 +1,169 @@ +package pRuntime + +import ( + "errors" + "io/ioutil" + "log" + "os" + "os/exec" + "os/signal" + "runtime" + "strconv" + "syscall" +) + +var pidFile = "go-p2ptunnel.pid" + +func SetPidFile(pFile string) { + pidFile = pFile +} + +func forkDaemon(isWritePidFile bool, environ ...string) (*exec.Cmd, error) { + cmdRet := &exec.Cmd{ + Path: os.Args[0], + Args: os.Args, + Stdin: os.Stdin, + Stdout: os.Stdout, + Stderr: os.Stderr, + Env: append(os.Environ(), environ...), + } + err := cmdRet.Start() + if err != nil { + return nil, err + } + //写入pid + if isWritePidFile { + err = ioutil.WriteFile(pidFile, []byte(strconv.Itoa(cmdRet.Process.Pid)), 0666) + } + if err != nil { + return nil, err + } + return cmdRet, nil +} + +func DaemonInit() { + if runtime.GOOS == "windows" { + return + } + if os.Getenv("__Daemon") == "true" { + return + } + c := "start" + if l := len(os.Args); l > 1 { + c = os.Args[l-1] + } + switch c { + case "start": + if CheckProIsRun() { + log.Fatal("当前进程已运行...") + } + cmdRet, err := forkDaemon(true, "__Daemon=true") + if err != nil { + log.Fatal("start err : ", err) + } + log.Println("Daemon is run... pid: ", cmdRet.Process.Pid) + case "restart": + err := Stop() + if err != nil { + log.Fatal("restart stop err : ", err) + } + os.Args = os.Args[:len(os.Args)-1] + cmdRet, err := forkDaemon(true, "__Daemon=true") + if err != nil { + log.Fatal("forkDaemon err : ", err) + } + log.Println("Daemon is run... pid: ", cmdRet.Process.Pid) + case "stop": + err := Stop() + if err != nil { + log.Fatal("stop err : ", err) + } + log.Println("Daemon is stop....") + case "reload": + err := Reload() + if err != nil { + log.Fatal("reload err : ", err) + } + log.Println("Daemon reload success....") + } + os.Exit(0) +} + +func CheckProIsRun() bool { + if GetRunningPid() == 0 { + return false + } + return true +} + +func FileExists(path string) bool { + _, err := os.Stat(path) //os.Stat获取文件信息 + if err != nil { + if os.IsExist(err) { + return true + } + return false + } + return true +} + +func GetRunningPid() int { + if !FileExists(pidFile) { + return 0 + } + b, err := ioutil.ReadFile(pidFile) + if err != nil { + log.Fatal("程序异常:", err) + } + pid, _ := strconv.Atoi(string(b)) + p, err := os.FindProcess(pid) + if err != nil { + return 0 + } + err = p.Signal(syscall.Signal(0)) + if err == nil { + return p.Pid + } + _ = os.Remove(pidFile) + return 0 +} + +func HandleEndSignal(fn func()) { + sig := make(chan os.Signal) + signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) + <-sig + _ = os.Remove(pidFile) + fn() + return +} + +func HandleReloadSignal(fn func()) { + sig := make(chan os.Signal) + signal.Notify(sig, syscall.SIGHUP) + for { + <-sig + fn() + } +} + +func Stop() error { + if !CheckProIsRun() { + return errors.New("进程没有运行") + } + pro, err := os.FindProcess(GetRunningPid()) + if err != nil { + return err + } + return pro.Signal(syscall.SIGTERM) +} + +func Reload() error { + if !CheckProIsRun() { + return errors.New("进程没有运行") + } + pro, err := os.FindProcess(GetRunningPid()) + if err != nil { + return err + } + return pro.Signal(syscall.SIGHUP) +} diff --git a/pRuntime/proc.go b/pRuntime/proc.go new file mode 100644 index 0000000..c6506cf --- /dev/null +++ b/pRuntime/proc.go @@ -0,0 +1,47 @@ +package pRuntime + +import ( + "fmt" + "os" +) + +type Proc struct { + proc *os.Process + procState *os.ProcessState +} + +func NewProc() (*Proc, error) { + if os.Getenv("__NewProc") == "true" { + return nil, nil + } + cmdRet, err := forkDaemon(false, "__NewProc=true") + if err != nil { + return nil, err + } + return &Proc{ + proc: cmdRet.Process, + }, nil +} + +func (p *Proc) Pid() int { + if p.proc == nil { + return 0 + } + return p.proc.Pid +} + +func (p *Proc) Kill() error { + if p.proc == nil { + return fmt.Errorf("proc is null") + } + return p.proc.Kill() +} + +func (p *Proc) Wait() error { + var err error + p.procState, err = p.proc.Wait() + if err != nil { + return err + } + return nil +}