exec.go 5.9 KB

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