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)