Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd426569

Browse files
authored
fix: make terminal raw in ssh command on windows (#12990)
1 parent9219044 commitd426569

File tree

4 files changed

+146
-8
lines changed

4 files changed

+146
-8
lines changed

‎cli/ssh.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ import (
2525
"golang.org/x/xerrors"
2626
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
2727

28-
"github.com/coder/retry"
29-
"github.com/coder/serpent"
30-
3128
"cdr.dev/slog"
3229
"cdr.dev/slog/sloggers/sloghuman"
33-
3430
"github.com/coder/coder/v2/cli/cliui"
3531
"github.com/coder/coder/v2/cli/cliutil"
3632
"github.com/coder/coder/v2/coderd/autobuild/notify"
3733
"github.com/coder/coder/v2/coderd/util/ptr"
3834
"github.com/coder/coder/v2/codersdk"
3935
"github.com/coder/coder/v2/codersdk/workspacesdk"
4036
"github.com/coder/coder/v2/cryptorand"
37+
"github.com/coder/coder/v2/pty"
38+
"github.com/coder/retry"
39+
"github.com/coder/serpent"
4140
)
4241

4342
var (
@@ -341,15 +340,22 @@ func (r *RootCmd) ssh() *serpent.Command {
341340
}
342341
}
343342

344-
stdoutFile,validOut:=inv.Stdout.(*os.File)
345343
stdinFile,validIn:=inv.Stdin.(*os.File)
346-
ifvalidOut&&validIn&&isatty.IsTerminal(stdoutFile.Fd()) {
347-
state,err:=term.MakeRaw(int(stdinFile.Fd()))
344+
stdoutFile,validOut:=inv.Stdout.(*os.File)
345+
ifvalidIn&&validOut&&isatty.IsTerminal(stdinFile.Fd())&&isatty.IsTerminal(stdoutFile.Fd()) {
346+
inState,err:=pty.MakeInputRaw(stdinFile.Fd())
347+
iferr!=nil {
348+
returnerr
349+
}
350+
deferfunc() {
351+
_=pty.RestoreTerminal(stdinFile.Fd(),inState)
352+
}()
353+
outState,err:=pty.MakeOutputRaw(stdoutFile.Fd())
348354
iferr!=nil {
349355
returnerr
350356
}
351357
deferfunc() {
352-
_=term.Restore(int(stdinFile.Fd()),state)
358+
_=pty.RestoreTerminal(stdoutFile.Fd(),outState)
353359
}()
354360

355361
windowChange:=listenWindowSize(ctx)

‎pty/terminal.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package pty
2+
3+
// TerminalState differs per-platform.
4+
typeTerminalStatestruct {
5+
stateterminalState
6+
}
7+
8+
// MakeInputRaw calls term.MakeRaw on non-Windows platforms. On Windows it sets
9+
// special terminal modes that enable VT100 emulation as well as setting the
10+
// same modes that term.MakeRaw sets.
11+
//
12+
//nolint:revive
13+
funcMakeInputRaw(fduintptr) (*TerminalState,error) {
14+
returnmakeInputRaw(fd)
15+
}
16+
17+
// MakeOutputRaw does nothing on non-Windows platforms. On Windows it sets
18+
// special terminal modes that enable VT100 emulation as well as setting the
19+
// same modes that term.MakeRaw sets.
20+
//
21+
//nolint:revive
22+
funcMakeOutputRaw(fduintptr) (*TerminalState,error) {
23+
returnmakeOutputRaw(fd)
24+
}
25+
26+
// RestoreTerminal restores the terminal back to its original state.
27+
//
28+
//nolint:revive
29+
funcRestoreTerminal(fduintptr,state*TerminalState)error {
30+
returnrestoreTerminal(fd,state)
31+
}

‎pty/terminal_other.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package pty
5+
6+
import"golang.org/x/term"
7+
8+
typeterminalState*term.State
9+
10+
//nolint:revive
11+
funcmakeInputRaw(fduintptr) (*TerminalState,error) {
12+
s,err:=term.MakeRaw(int(fd))
13+
iferr!=nil {
14+
returnnil,err
15+
}
16+
return&TerminalState{
17+
state:s,
18+
},nil
19+
}
20+
21+
//nolint:revive
22+
funcmakeOutputRaw(_uintptr) (*TerminalState,error) {
23+
// Does nothing. makeInputRaw does enough for both input and output.
24+
return&TerminalState{
25+
state:nil,
26+
},nil
27+
}
28+
29+
//nolint:revive
30+
funcrestoreTerminal(fduintptr,state*TerminalState)error {
31+
ifstate==nil||state.state==nil {
32+
returnnil
33+
}
34+
35+
returnterm.Restore(int(fd),state.state)
36+
}

‎pty/terminal_windows.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package pty
5+
6+
import"golang.org/x/sys/windows"
7+
8+
typeterminalStateuint32
9+
10+
// This is adapted from term.MakeRaw, but adds
11+
// ENABLE_VIRTUAL_TERMINAL_PROCESSING to the output mode and
12+
// ENABLE_VIRTUAL_TERMINAL_INPUT to the input mode.
13+
//
14+
// See: https://github.com/golang/term/blob/5b15d269ba1f54e8da86c8aa5574253aea0c2198/term_windows.go#L23
15+
//
16+
// Copyright 2019 The Go Authors. BSD-3-Clause license. See:
17+
// https://github.com/golang/term/blob/master/LICENSE
18+
funcmakeRaw(handle windows.Handle,inputbool) (uint32,error) {
19+
varprevStateuint32
20+
iferr:=windows.GetConsoleMode(handle,&prevState);err!=nil {
21+
return0,err
22+
}
23+
24+
varrawuint32
25+
ifinput {
26+
raw=prevState &^ (windows.ENABLE_ECHO_INPUT|windows.ENABLE_PROCESSED_INPUT|windows.ENABLE_LINE_INPUT|windows.ENABLE_PROCESSED_OUTPUT)
27+
raw|=windows.ENABLE_VIRTUAL_TERMINAL_INPUT
28+
}else {
29+
raw=prevState|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
30+
}
31+
32+
iferr:=windows.SetConsoleMode(handle,raw);err!=nil {
33+
return0,err
34+
}
35+
returnprevState,nil
36+
}
37+
38+
//nolint:revive
39+
funcmakeInputRaw(handleuintptr) (*TerminalState,error) {
40+
prevState,err:=makeRaw(windows.Handle(handle),true)
41+
iferr!=nil {
42+
returnnil,err
43+
}
44+
45+
return&TerminalState{
46+
state:terminalState(prevState),
47+
},nil
48+
}
49+
50+
//nolint:revive
51+
funcmakeOutputRaw(handleuintptr) (*TerminalState,error) {
52+
prevState,err:=makeRaw(windows.Handle(handle),false)
53+
iferr!=nil {
54+
returnnil,err
55+
}
56+
57+
return&TerminalState{
58+
state:terminalState(prevState),
59+
},nil
60+
}
61+
62+
//nolint:revive
63+
funcrestoreTerminal(handleuintptr,state*TerminalState)error {
64+
returnwindows.SetConsoleMode(windows.Handle(handle),uint32(state.state))
65+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp