]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/os/exec_posix.go
re PR rtl-optimization/51495 (ICE: in force_nonfallthru_and_redirect, at cfgrtl.c...
[thirdparty/gcc.git] / libgo / go / os / exec_posix.go
CommitLineData
405ca104
ILT
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
d8f41257
ILT
5// +build darwin freebsd linux openbsd windows
6
405ca104
ILT
7package os
8
adb0401d
ILT
9import (
10 "runtime"
11 "syscall"
12)
13
14type UnixSignal int32
15
16func (sig UnixSignal) String() string {
17 s := runtime.Signame(int32(sig))
18 if len(s) > 0 {
19 return s
20 }
21 return "UnixSignal"
22}
405ca104
ILT
23
24// StartProcess starts a new process with the program, arguments and attributes
25// specified by name, argv and attr.
adb0401d
ILT
26//
27// StartProcess is a low-level interface. The exec package provides
28// higher-level interfaces.
2fd401c8 29func StartProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
405ca104
ILT
30 sysattr := &syscall.ProcAttr{
31 Dir: attr.Dir,
32 Env: attr.Env,
adb0401d 33 Sys: attr.Sys,
405ca104
ILT
34 }
35 if sysattr.Env == nil {
36 sysattr.Env = Environ()
37 }
adb0401d
ILT
38 for _, f := range attr.Files {
39 sysattr.Files = append(sysattr.Files, f.Fd())
405ca104 40 }
405ca104
ILT
41
42 pid, h, e := syscall.StartProcess(name, argv, sysattr)
43 if iserror(e) {
44 return nil, &PathError{"fork/exec", name, Errno(e)}
45 }
46 return newProcess(pid, h), nil
47}
48
adb0401d 49// Kill causes the Process to exit immediately.
2fd401c8 50func (p *Process) Kill() error {
adb0401d
ILT
51 return p.Signal(SIGKILL)
52}
53
405ca104
ILT
54// Exec replaces the current process with an execution of the
55// named binary, with arguments argv and environment envv.
2fd401c8 56// If successful, Exec never returns. If it fails, it returns an error.
adb0401d
ILT
57//
58// To run a child process, see StartProcess (for a low-level interface)
59// or the exec package (for higher-level interfaces).
2fd401c8 60func Exec(name string, argv []string, envv []string) error {
405ca104
ILT
61 if envv == nil {
62 envv = Environ()
63 }
64 e := syscall.Exec(name, argv, envv)
65 if iserror(e) {
66 return &PathError{"exec", name, Errno(e)}
67 }
68 return nil
69}
70
71// TODO(rsc): Should os implement its own syscall.WaitStatus
72// wrapper with the methods, or is exposing the underlying one enough?
73//
74// TODO(rsc): Certainly need to have Rusage struct,
75// since syscall one might have different field types across
76// different OS.
77
78// Waitmsg stores the information about an exited process as reported by Wait.
79type Waitmsg struct {
80 Pid int // The process's id.
81 syscall.WaitStatus // System-dependent status info.
82 Rusage *syscall.Rusage // System-dependent resource usage info.
83}
84
85// Wait waits for process pid to exit or stop, and then returns a
2fd401c8 86// Waitmsg describing its status and an error, if any. The options
405ca104
ILT
87// (WNOHANG etc.) affect the behavior of the Wait call.
88// Wait is equivalent to calling FindProcess and then Wait
89// and Release on the result.
2fd401c8 90func Wait(pid int, options int) (w *Waitmsg, err error) {
405ca104
ILT
91 p, e := FindProcess(pid)
92 if e != nil {
93 return nil, e
94 }
95 defer p.Release()
96 return p.Wait(options)
97}
98
99// Convert i to decimal string.
100func itod(i int) string {
101 if i == 0 {
102 return "0"
103 }
104
105 u := uint64(i)
106 if i < 0 {
107 u = -u
108 }
109
110 // Assemble decimal in reverse order.
111 var b [32]byte
112 bp := len(b)
113 for ; u > 0; u /= 10 {
114 bp--
115 b[bp] = byte(u%10) + '0'
116 }
117
118 if i < 0 {
119 bp--
120 b[bp] = '-'
121 }
122
123 return string(b[bp:])
124}
125
adb0401d
ILT
126func (w *Waitmsg) String() string {
127 if w == nil {
128 return "<nil>"
129 }
405ca104
ILT
130 // TODO(austin) Use signal names when possible?
131 res := ""
132 switch {
133 case w.Exited():
134 res = "exit status " + itod(w.ExitStatus())
135 case w.Signaled():
136 res = "signal " + itod(w.Signal())
137 case w.Stopped():
138 res = "stop signal " + itod(w.StopSignal())
139 if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 {
140 res += " (trap " + itod(w.TrapCause()) + ")"
141 }
142 case w.Continued():
143 res = "continued"
144 }
145 if w.CoreDump() {
146 res += " (core dumped)"
147 }
148 return res
149}