]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/os/exec_posix.go
libgo: update to almost the 1.14.2 release
[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
5a8ea165 5// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows
d8f41257 6
405ca104
ILT
7package os
8
adb0401d 9import (
52fa80f8 10 "internal/syscall/execenv"
5a8ea165 11 "runtime"
adb0401d
ILT
12 "syscall"
13)
14
4f4a855d
ILT
15// The only signal values guaranteed to be present in the os package on all
16// systems are os.Interrupt (send the process an interrupt) and os.Kill (force
17// the process to exit). On Windows, sending os.Interrupt to a process with
18// os.Process.Signal is not implemented; it will return an error instead of
19// sending a signal.
4ccad563
ILT
20var (
21 Interrupt Signal = syscall.SIGINT
22 Kill Signal = syscall.SIGKILL
23)
24
593f74bb 25func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
bd2e46c8
ILT
26 // If there is no SysProcAttr (ie. no Chroot or changed
27 // UID/GID), double-check existence of the directory we want
22b955cc 28 // to chdir into. We can make the error clearer this way.
bd2e46c8 29 if attr != nil && attr.Sys == nil && attr.Dir != "" {
593f74bb
ILT
30 if _, err := Stat(attr.Dir); err != nil {
31 pe := err.(*PathError)
32 pe.Op = "chdir"
33 return nil, pe
34 }
35 }
36
405ca104
ILT
37 sysattr := &syscall.ProcAttr{
38 Dir: attr.Dir,
39 Env: attr.Env,
adb0401d 40 Sys: attr.Sys,
405ca104
ILT
41 }
42 if sysattr.Env == nil {
52fa80f8 43 sysattr.Env, err = execenv.Default(sysattr.Sys)
aa8901e9
ILT
44 if err != nil {
45 return nil, err
46 }
405ca104 47 }
aa8901e9 48 sysattr.Files = make([]uintptr, 0, len(attr.Files))
adb0401d
ILT
49 for _, f := range attr.Files {
50 sysattr.Files = append(sysattr.Files, f.Fd())
405ca104 51 }
405ca104
ILT
52
53 pid, h, e := syscall.StartProcess(name, argv, sysattr)
5a8ea165
ILT
54
55 // Make sure we don't run the finalizers of attr.Files.
56 runtime.KeepAlive(attr)
57
ab61e9c4
ILT
58 if e != nil {
59 return nil, &PathError{"fork/exec", name, e}
405ca104 60 }
5a8ea165 61
405ca104
ILT
62 return newProcess(pid, h), nil
63}
64
593f74bb 65func (p *Process) kill() error {
cbb6491d 66 return p.Signal(Kill)
405ca104
ILT
67}
68
593f74bb 69// ProcessState stores information about a process, as reported by Wait.
501699af
ILT
70type ProcessState struct {
71 pid int // The process's id.
72 status syscall.WaitStatus // System-dependent status info.
73 rusage *syscall.Rusage
405ca104
ILT
74}
75
501699af
ILT
76// Pid returns the process id of the exited process.
77func (p *ProcessState) Pid() int {
78 return p.pid
79}
80
593f74bb 81func (p *ProcessState) exited() bool {
501699af
ILT
82 return p.status.Exited()
83}
84
593f74bb 85func (p *ProcessState) success() bool {
501699af
ILT
86 return p.status.ExitStatus() == 0
87}
88
593f74bb 89func (p *ProcessState) sys() interface{} {
501699af
ILT
90 return p.status
91}
92
593f74bb 93func (p *ProcessState) sysUsage() interface{} {
501699af 94 return p.rusage
405ca104
ILT
95}
96
501699af
ILT
97func (p *ProcessState) String() string {
98 if p == nil {
adb0401d
ILT
99 return "<nil>"
100 }
501699af 101 status := p.Sys().(syscall.WaitStatus)
405ca104
ILT
102 res := ""
103 switch {
501699af 104 case status.Exited():
af146490 105 res = "exit status " + itoa(status.ExitStatus())
501699af 106 case status.Signaled():
be47d6ec 107 res = "signal: " + status.Signal().String()
501699af 108 case status.Stopped():
be47d6ec 109 res = "stop signal: " + status.StopSignal().String()
501699af 110 if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
af146490 111 res += " (trap " + itoa(status.TrapCause()) + ")"
405ca104 112 }
501699af 113 case status.Continued():
405ca104
ILT
114 res = "continued"
115 }
501699af 116 if status.CoreDump() {
405ca104
ILT
117 res += " (core dumped)"
118 }
119 return res
120}
4f4a855d
ILT
121
122// ExitCode returns the exit code of the exited process, or -1
123// if the process hasn't exited or was terminated by a signal.
124func (p *ProcessState) ExitCode() int {
125 // return -1 if the process hasn't started.
126 if p == nil {
127 return -1
128 }
129 return p.status.ExitStatus()
130}