github.com/dolfly/pty@v1.2.1/run_unix.go (about)

     1  //go:build !windows
     2  //+build !windows
     3  
     4  package pty
     5  
     6  import (
     7  	"os/exec"
     8  	"syscall"
     9  )
    10  
    11  // StartWithSize assigns a pseudo-terminal Tty to c.Stdin, c.Stdout,
    12  // and c.Stderr, calls c.Start, and returns the File of the tty's
    13  // corresponding Pty.
    14  //
    15  // This will resize the Pty to the specified size before starting the command.
    16  // Starts the process in a new session and sets the controlling terminal.
    17  func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error) {
    18  	if c.SysProcAttr == nil {
    19  		c.SysProcAttr = &syscall.SysProcAttr{}
    20  	}
    21  	c.SysProcAttr.Setsid = true
    22  	c.SysProcAttr.Setctty = true
    23  	return StartWithAttrs(c, sz, c.SysProcAttr)
    24  }
    25  
    26  // StartWithAttrs assigns a pseudo-terminal Tty to c.Stdin, c.Stdout,
    27  // and c.Stderr, calls c.Start, and returns the File of the tty's
    28  // corresponding Pty.
    29  //
    30  // This will resize the Pty to the specified size before starting the command if a size is provided.
    31  // The `attrs` parameter overrides the one set in c.SysProcAttr.
    32  //
    33  // This should generally not be needed. Used in some edge cases where it is needed to create a pty
    34  // without a controlling terminal.
    35  func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error) {
    36  	pty, tty, err := open()
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	defer func() {
    41  		// always close tty fds since it's being used in another process
    42  		// but pty is kept to resize tty
    43  		_ = tty.Close()
    44  	}()
    45  
    46  	if sz != nil {
    47  		if err := Setsize(pty, sz); err != nil {
    48  			_ = pty.Close()
    49  			return nil, err
    50  		}
    51  	}
    52  	if c.Stdout == nil {
    53  		c.Stdout = tty
    54  	}
    55  	if c.Stderr == nil {
    56  		c.Stderr = tty
    57  	}
    58  	if c.Stdin == nil {
    59  		c.Stdin = tty
    60  	}
    61  
    62  	c.SysProcAttr = attrs
    63  
    64  	if err := c.Start(); err != nil {
    65  		_ = pty.Close()
    66  		return nil, err
    67  	}
    68  	return pty, err
    69  }