rclone/vendor/github.com/sevlyar/go-daemon/oldapi/daemon_posix.go

89 lines
1.8 KiB
Go

// Package daemon provides function to daemonization processes.
// And such as the handling of system signals and the pid-file creation.
package daemon
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"syscall"
)
const (
envVarName = "_GO_DAEMON"
envVarValue = "1"
)
// func Reborn daemonize process. Function Reborn calls ForkExec
// in the parent process and terminates him. In the child process,
// function sets umask, work dir and calls Setsid. Function sets
// for child process environment variable _GO_DAEMON=1 - the mark,
// might used for debug.
func Reborn(umask uint32, workDir string) (err error) {
if !WasReborn() {
// parent process - fork and exec
var path string
if path, err = filepath.Abs(os.Args[0]); err != nil {
return
}
cmd := prepareCommand(path)
if err = cmd.Start(); err != nil {
return
}
os.Exit(0)
}
// child process - daemon
syscall.Umask(int(umask))
if len(workDir) != 0 {
if err = os.Chdir(workDir); err != nil {
return
}
}
_, err = syscall.Setsid()
// Do not required redirect std
// to /dev/null, this work was
// done function ForkExec
return
}
// func WasReborn, return true if the process has environment
// variable _GO_DAEMON=1 (child process).
func WasReborn() bool {
return os.Getenv(envVarName) == envVarValue
}
func prepareCommand(path string) (cmd *exec.Cmd) {
// prepare command-line arguments
cmd = exec.Command(path, os.Args[1:]...)
// prepare environment variables
envVar := fmt.Sprintf("%s=%s", envVarName, envVarValue)
cmd.Env = append(os.Environ(), envVar)
return
}
// func RedirectStream redirects file s to file target.
func RedirectStream(s, target *os.File) (err error) {
stdoutFd := int(s.Fd())
if err = syscall.Close(stdoutFd); err != nil {
return
}
err = syscall.Dup2(int(target.Fd()), stdoutFd)
return
}