From dac89bf5443e8a0eaea65c9dbd82a0b7ef98c04e Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 19 Jul 2015 17:50:55 +0200 Subject: [PATCH 1/2] Allow more than one cleanup handler --- cmd/restic/cleanup.go | 59 +++++++++++++++++++++++++++++++++++++++++++ cmd/restic/lock.go | 18 +------------ 2 files changed, 60 insertions(+), 17 deletions(-) create mode 100644 cmd/restic/cleanup.go diff --git a/cmd/restic/cleanup.go b/cmd/restic/cleanup.go new file mode 100644 index 000000000..a29d45be4 --- /dev/null +++ b/cmd/restic/cleanup.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "os" + "os/signal" + "sync" + "syscall" + + "github.com/restic/restic/debug" +) + +var cleanupHandlers struct { + sync.Mutex + list []func() error +} + +var stderr = os.Stderr + +func init() { + c := make(chan os.Signal) + signal.Notify(c, syscall.SIGINT) + + go CleanupHandler(c) +} + +// AddCleanupHandler adds the function f to the list of cleanup handlers so +// that it is executed when all the cleanup handlers are run, e.g. when SIGINT +// is received. +func AddCleanupHandler(f func() error) { + cleanupHandlers.Lock() + defer cleanupHandlers.Unlock() + + cleanupHandlers.list = append(cleanupHandlers.list, f) +} + +// RunCleanupHandlers runs all registered cleanup handlers +func RunCleanupHandlers() { + cleanupHandlers.Lock() + defer cleanupHandlers.Unlock() + + for _, f := range cleanupHandlers.list { + err := f() + if err != nil { + fmt.Fprintf(stderr, "error in cleanup handler: %v\n", err) + } + } +} + +// CleanupHandler handles the SIGINT signal. +func CleanupHandler(c <-chan os.Signal) { + for s := range c { + debug.Log("CleanupHandler", "signal %v received, cleaning up", s) + fmt.Println("\x1b[2KInterrupt received, cleaning up") + RunCleanupHandlers() + fmt.Println("exiting") + os.Exit(0) + } +} diff --git a/cmd/restic/lock.go b/cmd/restic/lock.go index a5bdc3981..ec4368003 100644 --- a/cmd/restic/lock.go +++ b/cmd/restic/lock.go @@ -3,9 +3,7 @@ package main import ( "fmt" "os" - "os/signal" "sync" - "syscall" "time" "github.com/restic/restic" @@ -123,19 +121,5 @@ func unlockAll() error { } func init() { - c := make(chan os.Signal) - signal.Notify(c, syscall.SIGINT) - - go CleanupHandler(c) -} - -// CleanupHandler handles the SIGINT signal. -func CleanupHandler(c <-chan os.Signal) { - for s := range c { - debug.Log("CleanupHandler", "signal %v received, cleaning up", s) - fmt.Println("\x1b[2KInterrupt received, cleaning up") - unlockAll() - fmt.Println("exiting") - os.Exit(0) - } + AddCleanupHandler(unlockAll) } From 76817da922be684f4d7f6931088c27b188739b73 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 19 Jul 2015 17:57:18 +0200 Subject: [PATCH 2/2] Run cleanup handlers in main function --- cmd/restic/cleanup.go | 6 ++++++ cmd/restic/main.go | 2 ++ 2 files changed, 8 insertions(+) diff --git a/cmd/restic/cleanup.go b/cmd/restic/cleanup.go index a29d45be4..b4d4771d5 100644 --- a/cmd/restic/cleanup.go +++ b/cmd/restic/cleanup.go @@ -13,6 +13,7 @@ import ( var cleanupHandlers struct { sync.Mutex list []func() error + done bool } var stderr = os.Stderr @@ -39,6 +40,11 @@ func RunCleanupHandlers() { cleanupHandlers.Lock() defer cleanupHandlers.Unlock() + if cleanupHandlers.done { + return + } + cleanupHandlers.done = true + for _, f := range cleanupHandlers.list { err := f() if err != nil { diff --git a/cmd/restic/main.go b/cmd/restic/main.go index 3acab925e..a11bab84f 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -32,6 +32,8 @@ func main() { fmt.Fprintf(os.Stderr, "\nthe `unlock` command can be used to remove stale locks\n") } + RunCleanupHandlers() + if err != nil { os.Exit(1) }