From 1287b307ac198e12127c26cfc1f543b2cb80ef6a Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 13 Feb 2016 18:29:26 +0100 Subject: [PATCH] Add cleanup handler to restore terminal state Closes #402 --- cmd/restic/global.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 5d9875fce..09ce319ab 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -6,6 +6,7 @@ import ( "io" "os" "strings" + "syscall" "github.com/jessevdk/go-flags" "github.com/restic/restic/backend" @@ -34,6 +35,48 @@ type GlobalOptions struct { stderr io.Writer } +func init() { + restoreTerminal() +} + +// checkErrno returns nil when err is set to syscall.Errno(0), since this is no +// error condition. +func checkErrno(err error) error { + e, ok := err.(syscall.Errno) + if !ok { + return err + } + + if e == 0 { + return nil + } + + return err +} + +// restoreTerminal installs a cleanup handler that restores the previous +// terminal state on exit. +func restoreTerminal() { + fd := int(os.Stdout.Fd()) + if !terminal.IsTerminal(fd) { + return + } + + state, err := terminal.GetState(fd) + if err != nil { + fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err) + return + } + + AddCleanupHandler(func() error { + err := checkErrno(terminal.Restore(fd, state)) + if err != nil { + fmt.Fprintf(os.Stderr, "unable to get restore terminal state: %#+v\n", err) + } + return err + }) +} + var globalOpts = GlobalOptions{stdout: os.Stdout, stderr: os.Stderr} var parser = flags.NewParser(&globalOpts, flags.HelpFlag|flags.PassDoubleDash)