Hi,
Currently, terminal.ReadPassword has a defer function to "restore" the termios's initial state.
However, that defer gets not called when a SIGINT is fired. I'd argue that doing Ctrl+C is a common thing when the enduser is prompted something (especially a password).
How could we deal with that?
1. Handle signals within terminal package
2. Add a GetState() function so that the user of the package has the responsibility to deal with that case.
I did #2 and wanted some feedback from you. This is what I added to the terminal package on my local machine:
// GetState returns the state of the given terminal.
func GetState(fd int) (*State, error) {
var state State
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0); err != 0 {
return nil, err
}
return &state, nil
}
This way, one can just do the following:
fd := os.Stdin.Fd()
oldState, err := terminal.GetState(fd)
if err != nil {
panic("Could not get state of terminal: " + err.Error())
}
defer terminal.Restore(fd, oldState)
sigch := make(chan os.Signal, 1)
signal.Notify(sigch, os.Interrupt)
go func() {
for _ = range sigch {
terminal.Restore(fd, oldState)
os.Exit(1)
}
}()
p, err := terminal.ReadPassword(fd)
fmt.Println()
if err != nil {
panic("Failed to read password: " + err.Error())
}
// string(p) is now the password
What do you think?
Thanks,
Tibor