Skip to content

Instantly share code, notes, and snippets.

@montanaflynn
Last active March 19, 2019 16:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save montanaflynn/5ae3eeae7212b0ba232f46e88f1ab67f to your computer and use it in GitHub Desktop.
Save montanaflynn/5ae3eeae7212b0ba232f46e88f1ab67f to your computer and use it in GitHub Desktop.
Watch for signals in terminal
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"golang.org/x/crypto/ssh/terminal"
)
func main() {
// check for ctrl-c signal
signalChan := make(chan os.Signal)
signal.Notify(signalChan, os.Interrupt)
go func() {
<-signalChan
os.Exit(1)
}()
// read password
p, err := terminal.ReadPassword(syscall.Stdin)
if err != nil {
panic(err)
}
// stop watching signals
signal.Stop(signalChan)
// print password
fmt.Println(string(p))
}
@FrontSide
Copy link

FrontSide commented Mar 19, 2019

Hey, thanks for this.
I gave it a try, unfortunately it still left my terminal in a bad state after issuing a Crtl+C while the prompt is open.
I was able to fix it by adding/amending the following:

// Get the state of the terminal before running the password prompt
originalTerminalState, err := terminal.GetState(int(syscall.Stdin))
if err != nil {
        os.Stderr.WriteString("Failed to get terminal state")
	os.Exit(1)
}

go func() {
        <-signalChan
        // Reset the terminal to the original state if a the user issues an interrupt
	terminal.Restore(int(syscall.Stdin), originalTerminalState)
	os.Exit(1)
}()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment