forked from coder/coder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
start.go
60 lines (51 loc) · 1.56 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package pty
import (
"context"
"os/exec"
)
// StartOption represents a configuration option passed to Start.
type StartOption func(*startOptions)
type startOptions struct {
ptyOpts []Option
}
// WithPTYOption applies the given options to the underlying PTY.
func WithPTYOption(opts ...Option) StartOption {
return func(o *startOptions) {
o.ptyOpts = append(o.ptyOpts, opts...)
}
}
// Cmd is a drop-in replacement for exec.Cmd with most of the same API, but
// it exposes the context.Context to our PTY code so that we can still kill the
// process when the Context expires. This is required because on Windows, we don't
// start the command using the `exec` library, so we have to manage the context
// ourselves.
type Cmd struct {
Context context.Context
Path string
Args []string
Env []string
Dir string
}
func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
return &Cmd{
Context: ctx,
Path: name,
Args: append([]string{name}, arg...),
Env: make([]string, 0),
}
}
func Command(name string, arg ...string) *Cmd {
return CommandContext(context.Background(), name, arg...)
}
func (c *Cmd) AsExec() *exec.Cmd {
//nolint: gosec
execCmd := exec.CommandContext(c.Context, c.Path, c.Args[1:]...)
execCmd.Dir = c.Dir
execCmd.Env = c.Env
return execCmd
}
// Start the command in a TTY. The calling code must not use cmd after passing it to the PTY, and
// instead rely on the returned Process to manage the command/process.
func Start(cmd *Cmd, opt ...StartOption) (PTYCmd, Process, error) {
return startPty(cmd, opt...)
}