Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / os / exec_posix.go
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
5 // +build darwin freebsd linux netbsd openbsd windows
6
7 package os
8
9 import (
10         "syscall"
11 )
12
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).
16 var (
17         Interrupt Signal = syscall.SIGINT
18         Kill      Signal = syscall.SIGKILL
19 )
20
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)
28                         pe.Op = "chdir"
29                         return nil, pe
30                 }
31         }
32
33         sysattr := &syscall.ProcAttr{
34                 Dir: attr.Dir,
35                 Env: attr.Env,
36                 Sys: attr.Sys,
37         }
38         if sysattr.Env == nil {
39                 sysattr.Env = Environ()
40         }
41         for _, f := range attr.Files {
42                 sysattr.Files = append(sysattr.Files, f.Fd())
43         }
44
45         pid, h, e := syscall.StartProcess(name, argv, sysattr)
46         if e != nil {
47                 return nil, &PathError{"fork/exec", name, e}
48         }
49         return newProcess(pid, h), nil
50 }
51
52 func (p *Process) kill() error {
53         return p.Signal(Kill)
54 }
55
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
61 }
62
63 // Pid returns the process id of the exited process.
64 func (p *ProcessState) Pid() int {
65         return p.pid
66 }
67
68 func (p *ProcessState) exited() bool {
69         return p.status.Exited()
70 }
71
72 func (p *ProcessState) success() bool {
73         return p.status.ExitStatus() == 0
74 }
75
76 func (p *ProcessState) sys() interface{} {
77         return p.status
78 }
79
80 func (p *ProcessState) sysUsage() interface{} {
81         return p.rusage
82 }
83
84 // Convert i to decimal string.
85 func itod(i int) string {
86         if i == 0 {
87                 return "0"
88         }
89
90         u := uint64(i)
91         if i < 0 {
92                 u = -u
93         }
94
95         // Assemble decimal in reverse order.
96         var b [32]byte
97         bp := len(b)
98         for ; u > 0; u /= 10 {
99                 bp--
100                 b[bp] = byte(u%10) + '0'
101         }
102
103         if i < 0 {
104                 bp--
105                 b[bp] = '-'
106         }
107
108         return string(b[bp:])
109 }
110
111 func (p *ProcessState) String() string {
112         if p == nil {
113                 return "<nil>"
114         }
115         status := p.Sys().(syscall.WaitStatus)
116         res := ""
117         switch {
118         case status.Exited():
119                 res = "exit status " + itod(status.ExitStatus())
120         case status.Signaled():
121                 res = "signal " + itod(int(status.Signal()))
122         case status.Stopped():
123                 res = "stop signal " + itod(int(status.StopSignal()))
124                 if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
125                         res += " (trap " + itod(status.TrapCause()) + ")"
126                 }
127         case status.Continued():
128                 res = "continued"
129         }
130         if status.CoreDump() {
131                 res += " (core dumped)"
132         }
133         return res
134 }