util.go

 1package term
 2
 3import (
 4	"io"
 5	"runtime"
 6)
 7
 8// readPasswordLine reads from reader until it finds \n or io.EOF.
 9// The slice returned does not include the \n.
10// readPasswordLine also ignores any \r it finds.
11// Windows uses \r as end of line. So, on Windows, readPasswordLine
12// reads until it finds \r and ignores any \n it finds during processing.
13func readPasswordLine(reader io.Reader) ([]byte, error) {
14	var buf [1]byte
15	var ret []byte
16
17	for {
18		n, err := reader.Read(buf[:])
19		if n > 0 {
20			switch buf[0] {
21			case '\b':
22				if len(ret) > 0 {
23					ret = ret[:len(ret)-1]
24				}
25			case '\n':
26				if runtime.GOOS != "windows" {
27					return ret, nil
28				}
29				// otherwise ignore \n
30			case '\r':
31				if runtime.GOOS == "windows" {
32					return ret, nil
33				}
34				// otherwise ignore \r
35			default:
36				ret = append(ret, buf[0])
37			}
38			continue
39		}
40		if err != nil {
41			if err == io.EOF && len(ret) > 0 {
42				return ret, nil
43			}
44			return ret, err
45		}
46	}
47}