Source file src/os/exec.go

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

View as plain text