mirror of
https://github.com/octoleo/restic.git
synced 2024-12-22 02:48:55 +00:00
Allow cleanup handlers to filter the exit code
This commit is contained in:
parent
908f7441fe
commit
d768c1c3e4
@ -11,7 +11,7 @@ import (
|
||||
|
||||
var cleanupHandlers struct {
|
||||
sync.Mutex
|
||||
list []func() error
|
||||
list []func(code int) (int, error)
|
||||
done bool
|
||||
ch chan os.Signal
|
||||
}
|
||||
@ -25,7 +25,7 @@ func init() {
|
||||
// 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) {
|
||||
func AddCleanupHandler(f func(code int) (int, error)) {
|
||||
cleanupHandlers.Lock()
|
||||
defer cleanupHandlers.Unlock()
|
||||
|
||||
@ -36,22 +36,24 @@ func AddCleanupHandler(f func() error) {
|
||||
}
|
||||
|
||||
// RunCleanupHandlers runs all registered cleanup handlers
|
||||
func RunCleanupHandlers() {
|
||||
func RunCleanupHandlers(code int) int {
|
||||
cleanupHandlers.Lock()
|
||||
defer cleanupHandlers.Unlock()
|
||||
|
||||
if cleanupHandlers.done {
|
||||
return
|
||||
return code
|
||||
}
|
||||
cleanupHandlers.done = true
|
||||
|
||||
for _, f := range cleanupHandlers.list {
|
||||
err := f()
|
||||
var err error
|
||||
code, err = f(code)
|
||||
if err != nil {
|
||||
Warnf("error in cleanup handler: %v\n", err)
|
||||
}
|
||||
}
|
||||
cleanupHandlers.list = nil
|
||||
return code
|
||||
}
|
||||
|
||||
// CleanupHandler handles the SIGINT signals.
|
||||
@ -75,6 +77,6 @@ func CleanupHandler(c <-chan os.Signal) {
|
||||
// Exit runs the cleanup handlers and then terminates the process with the
|
||||
// given exit code.
|
||||
func Exit(code int) {
|
||||
RunCleanupHandlers()
|
||||
code = RunCleanupHandlers(code)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
@ -197,9 +197,9 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
cleanup := prepareCheckCache(opts, &gopts)
|
||||
AddCleanupHandler(func() error {
|
||||
AddCleanupHandler(func(code int) (int, error) {
|
||||
cleanup()
|
||||
return nil
|
||||
return code, nil
|
||||
})
|
||||
|
||||
repo, err := OpenRepository(gopts)
|
||||
|
@ -158,13 +158,13 @@ func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
AddCleanupHandler(func() error {
|
||||
AddCleanupHandler(func(code int) (int, error) {
|
||||
debug.Log("running umount cleanup handler for mount at %v", mountpoint)
|
||||
err := umount(mountpoint)
|
||||
if err != nil {
|
||||
Warnf("unable to umount (maybe already umounted or still in use?): %v\n", err)
|
||||
}
|
||||
return nil
|
||||
return code, nil
|
||||
})
|
||||
|
||||
c, err := systemFuse.Mount(mountpoint, mountOptions...)
|
||||
|
@ -97,11 +97,11 @@ var isReadingPassword bool
|
||||
func init() {
|
||||
var cancel context.CancelFunc
|
||||
globalOptions.ctx, cancel = context.WithCancel(context.Background())
|
||||
AddCleanupHandler(func() error {
|
||||
AddCleanupHandler(func(code int) (int, error) {
|
||||
// Must be called before the unlock cleanup handler to ensure that the latter is
|
||||
// not blocked due to limited number of backend connections, see #1434
|
||||
cancel()
|
||||
return nil
|
||||
return code, nil
|
||||
})
|
||||
|
||||
f := cmdRoot.PersistentFlags()
|
||||
@ -199,20 +199,20 @@ func restoreTerminal() {
|
||||
return
|
||||
}
|
||||
|
||||
AddCleanupHandler(func() error {
|
||||
AddCleanupHandler(func(code int) (int, error) {
|
||||
// Restoring the terminal configuration while restic runs in the
|
||||
// background, causes restic to get stopped on unix systems with
|
||||
// a SIGTTOU signal. Thus only restore the terminal settings if
|
||||
// they might have been modified, which is the case while reading
|
||||
// a password.
|
||||
if !isReadingPassword {
|
||||
return nil
|
||||
return code, nil
|
||||
}
|
||||
err := checkErrno(term.Restore(fd, state))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "unable to restore terminal state: %v\n", err)
|
||||
}
|
||||
return err
|
||||
return code, err
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,9 @@ func runDebug() error {
|
||||
}
|
||||
|
||||
if prof != nil {
|
||||
AddCleanupHandler(func() error {
|
||||
AddCleanupHandler(func(code int) (int, error) {
|
||||
prof.Stop()
|
||||
return nil
|
||||
return code, nil
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ func unlockRepo(lock *restic.Lock) {
|
||||
debug.Log("unable to find lock %v in the global list of locks, ignoring", lock)
|
||||
}
|
||||
|
||||
func unlockAll() error {
|
||||
func unlockAll(code int) (int, error) {
|
||||
globalLocks.Lock()
|
||||
defer globalLocks.Unlock()
|
||||
|
||||
@ -127,11 +127,11 @@ func unlockAll() error {
|
||||
for _, lock := range globalLocks.locks {
|
||||
if err := lock.Unlock(); err != nil {
|
||||
debug.Log("error while unlocking: %v", err)
|
||||
return err
|
||||
return code, err
|
||||
}
|
||||
debug.Log("successfully removed lock")
|
||||
}
|
||||
globalLocks.locks = globalLocks.locks[:0]
|
||||
|
||||
return nil
|
||||
return code, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user