diff --git a/cmd/cmd.go b/cmd/cmd.go index ca7dcb47d..c71472904 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -471,6 +471,7 @@ func initConfig() { } func resolveExitCode(err error) { + atexit.Run() if err == nil { os.Exit(exitCodeSuccess) } diff --git a/cmd/mount/mount.go b/cmd/mount/mount.go index 93b43198a..e25799b8f 100644 --- a/cmd/mount/mount.go +++ b/cmd/mount/mount.go @@ -13,6 +13,7 @@ import ( fusefs "bazil.org/fuse/fs" "github.com/ncw/rclone/cmd/mountlib" "github.com/ncw/rclone/fs" + "github.com/ncw/rclone/lib/atexit" "github.com/ncw/rclone/vfs" "github.com/ncw/rclone/vfs/vfsflags" "github.com/okzk/sdnotify" @@ -133,6 +134,7 @@ func Mount(f fs.Fs, mountpoint string) error { signal.Notify(sigInt, syscall.SIGINT, syscall.SIGTERM) sigHup := make(chan os.Signal, 1) signal.Notify(sigHup, syscall.SIGHUP) + atexit.IgnoreSignals() if err := sdnotify.SdNotifyReady(); err != nil && err != sdnotify.SdNotifyNoSocket { return errors.Wrap(err, "failed to notify systemd") diff --git a/lib/atexit/atexit.go b/lib/atexit/atexit.go index 0f1bef969..8e44769d3 100644 --- a/lib/atexit/atexit.go +++ b/lib/atexit/atexit.go @@ -14,6 +14,7 @@ import ( var ( fns []func() + exitChan chan os.Signal exitOnce sync.Once registerOnce sync.Once ) @@ -24,10 +25,13 @@ func Register(fn func()) { // Run AtExit handlers on SIGINT or SIGTERM so everything gets // tidied up properly registerOnce.Do(func() { + exitChan = make(chan os.Signal, 1) + signal.Notify(exitChan, os.Interrupt) // syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT go func() { - ch := make(chan os.Signal, 1) - signal.Notify(ch, os.Interrupt) // syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT - sig := <-ch + sig, closed := <-exitChan + if closed { + return + } fs.Infof(nil, "Signal received: %s", sig) Run() fs.Infof(nil, "Exiting...") @@ -36,6 +40,16 @@ func Register(fn func()) { }) } +// IgnoreSignals disables the signal handler and prevents Run from beeing executed automatically +func IgnoreSignals() { + registerOnce.Do(func() {}) + if exitChan != nil { + signal.Stop(exitChan) + close(exitChan) + exitChan = nil + } +} + // Run all the at exit functions if they haven't been run already func Run() { exitOnce.Do(func() {