Source file
src/os/exec_plan9.go
1
2
3
4
5 package os
6
7 import (
8 "internal/itoa"
9 "syscall"
10 "time"
11 )
12
13
14
15
16
17 var (
18 Interrupt Signal = syscall.Note("interrupt")
19 Kill Signal = syscall.Note("kill")
20 )
21
22 func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
23 sysattr := &syscall.ProcAttr{
24 Dir: attr.Dir,
25 Env: attr.Env,
26 Sys: attr.Sys,
27 }
28
29 sysattr.Files = make([]uintptr, 0, len(attr.Files))
30 for _, f := range attr.Files {
31 sysattr.Files = append(sysattr.Files, f.Fd())
32 }
33
34 pid, _, e := syscall.StartProcess(name, argv, sysattr)
35 if e != nil {
36 return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
37 }
38
39 return newPIDProcess(pid), nil
40 }
41
42 func (p *Process) writeProcFile(file string, data string) error {
43 f, e := OpenFile("/proc/"+itoa.Itoa(p.Pid)+"/"+file, O_WRONLY, 0)
44 if e != nil {
45 return e
46 }
47 defer f.Close()
48 _, e = f.Write([]byte(data))
49 return e
50 }
51
52 func (p *Process) signal(sig Signal) error {
53 switch p.pidStatus() {
54 case statusDone:
55 return ErrProcessDone
56 case statusReleased:
57 return syscall.ENOENT
58 }
59
60 if e := p.writeProcFile("note", sig.String()); e != nil {
61 return NewSyscallError("signal", e)
62 }
63 return nil
64 }
65
66 func (p *Process) kill() error {
67 return p.signal(Kill)
68 }
69
70 func (p *Process) wait() (ps *ProcessState, err error) {
71 var waitmsg syscall.Waitmsg
72
73 switch p.pidStatus() {
74 case statusReleased:
75 return nil, ErrInvalid
76 }
77
78 err = syscall.WaitProcess(p.Pid, &waitmsg)
79 if err != nil {
80 return nil, NewSyscallError("wait", err)
81 }
82
83 p.doRelease(statusDone)
84 ps = &ProcessState{
85 pid: waitmsg.Pid,
86 status: &waitmsg,
87 }
88 return ps, nil
89 }
90
91 func findProcess(pid int) (p *Process, err error) {
92
93 return newPIDProcess(pid), nil
94 }
95
96
97 type ProcessState struct {
98 pid int
99 status *syscall.Waitmsg
100 }
101
102
103 func (p *ProcessState) Pid() int {
104 return p.pid
105 }
106
107 func (p *ProcessState) exited() bool {
108 return p.status.Exited()
109 }
110
111 func (p *ProcessState) success() bool {
112 return p.status.ExitStatus() == 0
113 }
114
115 func (p *ProcessState) sys() any {
116 return p.status
117 }
118
119 func (p *ProcessState) sysUsage() any {
120 return p.status
121 }
122
123 func (p *ProcessState) userTime() time.Duration {
124 return time.Duration(p.status.Time[0]) * time.Millisecond
125 }
126
127 func (p *ProcessState) systemTime() time.Duration {
128 return time.Duration(p.status.Time[1]) * time.Millisecond
129 }
130
131 func (p *ProcessState) String() string {
132 if p == nil {
133 return "<nil>"
134 }
135 return "exit status: " + p.status.Msg
136 }
137
138
139
140 func (p *ProcessState) ExitCode() int {
141
142 if p == nil {
143 return -1
144 }
145 return p.status.ExitStatus()
146 }
147
View as plain text