| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package os |
| |
| import ( |
| "errors" |
| "internal/testlog" |
| "runtime" |
| "sync" |
| "sync/atomic" |
| "syscall" |
| "time" |
| ) |
| |
| // ErrProcessDone indicates a Process has finished. |
| var ErrProcessDone = errors.New("os: process already finished") |
| |
| // Process stores the information about a process created by StartProcess. |
| type Process struct { |
| Pid int |
| handle uintptr // handle is accessed atomically on Windows |
| isdone uint32 // process has been successfully waited on, non zero if true |
| sigMu sync.RWMutex // avoid race between wait and signal |
| } |
| |
| func newProcess(pid int, handle uintptr) *Process { |
| p := &Process{Pid: pid, handle: handle} |
| runtime.SetFinalizer(p, (*Process).Release) |
| return p |
| } |
| |
| func (p *Process) setDone() { |
| atomic.StoreUint32(&p.isdone, 1) |
| } |
| |
| func (p *Process) done() bool { |
| return atomic.LoadUint32(&p.isdone) > 0 |
| } |
| |
| // ProcAttr holds the attributes that will be applied to a new process |
| // started by StartProcess. |
| type ProcAttr struct { |
| // If Dir is non-empty, the child changes into the directory before |
| // creating the process. |
| Dir string |
| // If Env is non-nil, it gives the environment variables for the |
| // new process in the form returned by Environ. |
| // If it is nil, the result of Environ will be used. |
| Env []string |
| // Files specifies the open files inherited by the new process. The |
| // first three entries correspond to standard input, standard output, and |
| // standard error. An implementation may support additional entries, |
| // depending on the underlying operating system. A nil entry corresponds |
| // to that file being closed when the process starts. |
| Files []*File |
| |
| // Operating system-specific process creation attributes. |
| // Note that setting this field means that your program |
| // may not execute properly or even compile on some |
| // operating systems. |
| Sys *syscall.SysProcAttr |
| } |
| |
| // A Signal represents an operating system signal. |
| // The usual underlying implementation is operating system-dependent: |
| // on Unix it is syscall.Signal. |
| type Signal interface { |
| String() string |
| Signal() // to distinguish from other Stringers |
| } |
| |
| // Getpid returns the process id of the caller. |
| func Getpid() int { return syscall.Getpid() } |
| |
| // Getppid returns the process id of the caller's parent. |
| func Getppid() int { return syscall.Getppid() } |
| |
| // FindProcess looks for a running process by its pid. |
| // |
| // The Process it returns can be used to obtain information |
| // about the underlying operating system process. |
| // |
| // On Unix systems, FindProcess always succeeds and returns a Process |
| // for the given pid, regardless of whether the process exists. |
| func FindProcess(pid int) (*Process, error) { |
| return findProcess(pid) |
| } |
| |
| // StartProcess starts a new process with the program, arguments and attributes |
| // specified by name, argv and attr. The argv slice will become os.Args in the |
| // new process, so it normally starts with the program name. |
| // |
| // If the calling goroutine has locked the operating system thread |
| // with runtime.LockOSThread and modified any inheritable OS-level |
| // thread state (for example, Linux or Plan 9 name spaces), the new |
| // process will inherit the caller's thread state. |
| // |
| // StartProcess is a low-level interface. The os/exec package provides |
| // higher-level interfaces. |
| // |
| // If there is an error, it will be of type *PathError. |
| func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) { |
| testlog.Open(name) |
| return startProcess(name, argv, attr) |
| } |
| |
| // Release releases any resources associated with the Process p, |
| // rendering it unusable in the future. |
| // Release only needs to be called if Wait is not. |
| func (p *Process) Release() error { |
| return p.release() |
| } |
| |
| // Kill causes the Process to exit immediately. Kill does not wait until |
| // the Process has actually exited. This only kills the Process itself, |
| // not any other processes it may have started. |
| func (p *Process) Kill() error { |
| return p.kill() |
| } |
| |
| // Wait waits for the Process to exit, and then returns a |
| // ProcessState describing its status and an error, if any. |
| // Wait releases any resources associated with the Process. |
| // On most operating systems, the Process must be a child |
| // of the current process or an error will be returned. |
| func (p *Process) Wait() (*ProcessState, error) { |
| return p.wait() |
| } |
| |
| // Signal sends a signal to the Process. |
| // Sending Interrupt on Windows is not implemented. |
| func (p *Process) Signal(sig Signal) error { |
| return p.signal(sig) |
| } |
| |
| // UserTime returns the user CPU time of the exited process and its children. |
| func (p *ProcessState) UserTime() time.Duration { |
| return p.userTime() |
| } |
| |
| // SystemTime returns the system CPU time of the exited process and its children. |
| func (p *ProcessState) SystemTime() time.Duration { |
| return p.systemTime() |
| } |
| |
| // Exited reports whether the program has exited. |
| func (p *ProcessState) Exited() bool { |
| return p.exited() |
| } |
| |
| // Success reports whether the program exited successfully, |
| // such as with exit status 0 on Unix. |
| func (p *ProcessState) Success() bool { |
| return p.success() |
| } |
| |
| // Sys returns system-dependent exit information about |
| // the process. Convert it to the appropriate underlying |
| // type, such as syscall.WaitStatus on Unix, to access its contents. |
| func (p *ProcessState) Sys() interface{} { |
| return p.sys() |
| } |
| |
| // SysUsage returns system-dependent resource usage information about |
| // the exited process. Convert it to the appropriate underlying |
| // type, such as *syscall.Rusage on Unix, to access its contents. |
| // (On Unix, *syscall.Rusage matches struct rusage as defined in the |
| // getrusage(2) manual page.) |
| func (p *ProcessState) SysUsage() interface{} { |
| return p.sysUsage() |
| } |