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.
5 // +build darwin dragonfly freebsd linux netbsd openbsd windows
13 // The only signal values guaranteed to be present on all systems
14 // are Interrupt (send the process an interrupt) and Kill (force
15 // the process to exit).
17 Interrupt Signal
= syscall
.SIGINT
18 Kill Signal
= syscall
.SIGKILL
21 func startProcess(name
string, argv
[]string, attr
*ProcAttr
) (p
*Process
, err error
) {
22 // If there is no SysProcAttr (ie. no Chroot or changed
23 // UID/GID), double-check existence of the directory we want
24 // to chdir into. We can make the error clearer this way.
25 if attr
!= nil && attr
.Sys
== nil && attr
.Dir
!= "" {
26 if _
, err
:= Stat(attr
.Dir
); err
!= nil {
27 pe
:= err
.(*PathError
)
33 sysattr
:= &syscall
.ProcAttr
{
38 if sysattr
.Env
== nil {
39 sysattr
.Env
= Environ()
41 for _
, f
:= range attr
.Files
{
42 sysattr
.Files
= append(sysattr
.Files
, f
.Fd())
45 pid
, h
, e
:= syscall
.StartProcess(name
, argv
, sysattr
)
47 return nil, &PathError
{"fork/exec", name
, e
}
49 return newProcess(pid
, h
), nil
52 func (p
*Process
) kill() error
{
56 // ProcessState stores information about a process, as reported by Wait.
57 type ProcessState
struct {
58 pid
int // The process's id.
59 status syscall
.WaitStatus
// System-dependent status info.
60 rusage
*syscall
.Rusage
63 // Pid returns the process id of the exited process.
64 func (p
*ProcessState
) Pid() int {
68 func (p
*ProcessState
) exited() bool {
69 return p
.status
.Exited()
72 func (p
*ProcessState
) success() bool {
73 return p
.status
.ExitStatus() == 0
76 func (p
*ProcessState
) sys() interface{} {
80 func (p
*ProcessState
) sysUsage() interface{} {
84 // Convert i to decimal string.
85 func itod(i
int) string {
95 // Assemble decimal in reverse order.
98 for ; u
> 0; u
/= 10 {
100 b
[bp
] = byte(u%10
) + '0'
108 return string(b
[bp
:])
111 func (p
*ProcessState
) String() string {
115 status
:= p
.Sys().(syscall
.WaitStatus
)
118 case status
.Exited():
119 res
= "exit status " + itod(status
.ExitStatus())
120 case status
.Signaled():
121 res
= "signal: " + status
.Signal().String()
122 case status
.Stopped():
123 res
= "stop signal: " + status
.StopSignal().String()
124 if status
.StopSignal() == syscall
.SIGTRAP
&& status
.TrapCause() != 0 {
125 res
+= " (trap " + itod(status
.TrapCause()) + ")"
127 case status
.Continued():
130 if status
.CoreDump() {
131 res
+= " (core dumped)"