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  }