mirror of
https://github.com/rclone/rclone.git
synced 2024-11-23 13:09:58 +08:00
8b8a943dd8
This patch will: - add --daemon-wait flag to control the time to wait for background mount - remove dependency on sevlyar/go-daemon and implement backgrounding directly - avoid setsid during backgrounding as it can result in race under Automount - provide a fallback PATH to correctly run `fusermount` under systemd as it runs mount units without standard environment variables - correctly handle ^C pressed while background process is being setting up
60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
// Daemonization interface for Unix platforms (implementation)
|
|
|
|
//go:build !windows && !plan9 && !js
|
|
// +build !windows,!plan9,!js
|
|
|
|
package daemonize
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
|
|
"github.com/rclone/rclone/fs"
|
|
)
|
|
|
|
// StartDaemon runs background twin of current process.
|
|
// It executes separate parts of code in child and parent processes.
|
|
// Returns child process pid in the parent or nil in the child.
|
|
// The method looks like a fork but safe for goroutines.
|
|
func StartDaemon(args []string) (*os.Process, error) {
|
|
if fs.IsDaemon() {
|
|
// This process is already daemonized
|
|
return nil, nil
|
|
}
|
|
|
|
env := append(os.Environ(), fs.DaemonMarkVar+"="+fs.DaemonMarkChild)
|
|
|
|
me, err := os.Executable()
|
|
if err != nil {
|
|
me = os.Args[0]
|
|
}
|
|
|
|
null, err := os.Open(os.DevNull)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
files := []*os.File{
|
|
null, // (0) stdin
|
|
null, // (1) stdout
|
|
null, // (2) stderr
|
|
}
|
|
sysAttr := &syscall.SysProcAttr{
|
|
// setsid (https://linux.die.net/man/2/setsid) in the child process will reset
|
|
// its process group id (PGID) to its PID thus detaching it from parent.
|
|
// This would make autofs fail because it detects mounting process by its PGID.
|
|
Setsid: false,
|
|
}
|
|
attr := &os.ProcAttr{
|
|
Env: env,
|
|
Files: files,
|
|
Sys: sysAttr,
|
|
}
|
|
|
|
daemon, err := os.StartProcess(me, args, attr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return daemon, nil
|
|
}
|