summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorAlexander Neumann <alexander@bumpern.de>2016-02-13 18:29:26 +0100
committerAlexander Neumann <alexander@bumpern.de>2016-02-13 18:29:26 +0100
commit1287b307ac198e12127c26cfc1f543b2cb80ef6a (patch)
tree0916ad1fb271496668c7c7680cd584dfe9c3ffed /cmd
parent24618305cc655246aefc6c627a6081883c77f037 (diff)
Add cleanup handler to restore terminal state
Closes #402
Diffstat (limited to 'cmd')
-rw-r--r--cmd/restic/global.go43
1 files changed, 43 insertions, 0 deletions
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)