2009-02-15 20:35:52 -07:00
|
|
|
// 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 (
|
2017-12-04 11:57:48 -07:00
|
|
|
"internal/testlog"
|
2011-02-03 20:41:26 -07:00
|
|
|
"runtime"
|
2016-06-09 23:24:40 -06:00
|
|
|
"sync"
|
2012-08-20 18:41:31 -06:00
|
|
|
"sync/atomic"
|
2009-12-15 16:40:16 -07:00
|
|
|
"syscall"
|
2016-08-14 10:39:00 -06:00
|
|
|
"time"
|
2009-02-15 20:35:52 -07:00
|
|
|
)
|
|
|
|
|
2011-02-03 20:41:26 -07:00
|
|
|
// Process stores the information about a process created by StartProcess.
|
|
|
|
type Process struct {
|
|
|
|
Pid int
|
2016-06-09 23:24:40 -06:00
|
|
|
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
|
2011-02-03 20:41:26 -07:00
|
|
|
}
|
|
|
|
|
2012-02-02 12:08:48 -07:00
|
|
|
func newProcess(pid int, handle uintptr) *Process {
|
2011-07-11 16:47:42 -06:00
|
|
|
p := &Process{Pid: pid, handle: handle}
|
2011-02-03 20:41:26 -07:00
|
|
|
runtime.SetFinalizer(p, (*Process).Release)
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2012-08-20 18:41:31 -06:00
|
|
|
func (p *Process) setDone() {
|
|
|
|
atomic.StoreUint32(&p.isdone, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Process) done() bool {
|
|
|
|
return atomic.LoadUint32(&p.isdone) > 0
|
|
|
|
}
|
|
|
|
|
2011-03-15 12:41:19 -06:00
|
|
|
// 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
|
2016-03-01 16:21:55 -07:00
|
|
|
// Files specifies the open files inherited by the new process. The
|
2011-03-15 12:41:19 -06:00
|
|
|
// first three entries correspond to standard input, standard output, and
|
2016-03-01 16:21:55 -07:00
|
|
|
// standard error. An implementation may support additional entries,
|
|
|
|
// depending on the underlying operating system. A nil entry corresponds
|
2011-03-15 12:41:19 -06:00
|
|
|
// to that file being closed when the process starts.
|
|
|
|
Files []*File
|
2011-06-14 08:49:34 -06:00
|
|
|
|
|
|
|
// 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
|
2011-03-15 12:41:19 -06:00
|
|
|
}
|
|
|
|
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
// A Signal represents an operating system signal.
|
|
|
|
// The usual underlying implementation is operating system-dependent:
|
|
|
|
// on Unix it is syscall.Signal.
|
2011-07-13 17:29:37 -06:00
|
|
|
type Signal interface {
|
|
|
|
String() string
|
os/signal: selective signal handling
Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.
This could plausibly move into package os now
that there are no magic side effects as a result
of the import.
Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)
Tested on darwin,linux 386,amd64.
Fixes #1266.
R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
https://golang.org/cl/3749041
2012-02-13 11:52:37 -07:00
|
|
|
Signal() // to distinguish from other Stringers
|
2011-07-13 17:29:37 -06:00
|
|
|
}
|
|
|
|
|
2009-05-25 15:38:38 -06:00
|
|
|
// Getpid returns the process id of the caller.
|
2009-12-15 16:40:16 -07:00
|
|
|
func Getpid() int { return syscall.Getpid() }
|
2009-05-25 15:38:38 -06:00
|
|
|
|
|
|
|
// Getppid returns the process id of the caller's parent.
|
2009-12-15 16:40:16 -07:00
|
|
|
func Getppid() int { return syscall.Getppid() }
|
2016-08-14 10:39:00 -06:00
|
|
|
|
|
|
|
// 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
|
2017-12-28 18:15:23 -07:00
|
|
|
// specified by name, argv and attr. The argv slice will become os.Args in the
|
2018-01-09 13:49:40 -07:00
|
|
|
// new process, so it normally starts with the program name.
|
2016-08-14 10:39:00 -06:00
|
|
|
//
|
2018-01-26 11:44:28 -07:00
|
|
|
// 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.
|
|
|
|
//
|
2016-08-14 10:39:00 -06:00
|
|
|
// 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) {
|
2017-12-04 11:57:48 -07:00
|
|
|
testlog.Open(name)
|
2016-08-14 10:39:00 -06:00
|
|
|
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.
|
|
|
|
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()
|
|
|
|
}
|