11package wsep
22
33import (
4- "bytes"
5- "context"
64 "io"
7- "io/ioutil"
8- "os"
95 "os/exec"
10- "syscall"
116
12- "github.com/creack/pty"
137 "golang.org/x/xerrors"
148)
159
1610// LocalExecer executes command on the local system.
1711type LocalExecer struct {
1812}
1913
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-
3014func (l * localProcess ) Stdin () io.WriteCloser {
3115 return l .stdin
3216}
@@ -53,81 +37,10 @@ func (l *localProcess) Close() error {
5337 return l .cmd .Process .Kill ()
5438}
5539
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-
6640func (l * localProcess ) Pid () int {
6741 return l .cmd .Process .Pid
6842}
6943
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-
13144type disabledStdinWriter struct {}
13245
13346func (w disabledStdinWriter ) Close () error {
0 commit comments