Skip to content

Commit 7d14375

Browse files
committed
Move xterminal to pty
1 parent 500695d commit 7d14375

File tree

6 files changed

+137
-104
lines changed

6 files changed

+137
-104
lines changed

cli/ssh.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ import (
2929
"cdr.dev/slog/sloggers/sloghuman"
3030
"github.com/coder/coder/v2/cli/cliui"
3131
"github.com/coder/coder/v2/cli/cliutil"
32-
"github.com/coder/coder/v2/cli/xterminal"
3332
"github.com/coder/coder/v2/coderd/autobuild/notify"
3433
"github.com/coder/coder/v2/coderd/util/ptr"
3534
"github.com/coder/coder/v2/codersdk"
3635
"github.com/coder/coder/v2/codersdk/workspacesdk"
3736
"github.com/coder/coder/v2/cryptorand"
37+
"github.com/coder/coder/v2/pty"
3838
"github.com/coder/retry"
3939
"github.com/coder/serpent"
4040
)
@@ -343,19 +343,19 @@ func (r *RootCmd) ssh() *serpent.Command {
343343
stdinFile, validIn := inv.Stdin.(*os.File)
344344
stdoutFile, validOut := inv.Stdout.(*os.File)
345345
if validIn && validOut && isatty.IsTerminal(stdinFile.Fd()) && isatty.IsTerminal(stdoutFile.Fd()) {
346-
inState, err := xterminal.MakeInputRaw(stdinFile.Fd())
346+
inState, err := pty.MakeInputRaw(stdinFile.Fd())
347347
if err != nil {
348348
return err
349349
}
350350
defer func() {
351-
_ = xterminal.Restore(stdinFile.Fd(), inState)
351+
_ = pty.RestoreTerminal(stdinFile.Fd(), inState)
352352
}()
353-
outState, err := xterminal.MakeOutputRaw(stdoutFile.Fd())
353+
outState, err := pty.MakeOutputRaw(stdoutFile.Fd())
354354
if err != nil {
355355
return err
356356
}
357357
defer func() {
358-
_ = xterminal.Restore(stdoutFile.Fd(), outState)
358+
_ = pty.RestoreTerminal(stdoutFile.Fd(), outState)
359359
}()
360360

361361
windowChange := listenWindowSize(ctx)

cli/xterminal/terminal.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

cli/xterminal/terminal_windows.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

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+
type TerminalState struct {
5+
state terminalState
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+
func MakeInputRaw(fd uintptr) (*TerminalState, error) {
14+
return makeInputRaw(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+
func MakeOutputRaw(fd uintptr) (*TerminalState, error) {
23+
return makeOutputRaw(fd)
24+
}
25+
26+
// RestoreTerminal restores the terminal back to its original state.
27+
//
28+
//nolint:revive
29+
func RestoreTerminal(fd uintptr, state *TerminalState) error {
30+
return restoreTerminal(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+
type terminalState *term.State
9+
10+
//nolint:revive
11+
func makeInputRaw(fd uintptr) (*TerminalState, error) {
12+
s, err := term.MakeRaw(int(fd))
13+
if err != nil {
14+
return nil, err
15+
}
16+
return &TerminalState{
17+
state: s,
18+
}, nil
19+
}
20+
21+
//nolint:revive
22+
func makeOutputRaw(_ 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+
func restoreTerminal(fd uintptr, state *TerminalState) error {
31+
if state == nil || state.state == nil {
32+
return nil
33+
}
34+
35+
return term.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+
type terminalState uint32
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+
func makeRaw(handle windows.Handle, input bool) (uint32, error) {
19+
var prevState uint32
20+
if err := windows.GetConsoleMode(handle, &prevState); err != nil {
21+
return 0, err
22+
}
23+
24+
var raw uint32
25+
if input {
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+
if err := windows.SetConsoleMode(handle, raw); err != nil {
33+
return 0, err
34+
}
35+
return prevState, nil
36+
}
37+
38+
//nolint:revive
39+
func makeInputRaw(handle uintptr) (*TerminalState, error) {
40+
prevState, err := makeRaw(windows.Handle(handle), true)
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
return &TerminalState{
46+
state: terminalState(prevState),
47+
}, nil
48+
}
49+
50+
//nolint:revive
51+
func makeOutputRaw(handle uintptr) (*TerminalState, error) {
52+
prevState, err := makeRaw(windows.Handle(handle), false)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return &TerminalState{
58+
state: terminalState(prevState),
59+
}, nil
60+
}
61+
62+
//nolint:revive
63+
func restoreTerminal(handle uintptr, state *TerminalState) error {
64+
return windows.SetConsoleMode(windows.Handle(handle), uint32(state.state))
65+
}

0 commit comments

Comments
 (0)