Add StartWithAttrs to allow bypassing setsid/setctty (#97)
Signed-off-by: Guillaume J. Charmes <git+guillaume@charmes.net>
Guillaume J. Charmes authored 4 years ago
GitHub committed 4 years ago
10 | 10 | // Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, |
11 | 11 | // and c.Stderr, calls c.Start, and returns the File of the tty's |
12 | 12 | // corresponding pty. |
13 | // | |
14 | // Starts the process in a new session and sets the controlling terminal. | |
13 | 15 | func Start(c *exec.Cmd) (pty *os.File, err error) { |
14 | 16 | return StartWithSize(c, nil) |
15 | 17 | } |
18 | 20 | // and c.Stderr, calls c.Start, and returns the File of the tty's |
19 | 21 | // corresponding pty. |
20 | 22 | // |
21 | // This will resize the pty to the specified size before starting the command | |
23 | // This will resize the pty to the specified size before starting the command. | |
24 | // Starts the process in a new session and sets the controlling terminal. | |
22 | 25 | func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) { |
26 | if c.SysProcAttr == nil { | |
27 | c.SysProcAttr = &syscall.SysProcAttr{} | |
28 | } | |
29 | c.SysProcAttr.Setsid = true | |
30 | c.SysProcAttr.Setctty = true | |
31 | return StartWithAttrs(c, sz, c.SysProcAttr) | |
32 | } | |
33 | ||
34 | // StartWithAttrs assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, | |
35 | // and c.Stderr, calls c.Start, and returns the File of the tty's | |
36 | // corresponding pty. | |
37 | // | |
38 | // This will resize the pty to the specified size before starting the command if a size is provided. | |
39 | // The `attrs` parameter overrides the one set in c.SysProcAttr. | |
40 | // | |
41 | // This should generally not be needed. Used in some edge cases where it is needed to create a pty | |
42 | // without a controlling terminal. | |
43 | func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (pty *os.File, err error) { | |
23 | 44 | pty, tty, err := Open() |
24 | 45 | if err != nil { |
25 | 46 | return nil, err |
26 | 47 | } |
27 | 48 | defer tty.Close() |
49 | ||
28 | 50 | if sz != nil { |
29 | err = Setsize(pty, sz) | |
30 | if err != nil { | |
51 | if err := Setsize(pty, sz); err != nil { | |
31 | 52 | pty.Close() |
32 | 53 | return nil, err |
33 | 54 | } |
41 | 62 | if c.Stdin == nil { |
42 | 63 | c.Stdin = tty |
43 | 64 | } |
44 | if c.SysProcAttr == nil { | |
45 | c.SysProcAttr = &syscall.SysProcAttr{} | |
46 | } | |
47 | c.SysProcAttr.Setctty = true | |
48 | c.SysProcAttr.Setsid = true | |
49 | c.SysProcAttr.Ctty = int(tty.Fd()) | |
50 | err = c.Start() | |
51 | if err != nil { | |
52 | pty.Close() | |
65 | ||
66 | c.SysProcAttr = attrs | |
67 | ||
68 | if err := c.Start(); err != nil { | |
69 | _ = pty.Close() | |
53 | 70 | return nil, err |
54 | 71 | } |
55 | 72 | return pty, err |