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 uint32 // process has been successfully waited on, non zero if true 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 atomic.StoreUint32(&p.isdone, 1) 36 } 37 38 func (p *Process) done() bool { 39 return atomic.LoadUint32(&p.isdone) > 0 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. 90 func FindProcess(pid int) (*Process, error) { 91 return findProcess(pid) 92 } 93 94 // StartProcess starts a new process with the program, arguments and attributes 95 // specified by name, argv and attr. The argv slice will become os.Args in the 96 // new process, so it normally starts with the program name. 97 // 98 // If the calling goroutine has locked the operating system thread 99 // with runtime.LockOSThread and modified any inheritable OS-level 100 // thread state (for example, Linux or Plan 9 name spaces), the new 101 // process will inherit the caller's thread state. 102 // 103 // StartProcess is a low-level interface. The os/exec package provides 104 // higher-level interfaces. 105 // 106 // If there is an error, it will be of type *PathError. 107 func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) { 108 testlog.Open(name) 109 return startProcess(name, argv, attr) 110 } 111 112 // Release releases any resources associated with the Process p, 113 // rendering it unusable in the future. 114 // Release only needs to be called if Wait is not. 115 func (p *Process) Release() error { 116 return p.release() 117 } 118 119 // Kill causes the Process to exit immediately. Kill does not wait until 120 // the Process has actually exited. This only kills the Process itself, 121 // not any other processes it may have started. 122 func (p *Process) Kill() error { 123 return p.kill() 124 } 125 126 // Wait waits for the Process to exit, and then returns a 127 // ProcessState describing its status and an error, if any. 128 // Wait releases any resources associated with the Process. 129 // On most operating systems, the Process must be a child 130 // of the current process or an error will be returned. 131 func (p *Process) Wait() (*ProcessState, error) { 132 return p.wait() 133 } 134 135 // Signal sends a signal to the Process. 136 // Sending Interrupt on Windows is not implemented. 137 func (p *Process) Signal(sig Signal) error { 138 return p.signal(sig) 139 } 140 141 // UserTime returns the user CPU time of the exited process and its children. 142 func (p *ProcessState) UserTime() time.Duration { 143 return p.userTime() 144 } 145 146 // SystemTime returns the system CPU time of the exited process and its children. 147 func (p *ProcessState) SystemTime() time.Duration { 148 return p.systemTime() 149 } 150 151 // Exited reports whether the program has exited. 152 func (p *ProcessState) Exited() bool { 153 return p.exited() 154 } 155 156 // Success reports whether the program exited successfully, 157 // such as with exit status 0 on Unix. 158 func (p *ProcessState) Success() bool { 159 return p.success() 160 } 161 162 // Sys returns system-dependent exit information about 163 // the process. Convert it to the appropriate underlying 164 // type, such as syscall.WaitStatus on Unix, to access its contents. 165 func (p *ProcessState) Sys() interface{} { 166 return p.sys() 167 } 168 169 // SysUsage returns system-dependent resource usage information about 170 // the exited process. Convert it to the appropriate underlying 171 // type, such as *syscall.Rusage on Unix, to access its contents. 172 // (On Unix, *syscall.Rusage matches struct rusage as defined in the 173 // getrusage(2) manual page.) 174 func (p *ProcessState) SysUsage() interface{} { 175 return p.sysUsage() 176 } 177