1
1
package wsep
2
2
3
3
import (
4
- "bytes"
5
- "context"
6
4
"io"
7
- "io/ioutil"
8
- "os"
9
5
"os/exec"
10
- "syscall"
11
6
12
- "github.com/creack/pty"
13
7
"golang.org/x/xerrors"
14
8
)
15
9
16
10
// LocalExecer executes command on the local system.
17
11
type LocalExecer struct {
18
12
}
19
13
20
- type localProcess struct {
21
- // tty may be nil
22
- tty * os.File
23
- cmd * exec.Cmd
24
-
25
- stdin io.WriteCloser
26
- stdout io.Reader
27
- stderr io.Reader
28
- }
29
-
30
14
func (l * localProcess ) Stdin () io.WriteCloser {
31
15
return l .stdin
32
16
}
@@ -53,81 +37,10 @@ func (l *localProcess) Close() error {
53
37
return l .cmd .Process .Kill ()
54
38
}
55
39
56
- func (l * localProcess ) Resize (ctx context.Context , rows , cols uint16 ) error {
57
- if l .tty == nil {
58
- return nil
59
- }
60
- return pty .Setsize (l .tty , & pty.Winsize {
61
- Rows : rows ,
62
- Cols : cols ,
63
- })
64
- }
65
-
66
40
func (l * localProcess ) Pid () int {
67
41
return l .cmd .Process .Pid
68
42
}
69
43
70
- // Start executes the given command locally
71
- func (l LocalExecer ) Start (ctx context.Context , c Command ) (Process , error ) {
72
- var (
73
- process localProcess
74
- err error
75
- )
76
- process .cmd = exec .CommandContext (ctx , c .Command , c .Args ... )
77
- process .cmd .Env = append (os .Environ (), c .Env ... )
78
- process .cmd .Dir = c .WorkingDir
79
-
80
- if c .GID != 0 || c .UID != 0 {
81
- process .cmd .SysProcAttr = & syscall.SysProcAttr {
82
- Credential : & syscall.Credential {},
83
- }
84
- }
85
- if c .GID != 0 {
86
- process .cmd .SysProcAttr .Credential .Gid = c .GID
87
- }
88
- if c .UID != 0 {
89
- process .cmd .SysProcAttr .Credential .Uid = c .UID
90
- }
91
-
92
- if c .TTY {
93
- // This special WSEP_TTY variable helps debug unexpected TTYs.
94
- process .cmd .Env = append (process .cmd .Env , "WSEP_TTY=true" )
95
- process .tty , err = pty .Start (process .cmd )
96
- if err != nil {
97
- return nil , xerrors .Errorf ("start command with pty: %w" , err )
98
- }
99
- process .stdout = process .tty
100
- process .stderr = ioutil .NopCloser (bytes .NewReader (nil ))
101
- process .stdin = process .tty
102
- } else {
103
- if c .Stdin {
104
- process .stdin , err = process .cmd .StdinPipe ()
105
- if err != nil {
106
- return nil , xerrors .Errorf ("create pipe: %w" , err )
107
- }
108
- } else {
109
- process .stdin = disabledStdinWriter {}
110
- }
111
-
112
- process .stdout , err = process .cmd .StdoutPipe ()
113
- if err != nil {
114
- return nil , xerrors .Errorf ("create pipe: %w" , err )
115
- }
116
-
117
- process .stderr , err = process .cmd .StderrPipe ()
118
- if err != nil {
119
- return nil , xerrors .Errorf ("create pipe: %w" , err )
120
- }
121
-
122
- err = process .cmd .Start ()
123
- if err != nil {
124
- return nil , xerrors .Errorf ("start command: %w" , err )
125
- }
126
- }
127
-
128
- return & process , nil
129
- }
130
-
131
44
type disabledStdinWriter struct {}
132
45
133
46
func (w disabledStdinWriter ) Close () error {
0 commit comments