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