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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy