Skip to content

Commit 7effd64

Browse files
committed
ssh/terminal: store termios copy in terminal state on Solaris
TestMakeRawState currently fails on Solaris: --- FAIL: TestMakeRawState (0.00s) terminal_test.go:334: states do not match; was &{0xc420015dd0}, expected &{0xc420015da0} Change terminal.State to include a copy to the unix.Termios (like the implementation for Linux and the BSDs) which also makes terminal.MakeRaw behave as expected and lets TestMakeRawState pass. Change-Id: I29382f83b84ff301991e1db170f32f41e144aec8 Reviewed-on: https://go-review.googlesource.com/99456 Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 526a373 commit 7effd64

File tree

1 file changed

+18
-22
lines changed

1 file changed

+18
-22
lines changed

ssh/terminal/util_solaris.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
// State contains the state of a terminal.
1616
type State struct {
17-
state *unix.Termios
17+
termios unix.Termios
1818
}
1919

2020
// IsTerminal returns true if the given file descriptor is a terminal.
@@ -75,47 +75,43 @@ func ReadPassword(fd int) ([]byte, error) {
7575
// restored.
7676
// see http://cr.illumos.org/~webrev/andy_js/1060/
7777
func MakeRaw(fd int) (*State, error) {
78-
oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
78+
termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
7979
if err != nil {
8080
return nil, err
8181
}
82-
oldTermios := *oldTermiosPtr
83-
84-
newTermios := oldTermios
85-
newTermios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
86-
newTermios.Oflag &^= syscall.OPOST
87-
newTermios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
88-
newTermios.Cflag &^= syscall.CSIZE | syscall.PARENB
89-
newTermios.Cflag |= syscall.CS8
90-
newTermios.Cc[unix.VMIN] = 1
91-
newTermios.Cc[unix.VTIME] = 0
92-
93-
if err := unix.IoctlSetTermios(fd, unix.TCSETS, &newTermios); err != nil {
82+
83+
oldState := State{termios: *termios}
84+
85+
termios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON
86+
termios.Oflag &^= unix.OPOST
87+
termios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN
88+
termios.Cflag &^= unix.CSIZE | unix.PARENB
89+
termios.Cflag |= unix.CS8
90+
termios.Cc[unix.VMIN] = 1
91+
termios.Cc[unix.VTIME] = 0
92+
93+
if err := unix.IoctlSetTermios(fd, unix.TCSETS, termios); err != nil {
9494
return nil, err
9595
}
9696

97-
return &State{
98-
state: oldTermiosPtr,
99-
}, nil
97+
return &oldState, nil
10098
}
10199

102100
// Restore restores the terminal connected to the given file descriptor to a
103101
// previous state.
104102
func Restore(fd int, oldState *State) error {
105-
return unix.IoctlSetTermios(fd, unix.TCSETS, oldState.state)
103+
return unix.IoctlSetTermios(fd, unix.TCSETS, &oldState.termios)
106104
}
107105

108106
// GetState returns the current state of a terminal which may be useful to
109107
// restore the terminal after a signal.
110108
func GetState(fd int) (*State, error) {
111-
oldTermiosPtr, err := unix.IoctlGetTermios(fd, unix.TCGETS)
109+
termios, err := unix.IoctlGetTermios(fd, unix.TCGETS)
112110
if err != nil {
113111
return nil, err
114112
}
115113

116-
return &State{
117-
state: oldTermiosPtr,
118-
}, nil
114+
return &State{termios: *termios}, nil
119115
}
120116

121117
// GetSize returns the dimensions of the given terminal.

0 commit comments

Comments
 (0)