Source file src/os/exec.go
1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package os 6 7 import ( 8 "errors" 9 "internal/testlog" 10 "runtime" 11 "sync" 12 "sync/atomic" 13 "syscall" 14 "time" 15 ) 16 17 // ErrProcessDone indicates a [Process] has finished. 18 var ErrProcessDone = errors.New("os: process already finished") 19 20 // Process stores the information about a process created by [StartProcess]. 21 type Process struct { 22 Pid int 23 handle atomic.Uintptr 24 isdone atomic.Bool // process has been successfully waited on 25 sigMu sync.RWMutex // avoid race between wait and signal 26 } 27 28 func newProcess(pid int, handle uintptr) *Process { 29 p := &Process{Pid: pid} 30 p.handle.Store(handle) 31 runtime.SetFinalizer(p, (*Process).Release) 32 return p 33 } 34 35 func (p *Process) setDone() { 36 p.isdone.Store(true) 37 } 38 39 func (p *Process) done() bool { 40 return p.isdone.Load() 41 } 42 43 // ProcAttr holds the attributes that will be applied to a new process 44 // started by StartProcess. 45 type ProcAttr struct { 46 // If Dir is non-empty, the child changes into the directory before 47 // creating the process. 48 Dir string 49 // If Env is non-nil, it gives the environment variables for the 50 // new process in the form returned by Environ. 51 // If it is nil, the result of Environ will be used. 52 Env []string 53 // Files specifies the open files inherited by the new process. The 54 // first three entries correspond to standard input, standard output, and 55 // standard error. An implementation may support additional entries, 56 // depending on the underlying operating system. A nil entry corresponds 57 // to that file being closed when the process starts. 58 // On Unix systems, StartProcess will change these File values 59 // to blocking mode, which means that SetDeadline will stop working 60 // and calling Close will not interrupt a Read or Write. 61 Files []*File 62 63 // Operating system-specific process creation attributes. 64 // Note that setting this field means that your program 65 // may not execute properly or even compile on some 66 // operating systems. 67 Sys *syscall.SysProcAttr 68 } 69 70 // A Signal represents an operating system signal. 71 // The usual underlying implementation is operating system-dependent: 72 // on Unix it is syscall.Signal. 73 type Signal interface { 74 String() string 75 Signal() // to distinguish from other Stringers 76 } 77 78 // Getpid returns the process id of the caller. 79 func Getpid() int { return syscall.Getpid() } 80 81 // Getppid returns the process id of the caller's parent. 82 func Getppid() int { return syscall.Getppid() } 83 84 // FindProcess looks for a running process by its pid. 85 // 86 // The [Process] it returns can be used to obtain information 87 // about the underlying operating system process. 88 // 89 // On Unix systems, FindProcess always succeeds and returns a Process 90 // for the given pid, regardless of whether the process exists. To test whether 91 // the process actually exists, see whether p.Signal(syscall.Signal(0)) reports 92 // an error. 93 func FindProcess(pid int) (*Process, error) { 94 return findProcess(pid) 95 } 96 97 // StartProcess starts a new process with the program, arguments and attributes 98 // specified by name, argv and attr. The argv slice will become [os.Args] in the 99 // new process, so it normally starts with the program name. 100 // 101 // If the calling goroutine has locked the operating system thread 102 // with [runtime.LockOSThread] and modified any inheritable OS-level 103 // thread state (for example, Linux or Plan 9 name spaces), the new 104 // process will inherit the caller's thread state. 105 // 106 // StartProcess is a low-level interface. The [os/exec] package provides 107 // higher-level interfaces. 108 // 109 // If there is an error, it will be of type [*PathError]. 110 func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) { 111 testlog.Open(name) 112 return startProcess(name, argv, attr) 113 } 114 115 // Release releases any resources associated with the [Process] p, 116 // rendering it unusable in the future. 117 // Release only needs to be called if [Process.Wait] is not. 118 func (p *Process) Release() error { 119 return p.release() 120 } 121 122 // Kill causes the [Process] to exit immediately. Kill does not wait until 123 // the Process has actually exited. This only kills the Process itself, 124 // not any other processes it may have started. 125 func (p *Process) Kill() error { 126 return p.kill() 127 } 128 129 // Wait waits for the [Process] to exit, and then returns a 130 // ProcessState describing its status and an error, if any. 131 // Wait releases any resources associated with the Process. 132 // On most operating systems, the Process must be a child 133 // of the current process or an error will be returned. 134 func (p *Process) Wait() (*ProcessState, error) { 135 return p.wait() 136 } 137 138 // Signal sends a signal to the [Process]. 139 // Sending [Interrupt] on Windows is not implemented. 140 func (p *Process) Signal(sig Signal) error { 141 return p.signal(sig) 142 } 143 144 // UserTime returns the user CPU time of the exited process and its children. 145 func (p *ProcessState) UserTime() time.Duration { 146 return p.userTime() 147 } 148 149 // SystemTime returns the system CPU time of the exited process and its children. 150 func (p *ProcessState) SystemTime() time.Duration { 151 return p.systemTime() 152 } 153 154 // Exited reports whether the program has exited. 155 // On Unix systems this reports true if the program exited due to calling exit, 156 // but false if the program terminated due to a signal. 157 func (p *ProcessState) Exited() bool { 158 return p.exited() 159 } 160 161 // Success reports whether the program exited successfully, 162 // such as with exit status 0 on Unix. 163 func (p *ProcessState) Success() bool { 164 return p.success() 165 } 166 167 // Sys returns system-dependent exit information about 168 // the process. Convert it to the appropriate underlying 169 // type, such as [syscall.WaitStatus] on Unix, to access its contents. 170 func (p *ProcessState) Sys() any { 171 return p.sys() 172 } 173 174 // SysUsage returns system-dependent resource usage information about 175 // the exited process. Convert it to the appropriate underlying 176 // type, such as [*syscall.Rusage] on Unix, to access its contents. 177 // (On Unix, *syscall.Rusage matches struct rusage as defined in the 178 // getrusage(2) manual page.) 179 func (p *ProcessState) SysUsage() any { 180 return p.sysUsage() 181 } 182