github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/sandbox/process/exec.go (about) 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 process 6 7 import ( 8 "errors" 9 "github.com/LanceLRQ/deer-common/sandbox/forkexec" 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 Files []interface{} 58 59 // Operating system-specific process creation attributes. 60 // Note that setting this field means that your program 61 // may not execute properly or even compile on some 62 // operating systems. 63 Sys *forkexec.SysProcAttr 64 } 65 66 // A Signal represents an operating system signal. 67 // The usual underlying implementation is operating system-dependent: 68 // on Unix it is syscall.Signal. 69 type Signal interface { 70 String() string 71 Signal() // to distinguish from other Stringers 72 } 73 74 // Getpid returns the process id of the caller. 75 func Getpid() int { return syscall.Getpid() } 76 77 // Getppid returns the process id of the caller's parent. 78 func Getppid() int { return syscall.Getppid() } 79 80 // FindProcess looks for a running process by its pid. 81 // 82 // The Process it returns can be used to obtain information 83 // about the underlying operating system process. 84 // 85 // On Unix systems, FindProcess always succeeds and returns a Process 86 // for the given pid, regardless of whether the process exists. 87 func FindProcess(pid int) (*Process, error) { 88 return findProcess(pid) 89 } 90 91 // StartProcess starts a new process with the program, arguments and attributes 92 // specified by name, argv and attr. The argv slice will become os.Args in the 93 // new process, so it normally starts with the program name. 94 // 95 // If the calling goroutine has locked the operating system thread 96 // with runtime.LockOSThread and modified any inheritable OS-level 97 // thread state (for example, Linux or Plan 9 name spaces), the new 98 // process will inherit the caller's thread state. 99 // 100 // StartProcess is a low-level interface. The os/exec package provides 101 // higher-level interfaces. 102 // 103 // If there is an error, it will be of type *PathError. 104 func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) { 105 return startProcess(name, argv, attr) 106 } 107 108 // Release releases any resources associated with the Process p, 109 // rendering it unusable in the future. 110 // Release only needs to be called if Wait is not. 111 func (p *Process) Release() error { 112 return p.release() 113 } 114 115 // Kill causes the Process to exit immediately. Kill does not wait until 116 // the Process has actually exited. This only kills the Process itself, 117 // not any other processes it may have started. 118 func (p *Process) Kill() error { 119 return p.kill() 120 } 121 122 // Wait waits for the Process to exit, and then returns a 123 // ProcessState describing its status and an error, if any. 124 // Wait releases any resources associated with the Process. 125 // On most operating systems, the Process must be a child 126 // of the current process or an error will be returned. 127 func (p *Process) Wait() (*ProcessState, error) { 128 return p.wait() 129 } 130 131 // Signal sends a signal to the Process. 132 // Sending Interrupt on Windows is not implemented. 133 func (p *Process) Signal(sig Signal) error { 134 return p.signal(sig) 135 } 136 137 // UserTime returns the user CPU time of the exited process and its children. 138 func (p *ProcessState) UserTime() time.Duration { 139 return p.userTime() 140 } 141 142 // SystemTime returns the system CPU time of the exited process and its children. 143 func (p *ProcessState) SystemTime() time.Duration { 144 return p.systemTime() 145 } 146 147 // Exited reports whether the program has exited. 148 func (p *ProcessState) Exited() bool { 149 return p.exited() 150 } 151 152 // Success reports whether the program exited successfully, 153 // such as with exit status 0 on Unix. 154 func (p *ProcessState) Success() bool { 155 return p.success() 156 } 157 158 // Sys returns system-dependent exit information about 159 // the process. Convert it to the appropriate underlying 160 // type, such as syscall.WaitStatus on Unix, to access its contents. 161 func (p *ProcessState) Sys() interface{} { 162 return p.sys() 163 } 164 165 // SysUsage returns system-dependent resource usage information about 166 // the exited process. Convert it to the appropriate underlying 167 // type, such as *syscall.Rusage on Unix, to access its contents. 168 // (On Unix, *syscall.Rusage matches struct rusage as defined in the 169 // getrusage(2) manual page.) 170 func (p *ProcessState) SysUsage() interface{} { 171 return p.sysUsage() 172 }