]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/os/exec_plan9.go
libgo: Update to current sources.
[thirdparty/gcc.git] / libgo / go / os / exec_plan9.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
5package os
6
7import (
9c63abc9 8 "errors"
405ca104
ILT
9 "runtime"
10 "syscall"
501699af 11 "time"
405ca104
ILT
12)
13
4ccad563
ILT
14// The only signal values guaranteed to be present on all systems
15// are Interrupt (send the process an interrupt) and Kill (force
16// the process to exit).
17var (
18 Interrupt Signal = syscall.Note("interrupt")
19 Kill Signal = syscall.Note("kill")
20)
21
593f74bb 22func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
405ca104
ILT
23 sysattr := &syscall.ProcAttr{
24 Dir: attr.Dir,
25 Env: attr.Env,
adb0401d 26 Sys: attr.Sys,
405ca104
ILT
27 }
28
501699af
ILT
29 for _, f := range attr.Files {
30 sysattr.Files = append(sysattr.Files, f.Fd())
405ca104
ILT
31 }
32
405ca104 33 pid, h, e := syscall.StartProcess(name, argv, sysattr)
ab61e9c4 34 if e != nil {
405ca104
ILT
35 return nil, &PathError{"fork/exec", name, e}
36 }
37
38 return newProcess(pid, h), nil
39}
40
4ccad563
ILT
41func (p *Process) writeProcFile(file string, data string) error {
42 f, e := OpenFile("/proc/"+itoa(p.Pid)+"/"+file, O_WRONLY, 0)
43 if e != nil {
44 return e
45 }
46 defer f.Close()
47 _, e = f.Write([]byte(data))
48 return e
adb0401d
ILT
49}
50
593f74bb 51func (p *Process) signal(sig Signal) error {
bd2e46c8 52 if p.done() {
9c63abc9 53 return errors.New("os: process already finished")
adb0401d 54 }
4ccad563
ILT
55 if sig == Kill {
56 // Special-case the kill signal since it doesn't use /proc/$pid/note.
57 return p.Kill()
58 }
59 if e := p.writeProcFile("note", sig.String()); e != nil {
adb0401d
ILT
60 return NewSyscallError("signal", e)
61 }
4ccad563 62 return nil
adb0401d
ILT
63}
64
593f74bb 65func (p *Process) kill() error {
4ccad563 66 if e := p.writeProcFile("ctl", "kill"); e != nil {
adb0401d
ILT
67 return NewSyscallError("kill", e)
68 }
4ccad563 69 return nil
adb0401d
ILT
70}
71
593f74bb 72func (p *Process) wait() (ps *ProcessState, err error) {
405ca104
ILT
73 var waitmsg syscall.Waitmsg
74
75 if p.Pid == -1 {
501699af 76 return nil, ErrInvalid
405ca104
ILT
77 }
78
79 for true {
80 err = syscall.Await(&waitmsg)
81
ab61e9c4 82 if err != nil {
405ca104
ILT
83 return nil, NewSyscallError("wait", err)
84 }
85
86 if waitmsg.Pid == p.Pid {
bd2e46c8 87 p.setDone()
405ca104
ILT
88 break
89 }
90 }
91
501699af
ILT
92 ps = &ProcessState{
93 pid: waitmsg.Pid,
94 status: &waitmsg,
405ca104 95 }
501699af 96 return ps, nil
405ca104
ILT
97}
98
593f74bb 99func (p *Process) release() error {
405ca104
ILT
100 // NOOP for Plan 9.
101 p.Pid = -1
102 // no need for a finalizer anymore
103 runtime.SetFinalizer(p, nil)
104 return nil
105}
106
af92e385 107func findProcess(pid int) (p *Process, err error) {
405ca104
ILT
108 // NOOP for Plan 9.
109 return newProcess(pid, 0), nil
110}
111
593f74bb 112// ProcessState stores information about a process, as reported by Wait.
501699af
ILT
113type ProcessState struct {
114 pid int // The process's id.
115 status *syscall.Waitmsg // System-dependent status info.
116}
117
118// Pid returns the process id of the exited process.
119func (p *ProcessState) Pid() int {
120 return p.pid
121}
122
593f74bb 123func (p *ProcessState) exited() bool {
501699af
ILT
124 return p.status.Exited()
125}
126
593f74bb 127func (p *ProcessState) success() bool {
501699af
ILT
128 return p.status.ExitStatus() == 0
129}
130
593f74bb 131func (p *ProcessState) sys() interface{} {
501699af
ILT
132 return p.status
133}
134
593f74bb 135func (p *ProcessState) sysUsage() interface{} {
501699af
ILT
136 return p.status
137}
138
593f74bb 139func (p *ProcessState) userTime() time.Duration {
501699af
ILT
140 return time.Duration(p.status.Time[0]) * time.Millisecond
141}
142
593f74bb 143func (p *ProcessState) systemTime() time.Duration {
501699af
ILT
144 return time.Duration(p.status.Time[1]) * time.Millisecond
145}
146
147func (p *ProcessState) String() string {
148 if p == nil {
adb0401d
ILT
149 return "<nil>"
150 }
501699af 151 return "exit status: " + p.status.Msg
405ca104 152}