Слияние кода завершено, страница обновится автоматически
//+build !windows
package gitee
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
"golang.org/x/sys/unix"
)
func processIsRunning(pid int) error {
if err := syscall.Kill(pid, 0); err == syscall.ESRCH {
return err
}
return nil
}
func appForceExit(name string, pidfile string, pid int) error {
err := syscall.Kill(pid, syscall.SIGTERM)
if err != nil {
return fmt.Errorf("cannot kill %s[%d]", name, pid)
}
for i := 0; i < 50; i++ {
time.Sleep(100 * time.Millisecond)
if err := syscall.Kill(pid, 0); err != nil {
break
}
}
defer os.Remove(pidfile)
if err := syscall.Kill(pid, 0); err == nil {
_ = syscall.Kill(pid, syscall.SIGKILL)
return fmt.Errorf("Stop %s timeout", name)
}
return nil
}
// AppExit exit app
func AppExit(name string, pidfile string, force bool) error {
pid, err := AppIsRunningEx(pidfile)
if err != nil {
return fmt.Errorf("%s is not running", name)
}
_, err = os.FindProcess(pid)
if err != nil {
return fmt.Errorf("%s is not running", name)
}
if force {
return appForceExit(name, pidfile, pid)
}
if err := syscall.Kill(pid, syscall.SIGUSR1); err != nil {
fmt.Fprintf(os.Stderr, "unable kill \x1b[33m%s\x1b[33m[\x1b[33m%d\x1b[0m] error: \x1b[31m%v\x1b[0m\n", name, pid, err)
return err
}
_ = os.Remove(pidfile)
fmt.Fprintf(os.Stderr, "%s \x1b[32m%d\x1b[0m is stopped\n", name, pid)
return nil
}
// linux arm64 no dup2 syscall. golang/x/sys/unix use Dup3 impl
/*
func Dup2(oldfd int, newfd int) (err error) {
return Dup3(oldfd, newfd, 0)
}
golang.org/x/sys/unix/syscall_linux_arm64.go
*/
func appInitializeFD(stderr string) bool {
var stderrfile string
if len(stderr) == 0 {
stderrfile = os.DevNull
} else {
stderrfile = filepath.Clean(stderr)
}
file, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
if err != nil {
return false
}
defer file.Close()
fd := file.Fd()
_ = unix.Dup2(int(fd), int(os.Stdin.Fd()))
_ = unix.Dup2(int(fd), int(os.Stdout.Fd()))
if stderrfile == os.DevNull {
_ = unix.Dup2(int(fd), int(os.Stderr.Fd()))
return true
}
dir := filepath.Dir(stderr)
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
_ = os.MkdirAll(dir, 0776)
}
filestderr, err := os.OpenFile(stderr, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return false
}
_ = unix.Dup2(int(filestderr.Fd()), int(os.Stderr.Fd()))
filestderr.Close()
return true
}
// AppDaemonizedEx todo
func AppDaemonizedEx(name, pidfile, stderr string) error {
pid, err := AppIsRunningEx(pidfile)
if err == nil {
return fmt.Errorf("%s is running, pid=%d", name, pid)
}
ek := StrCat(strings.ToUpper(name), "_DAEMONIZED")
if os.Getenv(ek) != "" {
return AppImmobilized(pidfile)
}
wd, err := os.Getwd()
if err != nil {
wd, _ = filepath.Split(os.Args[0])
}
appInitializeFD(stderr)
files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
exe, _ := os.Executable()
sysattrs := syscall.SysProcAttr{Setsid: true}
env := append(os.Environ(), StrCat(ek, "=1"))
procAttr := &os.ProcAttr{
Dir: wd,
Env: env,
Sys: &sysattrs,
Files: files,
}
_, err = os.StartProcess(exe, os.Args, procAttr)
if err != nil {
os.Exit(1)
return err
}
os.Exit(0)
return nil
}
// AppRestart restart app
func AppRestart(name string, pidfile string, arg ...string) error {
pid, err := AppIsRunningEx(pidfile)
if err != nil {
return fmt.Errorf("%s is not running", name)
}
err = syscall.Kill(pid, syscall.SIGUSR1)
if err != nil {
return err
}
for i := 0; i < 100; i++ {
if syscall.Kill(pid, 0) != nil {
break
}
time.Sleep(1 * time.Millisecond)
}
_ = os.Remove(pidfile)
exe, err := os.Executable()
if err != nil {
return err
}
var cmd exec.Cmd
cmd.Path = exe
cmd.Args = append([]string{exe}, arg...)
err = cmd.Run()
if err != nil {
return err
}
return nil
}
// new app restart
// only send SIGUSR2
func NewAppRestart(name, pidfile string) error {
pid, err := AppIsRunningEx(pidfile)
if err != nil {
return fmt.Errorf("%s is not running", name)
}
return syscall.Kill(pid, syscall.SIGUSR2)
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )