Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(121)

Delta Between Two Patch Sets: ssh/terminal/util.go

Issue 7286043: code review 7286043: ssh/terminal: add darwin support. (Closed)
Left Patch Set: diff -r 7eef55bbd51c https://code.google.com/p/go.crypto Created 11 years, 1 month ago
Right Patch Set: diff -r 7eef55bbd51c https://code.google.com/p/go.crypto/ Created 11 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | ssh/terminal/util_bsd.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // +build linux,!appengine darwin 5 // +build linux,!appengine darwin
6 6
7 // Package terminal provides support functions for dealing with terminals, as 7 // Package terminal provides support functions for dealing with terminals, as
8 // commonly found on UNIX systems. 8 // commonly found on UNIX systems.
9 // 9 //
10 // Putting a terminal into raw mode is the most common requirement: 10 // Putting a terminal into raw mode is the most common requirement:
(...skipping 11 matching lines...) Expand all
22 "unsafe" 22 "unsafe"
23 ) 23 )
24 24
25 // State contains the state of a terminal. 25 // State contains the state of a terminal.
26 type State struct { 26 type State struct {
27 termios syscall.Termios 27 termios syscall.Termios
28 } 28 }
29 29
30 // IsTerminal returns true if the given file descriptor is a terminal. 30 // IsTerminal returns true if the given file descriptor is a terminal.
31 func IsTerminal(fd int) bool { 31 func IsTerminal(fd int) bool {
32 » _, err := tcgetattr(fd) 32 » var termios syscall.Termios
33 » return err == nil 33 » _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadT ermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
34 » return err == 0
34 } 35 }
35 36
36 // MakeRaw put the terminal connected to the given file descriptor into raw 37 // MakeRaw put the terminal connected to the given file descriptor into raw
37 // mode and returns the previous state of the terminal so that it can be 38 // mode and returns the previous state of the terminal so that it can be
38 // restored. 39 // restored.
39 func MakeRaw(fd int) (*State, error) { 40 func MakeRaw(fd int) (*State, error) {
40 var oldState State 41 var oldState State
41 » termios, err := tcgetattr(fd) 42 » if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlRe adTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
42 » if err != nil {
43 return nil, err 43 return nil, err
44 } 44 }
45 oldState.termios = *termios
46 45
47 » termios.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | sysca ll.IGNCR | syscall.IXON | syscall.IXOFF 46 » newState := oldState.termios
48 » termios.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG 47 » newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | sysc all.IGNCR | syscall.IXON | syscall.IXOFF
49 » if err := tcsetattr(fd, termios); err != nil { 48 » newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
49 » if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWr iteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
50 return nil, err 50 return nil, err
51 } 51 }
52
52 return &oldState, nil 53 return &oldState, nil
53 } 54 }
54 55
55 // GetState returns the current state of a terminal which may be useful to 56 // GetState returns the current state of a terminal which may be useful to
56 // restore the terminal after a signal. 57 // restore the terminal after a signal.
57 func GetState(fd int) (*State, error) { 58 func GetState(fd int) (*State, error) {
58 var oldState State 59 var oldState State
59 » termios, err := tcgetattr(fd) 60 » if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlRe adTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
60 » if err != nil {
61 return nil, err 61 return nil, err
62 } 62 }
63 » oldState.termios = *termios 63
64 return &oldState, nil 64 return &oldState, nil
65 } 65 }
66 66
67 // Restore restores the terminal connected to the given file descriptor to a 67 // Restore restores the terminal connected to the given file descriptor to a
68 // previous state. 68 // previous state.
69 func Restore(fd int, state *State) error { 69 func Restore(fd int, state *State) error {
70 » return tcsetattr(fd, &state.termios) 70 » _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWrite Termios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
71 » return err
71 } 72 }
72 73
73 // GetSize returns the dimensions of the given terminal. 74 // GetSize returns the dimensions of the given terminal.
74 func GetSize(fd int) (width, height int, err error) { 75 func GetSize(fd int) (width, height int, err error) {
75 var dimensions [4]uint16 76 var dimensions [4]uint16
76 77
77 if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr (syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { 78 if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr (syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
78 return -1, -1, err 79 return -1, -1, err
79 } 80 }
80 return int(dimensions[1]), int(dimensions[0]), nil 81 return int(dimensions[1]), int(dimensions[0]), nil
81 } 82 }
82 83
83 // ReadPassword reads a line of input from a terminal without local echo. This 84 // ReadPassword reads a line of input from a terminal without local echo. This
84 // is commonly used for inputting passwords and other sensitive data. The slice 85 // is commonly used for inputting passwords and other sensitive data. The slice
85 // returned does not include the \n. 86 // returned does not include the \n.
86 func ReadPassword(fd int) ([]byte, error) { 87 func ReadPassword(fd int) ([]byte, error) {
87 » oldState, err := tcgetattr(fd) 88 » var oldState syscall.Termios
88 » if err != nil { 89 » if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlRe adTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
89 return nil, err 90 return nil, err
90 } 91 }
91 92
92 » newState := *oldState 93 » newState := oldState
93 newState.Lflag &^= syscall.ECHO 94 newState.Lflag &^= syscall.ECHO
94 newState.Lflag |= syscall.ICANON | syscall.ISIG 95 newState.Lflag |= syscall.ICANON | syscall.ISIG
95 newState.Iflag |= syscall.ICRNL 96 newState.Iflag |= syscall.ICRNL
96 » if err := tcsetattr(fd, &newState); err != nil { 97 » if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWr iteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
97 return nil, err 98 return nil, err
98 } 99 }
99 100
100 defer func() { 101 defer func() {
101 » » tcsetattr(fd, oldState) 102 » » syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermi os, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
102 }() 103 }()
103 104
104 var buf [16]byte 105 var buf [16]byte
105 var ret []byte 106 var ret []byte
106 for { 107 for {
107 n, err := syscall.Read(fd, buf[:]) 108 n, err := syscall.Read(fd, buf[:])
108 if err != nil { 109 if err != nil {
109 return nil, err 110 return nil, err
110 } 111 }
111 if n == 0 { 112 if n == 0 {
112 if len(ret) == 0 { 113 if len(ret) == 0 {
113 return nil, io.EOF 114 return nil, io.EOF
114 } 115 }
115 break 116 break
116 } 117 }
117 if buf[n-1] == '\n' { 118 if buf[n-1] == '\n' {
118 n-- 119 n--
119 } 120 }
120 ret = append(ret, buf[:n]...) 121 ret = append(ret, buf[:n]...)
121 if n < len(buf) { 122 if n < len(buf) {
122 break 123 break
123 } 124 }
124 } 125 }
125 126
126 return ret, nil 127 return ret, nil
127 } 128 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b