Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d1405c

Browse files
committed
Vendor conpty as well
1 parent 03ea70c commit 2d1405c

File tree

3 files changed

+144
-1
lines changed

3 files changed

+144
-1
lines changed

expect/conpty/conpty.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// +build windows
2+
3+
// Original copyright 2020 ActiveState Software. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file
6+
7+
package conpty
8+
9+
import (
10+
"fmt"
11+
"os"
12+
13+
"golang.org/x/sys/windows"
14+
)
15+
16+
// ConPty represents a windows pseudo console.
17+
type ConPty struct {
18+
hpCon windows.Handle
19+
pipeFdIn windows.Handle
20+
pipeFdOut windows.Handle
21+
consoleSize uintptr
22+
inPipe *os.File
23+
outPipe *os.File
24+
}
25+
26+
// New returns a new ConPty pseudo terminal device
27+
func New(columns int16, rows int16) (*ConPty, error) {
28+
c := &ConPty{
29+
consoleSize: uintptr(columns) + (uintptr(rows) << 16),
30+
}
31+
32+
return c, c.createPseudoConsoleAndPipes()
33+
}
34+
35+
// Close closes the pseudo-terminal and cleans up all attached resources
36+
func (c *ConPty) Close() error {
37+
err := closePseudoConsole(c.hpCon)
38+
c.inPipe.Close()
39+
c.outPipe.Close()
40+
return err
41+
}
42+
43+
// OutPipe returns the output pipe of the pseudo terminal
44+
func (c *ConPty) OutPipe() *os.File {
45+
return c.outPipe
46+
}
47+
48+
// InPipe returns input pipe of the pseudo terminal
49+
// Note: It is safer to use the Write method to prevent partially-written VT sequences
50+
// from corrupting the terminal
51+
func (c *ConPty) InPipe() *os.File {
52+
return c.inPipe
53+
}
54+
55+
func (c *ConPty) createPseudoConsoleAndPipes() error {
56+
// These are the readers/writers for "stdin", but we only need this to
57+
// successfully call CreatePseudoConsole. After, we can throw it away.
58+
var hPipeInW, hPipeInR windows.Handle
59+
60+
// Create the stdin pipe although we never use this.
61+
if err := windows.CreatePipe(&hPipeInR, &hPipeInW, nil, 0); err != nil {
62+
return err
63+
}
64+
65+
// Create the stdout pipe
66+
if err := windows.CreatePipe(&c.pipeFdOut, &c.pipeFdIn, nil, 0); err != nil {
67+
return err
68+
}
69+
70+
// Create the pty with our stdin/stdout
71+
if err := createPseudoConsole(c.consoleSize, hPipeInR, c.pipeFdIn, &c.hpCon); err != nil {
72+
return fmt.Errorf("failed to create pseudo console: %d, %v", uintptr(c.hpCon), err)
73+
}
74+
75+
// Close our stdin cause we're never going to use it
76+
if hPipeInR != windows.InvalidHandle {
77+
windows.CloseHandle(hPipeInR)
78+
}
79+
if hPipeInW != windows.InvalidHandle {
80+
windows.CloseHandle(hPipeInW)
81+
}
82+
83+
c.inPipe = os.NewFile(uintptr(c.pipeFdIn), "|0")
84+
c.outPipe = os.NewFile(uintptr(c.pipeFdOut), "|1")
85+
86+
return nil
87+
}
88+
89+
func (c *ConPty) Resize(cols uint16, rows uint16) error {
90+
return resizePseudoConsole(c.hpCon, uintptr(cols)+(uintptr(rows)<<16))
91+
}

expect/conpty/syscall.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// +build windows
2+
3+
// Copyright 2020 ActiveState Software. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file
6+
7+
package conpty
8+
9+
import (
10+
"unsafe"
11+
12+
"golang.org/x/sys/windows"
13+
)
14+
15+
var (
16+
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
17+
procResizePseudoConsole = kernel32.NewProc("ResizePseudoConsole")
18+
procCreatePseudoConsole = kernel32.NewProc("CreatePseudoConsole")
19+
procClosePseudoConsole = kernel32.NewProc("ClosePseudoConsole")
20+
)
21+
22+
func createPseudoConsole(consoleSize uintptr, ptyIn windows.Handle, ptyOut windows.Handle, hpCon *windows.Handle) (err error) {
23+
r1, _, e1 := procCreatePseudoConsole.Call(
24+
consoleSize,
25+
uintptr(ptyIn),
26+
uintptr(ptyOut),
27+
0,
28+
uintptr(unsafe.Pointer(hpCon)),
29+
)
30+
31+
if r1 != 0 { // !S_OK
32+
err = e1
33+
}
34+
return
35+
}
36+
37+
func resizePseudoConsole(handle windows.Handle, consoleSize uintptr) (err error) {
38+
r1, _, e1 := procResizePseudoConsole.Call(uintptr(handle), consoleSize)
39+
if r1 != 0 { // !S_OK
40+
err = e1
41+
}
42+
return
43+
}
44+
45+
func closePseudoConsole(handle windows.Handle) (err error) {
46+
r1, _, e1 := procClosePseudoConsole.Call(uintptr(handle))
47+
if r1 == 0 {
48+
err = e1
49+
}
50+
51+
return
52+
}

expect/pty/pty_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
"golang.org/x/sys/windows"
1010

11-
"github.com/hashicorp/waypoint-plugin-sdk/internal/pkg/conpty"
11+
"github.com/coder/coder/expect/conpty"
1212
)
1313

1414
func newPty() (Pty, error) {

0 commit comments

Comments
 (0)