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