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

     1  //go:build windows
     2  // +build windows
     3  
     4  package pty
     5  
     6  import (
     7  	"context"
     8  	"io"
     9  	"os"
    10  	"syscall"
    11  
    12  	_ "unsafe" // for go:linkname
    13  )
    14  
    15  // copied from os/exec.Cmd for platform compatibility
    16  // we need to use startupInfoEx for pty support, but os/exec.Cmd only have
    17  // support for startupInfo on windows, so we have to rewrite some internal
    18  // logic for windows while keep its behavior compatible with other platforms.
    19  
    20  // cmd represents an external command being prepared or run.
    21  //
    22  // A cmd cannot be reused after calling its Run, Output or CombinedOutput
    23  // methods.
    24  //go:linkname cmd os/exec.Cmd
    25  type cmd struct {
    26  	// Path is the path of the command to run.
    27  	//
    28  	// This is the only field that must be set to a non-zero
    29  	// value. If Path is relative, it is evaluated relative
    30  	// to Dir.
    31  	Path string
    32  
    33  	// Args holds command line arguments, including the command as Args[0].
    34  	// If the Args field is empty or nil, Run uses {Path}.
    35  	//
    36  	// In typical use, both Path and Args are set by calling Command.
    37  	Args []string
    38  
    39  	// Env specifies the environment of the process.
    40  	// Each entry is of the form "key=value".
    41  	// If Env is nil, the new process uses the current process's
    42  	// environment.
    43  	// If Env contains duplicate environment keys, only the last
    44  	// value in the slice for each duplicate key is used.
    45  	// As a special case on Windows, SYSTEMROOT is always added if
    46  	// missing and not explicitly set to the empty string.
    47  	Env []string
    48  
    49  	// Dir specifies the working directory of the command.
    50  	// If Dir is the empty string, Run runs the command in the
    51  	// calling process's current directory.
    52  	Dir string
    53  
    54  	// Stdin specifies the process's standard input.
    55  	//
    56  	// If Stdin is nil, the process reads from the null device (os.DevNull).
    57  	//
    58  	// If Stdin is an *os.File, the process's standard input is connected
    59  	// directly to that file.
    60  	//
    61  	// Otherwise, during the execution of the command a separate
    62  	// goroutine reads from Stdin and delivers that data to the command
    63  	// over a pipe. In this case, Wait does not complete until the goroutine
    64  	// stops copying, either because it has reached the end of Stdin
    65  	// (EOF or a read error) or because writing to the pipe returned an error.
    66  	Stdin io.Reader
    67  
    68  	// Stdout and Stderr specify the process's standard output and error.
    69  	//
    70  	// If either is nil, Run connects the corresponding file descriptor
    71  	// to the null device (os.DevNull).
    72  	//
    73  	// If either is an *os.File, the corresponding output from the process
    74  	// is connected directly to that file.
    75  	//
    76  	// Otherwise, during the execution of the command a separate goroutine
    77  	// reads from the process over a pipe and delivers that data to the
    78  	// corresponding Writer. In this case, Wait does not complete until the
    79  	// goroutine reaches EOF or encounters an error.
    80  	//
    81  	// If Stdout and Stderr are the same writer, and have a type that can
    82  	// be compared with ==, at most one goroutine at a time will call Write.
    83  	Stdout io.Writer
    84  	Stderr io.Writer
    85  
    86  	// ExtraFiles specifies additional open files to be inherited by the
    87  	// new process. It does not include standard input, standard output, or
    88  	// standard error. If non-nil, entry i becomes file descriptor 3+i.
    89  	//
    90  	// ExtraFiles is not supported on Windows.
    91  	ExtraFiles []*os.File
    92  
    93  	// SysProcAttr holds optional, operating system-specific attributes.
    94  	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
    95  	SysProcAttr *syscall.SysProcAttr
    96  
    97  	// Process is the underlying process, once started.
    98  	Process *os.Process
    99  
   100  	// ProcessState contains information about an exited process,
   101  	// available after a call to Wait or Run.
   102  	ProcessState *os.ProcessState
   103  
   104  	ctx             context.Context // nil means none
   105  	lookPathErr     error           // LookPath error, if any.
   106  	finished        bool            // when Wait was called
   107  	childFiles      []*os.File
   108  	closeAfterStart []io.Closer
   109  	closeAfterWait  []io.Closer
   110  	goroutine       []func() error
   111  	errch           chan error // one send per goroutine
   112  	waitDone        chan struct{}
   113  }
   114  
   115  //go:linkname _cmd_closeDescriptors os/exec.(*Cmd).closeDescriptors
   116  func _cmd_closeDescriptors(c *cmd, closers []io.Closer)
   117  
   118  //go:linkname _cmd_envv os/exec.(*Cmd).envv
   119  func _cmd_envv(c *cmd) ([]string, error)
   120  
   121  //go:linkname _cmd_argv os/exec.(*Cmd).argv
   122  func _cmd_argv(c *cmd) []string
   123  
   124  //go:linkname lookExtensions os/exec.lookExtensions
   125  func lookExtensions(path, dir string) (string, error)
   126  
   127  //go:linkname dedupEnv os/exec.dedupEnv
   128  func dedupEnv(env []string) []string
   129  
   130  //go:linkname addCriticalEnv os/exec.addCriticalEnv
   131  func addCriticalEnv(env []string) []string
   132  
   133  //go:linkname newProcess os.newProcess
   134  func newProcess(pid int, handle uintptr) *os.Process
   135  
   136  //go:linkname execEnvDefault internal/syscall/execenv.Default
   137  func execEnvDefault(sys *syscall.SysProcAttr) (env []string, err error)
   138  
   139  //go:linkname createEnvBlock syscall.createEnvBlock
   140  func createEnvBlock(envv []string) *uint16
   141  
   142  //go:linkname makeCmdLine syscall.makeCmdLine
   143  func makeCmdLine(args []string) string
   144  
   145  //go:linkname joinExeDirAndFName syscall.joinExeDirAndFName
   146  func joinExeDirAndFName(dir, p string) (name string, err error)