123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- // 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.
- // On Unix systems, StartProcess will change these File values
- // to blocking mode, which means that SetDeadline will stop working
- // and calling Close will not interrupt a Read or Write.
- 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.
- // On Unix systems this reports true if the program exited due to calling exit,
- // but false if the program terminated due to a signal.
- 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() any {
- 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() any {
- return p.sysUsage()
- }
|