1
+ //go:build windows
1
2
// +build windows
2
3
3
4
// Original copyright 2020 ActiveState Software. All rights reserved.
@@ -16,17 +17,17 @@ import (
16
17
17
18
// ConPty represents a windows pseudo console.
18
19
type ConPty struct {
19
- hpCon windows.Handle
20
- pipeFdIn windows.Handle
21
- pipeFdOut windows.Handle
22
- pipe3 windows.Handle
23
- pipe4 windows.Handle
24
- consoleSize uintptr
25
- outputR * os.File
26
- outputW * os.File
27
- inputR * os.File
28
- inputW * os.File
29
- closed bool
20
+ hpCon windows.Handle
21
+ outPipePseudoConsoleSide windows.Handle
22
+ outPipeOurSide windows.Handle
23
+ inPipeOurSide windows.Handle
24
+ inPipePseudoConsoleSide windows.Handle
25
+ consoleSize uintptr
26
+ outFilePseudoConsoleSide * os.File
27
+ outFileOurSide * os.File
28
+ inFilePseudoConsoleSide * os.File
29
+ inFileOurSide * os.File
30
+ closed bool
30
31
}
31
32
32
33
// New returns a new ConPty pseudo terminal device
@@ -40,67 +41,62 @@ func New(columns int16, rows int16) (*ConPty, error) {
40
41
41
42
// Close closes the pseudo-terminal and cleans up all attached resources
42
43
func (c * ConPty ) Close () error {
43
- if (c .closed ) {
44
+ // Trying to close these pipes multiple times will result in an
45
+ // access violation
46
+ if c .closed {
44
47
return nil
45
48
}
46
49
47
50
err := closePseudoConsole (c .hpCon )
48
- c .outputR .Close ()
49
- c .outputW .Close ()
50
- c .inputR .Close ()
51
- c .inputW .Close ()
51
+ c .outFilePseudoConsoleSide .Close ()
52
+ c .outFileOurSide .Close ()
53
+ c .inFilePseudoConsoleSide .Close ()
54
+ c .inFileOurSide .Close ()
52
55
c .closed = true
53
56
return err
54
57
}
55
58
56
59
// OutPipe returns the output pipe of the pseudo terminal
57
60
func (c * ConPty ) OutPipe () * os.File {
58
- return c .outputR
61
+ return c .outFilePseudoConsoleSide
59
62
}
60
63
61
64
func (c * ConPty ) Reader () io.Reader {
62
- return c .outputW
65
+ return c .outFileOurSide
63
66
}
64
67
65
68
// InPipe returns input pipe of the pseudo terminal
66
69
// Note: It is safer to use the Write method to prevent partially-written VT sequences
67
70
// from corrupting the terminal
68
71
func (c * ConPty ) InPipe () * os.File {
69
- return c .inputR
72
+ return c .inFilePseudoConsoleSide
70
73
}
71
74
72
75
func (c * ConPty ) WriteString (str string ) (int , error ) {
73
- return c .inputW .WriteString (str )
76
+ return c .inFileOurSide .WriteString (str )
74
77
}
75
78
76
79
func (c * ConPty ) createPseudoConsoleAndPipes () error {
77
- // These are the readers/writers for "stdin", but we only need this to
78
- // successfully call CreatePseudoConsole. After, we can throw it away.
79
- var hPipeInW , hPipeInR windows.Handle
80
-
81
80
// Create the stdin pipe
82
- if err := windows .CreatePipe (& hPipeInR , & hPipeInW , nil , 0 ); err != nil {
81
+ if err := windows .CreatePipe (& c . inPipePseudoConsoleSide , & c . inPipeOurSide , nil , 0 ); err != nil {
83
82
return err
84
83
}
85
84
86
85
// Create the stdout pipe
87
- if err := windows .CreatePipe (& c .pipeFdOut , & c .pipeFdIn , nil , 0 ); err != nil {
86
+ if err := windows .CreatePipe (& c .outPipeOurSide , & c .outPipePseudoConsoleSide , nil , 0 ); err != nil {
88
87
return err
89
88
}
90
89
91
90
// Create the pty with our stdin/stdout
92
- if err := createPseudoConsole (c .consoleSize , hPipeInR , c .pipeFdIn , & c .hpCon ); err != nil {
91
+ if err := createPseudoConsole (c .consoleSize , c . inPipePseudoConsoleSide , c .outPipePseudoConsoleSide , & c .hpCon ); err != nil {
93
92
return fmt .Errorf ("failed to create pseudo console: %d, %v" , uintptr (c .hpCon ), err )
94
93
}
95
94
96
- c .pipe3 = hPipeInR
97
- c .pipe4 = hPipeInW
98
-
99
- c .outputR = os .NewFile (uintptr (c .pipeFdIn ), "|0" )
100
- c .outputW = os .NewFile (uintptr (c .pipeFdOut ), "|1" )
95
+ c .outFilePseudoConsoleSide = os .NewFile (uintptr (c .outPipePseudoConsoleSide ), "|0" )
96
+ c .outFileOurSide = os .NewFile (uintptr (c .outPipeOurSide ), "|1" )
101
97
102
- c .inputR = os .NewFile (uintptr (c .pipe3 ), "|2" )
103
- c .inputW = os .NewFile (uintptr (c .pipe4 ), "|3" )
98
+ c .inFilePseudoConsoleSide = os .NewFile (uintptr (c .inPipePseudoConsoleSide ), "|2" )
99
+ c .inFileOurSide = os .NewFile (uintptr (c .inPipeOurSide ), "|3" )
104
100
c .closed = false
105
101
106
102
return nil
0 commit comments