From 14115b061b253f3c58eee731e3b38dbb18fcf1fa Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 11 Oct 2015 18:02:48 +0200 Subject: Add native daemonization --- daemonize.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ main.go | 6 +++++- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 daemonize.go diff --git a/daemonize.go b/daemonize.go new file mode 100644 index 0000000..87faf33 --- /dev/null +++ b/daemonize.go @@ -0,0 +1,47 @@ +package main + +import ( + "syscall" + "os/exec" + "os" + "fmt" + "os/signal" +) + +// The child sends us USR1 if the mount was successful +func waitForUsr1() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGUSR1) + <-c + os.Exit(0) +} + +// daemonize - execute ourselves once again, this time with the "-f" flag, and +// wait for SIGUSR1. +func daemonize() { + go waitForUsr1() + name := os.Args[0] + newArgs := []string{"-f"} + newArgs = append(newArgs, os.Args[1:]...) + c := exec.Command(name, newArgs...) + c.Stdout = os.Stdout + c.Stderr = os.Stderr + c.Stdin = os.Stdin + err := c.Start() + if err != nil { + fmt.Printf("daemonize: starting %s failed: %v\n", name) + os.Exit(1) + } + err = c.Wait() + if err != nil { + if exiterr, ok := err.(*exec.ExitError); ok { + if waitstat, ok := exiterr.Sys().(syscall.WaitStatus); ok { + os.Exit(waitstat.ExitStatus()) + } + } + fmt.Printf("daemonize: wait returned an unknown error: %v\n", err) + os.Exit(1) + } + // The child exited with 0 - let's do the same. + os.Exit(0) +} diff --git a/main.go b/main.go index 89f3723..2d6da05 100644 --- a/main.go +++ b/main.go @@ -66,7 +66,7 @@ func main() { runtime.GOMAXPROCS(4) // Parse command line arguments - var debug, init, zerokey, fusedebug, openssl, passwd bool + var debug, init, zerokey, fusedebug, openssl, passwd, foreground bool var masterkey string flag.Usage = usageText @@ -76,10 +76,14 @@ func main() { flag.BoolVar(&zerokey, "zerokey", false, "Use all-zero dummy master key") flag.BoolVar(&openssl, "openssl", true, "Use OpenSSL instead of built-in Go crypto") flag.BoolVar(&passwd, "passwd", false, "Change password") + flag.BoolVar(&foreground, "f", false, "Stay in the foreground") flag.StringVar(&masterkey, "masterkey", "", "Mount with explicit master key") var cpuprofile = flag.String("cpuprofile", "", "Write cpu profile to specified file") flag.Parse() + if ! foreground { + daemonize() // does not return + } if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { -- cgit v1.2.3