Source file
src/os/exec_posix.go
Documentation: os
1
2
3
4
5
6
7 package os
8
9 import (
10 "internal/syscall/execenv"
11 "runtime"
12 "syscall"
13 )
14
15
16
17
18
19
20 var (
21 Interrupt Signal = syscall.SIGINT
22 Kill Signal = syscall.SIGKILL
23 )
24
25 func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
26
27
28
29 if attr != nil && attr.Sys == nil && attr.Dir != "" {
30 if _, err := Stat(attr.Dir); err != nil {
31 pe := err.(*PathError)
32 pe.Op = "chdir"
33 return nil, pe
34 }
35 }
36
37 sysattr := &syscall.ProcAttr{
38 Dir: attr.Dir,
39 Env: attr.Env,
40 Sys: attr.Sys,
41 }
42 if sysattr.Env == nil {
43 sysattr.Env, err = execenv.Default(sysattr.Sys)
44 if err != nil {
45 return nil, err
46 }
47 }
48 sysattr.Files = make([]uintptr, 0, len(attr.Files))
49 for _, f := range attr.Files {
50 sysattr.Files = append(sysattr.Files, f.Fd())
51 }
52
53 pid, h, e := syscall.StartProcess(name, argv, sysattr)
54
55
56 runtime.KeepAlive(attr)
57
58 if e != nil {
59 return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
60 }
61
62 return newProcess(pid, h), nil
63 }
64
65 func (p *Process) kill() error {
66 return p.Signal(Kill)
67 }
68
69
70 type ProcessState struct {
71 pid int
72 status syscall.WaitStatus
73 rusage *syscall.Rusage
74 }
75
76
77 func (p *ProcessState) Pid() int {
78 return p.pid
79 }
80
81 func (p *ProcessState) exited() bool {
82 return p.status.Exited()
83 }
84
85 func (p *ProcessState) success() bool {
86 return p.status.ExitStatus() == 0
87 }
88
89 func (p *ProcessState) sys() interface{} {
90 return p.status
91 }
92
93 func (p *ProcessState) sysUsage() interface{} {
94 return p.rusage
95 }
96
97 func (p *ProcessState) String() string {
98 if p == nil {
99 return "<nil>"
100 }
101 status := p.Sys().(syscall.WaitStatus)
102 res := ""
103 switch {
104 case status.Exited():
105 res = "exit status " + itoa(status.ExitStatus())
106 case status.Signaled():
107 res = "signal: " + status.Signal().String()
108 case status.Stopped():
109 res = "stop signal: " + status.StopSignal().String()
110 if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
111 res += " (trap " + itoa(status.TrapCause()) + ")"
112 }
113 case status.Continued():
114 res = "continued"
115 }
116 if status.CoreDump() {
117 res += " (core dumped)"
118 }
119 return res
120 }
121
122
123
124 func (p *ProcessState) ExitCode() int {
125
126 if p == nil {
127 return -1
128 }
129 return p.status.ExitStatus()
130 }
131
View as plain text