[1/7] Preprocessor cleanup
[official-gcc.git] / libgo / go / os / exec_plan9.go
blob6b4d28c93da5f0aea58633104463b4fe1f69898d
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.
5 package os
7 import (
8 "errors"
9 "runtime"
10 "syscall"
11 "time"
14 // The only signal values guaranteed to be present in the os package
15 // on all systems are Interrupt (send the process an interrupt) and
16 // Kill (force the process to exit). Interrupt is not implemented on
17 // Windows; using it with os.Process.Signal will return an error.
18 var (
19 Interrupt Signal = syscall.Note("interrupt")
20 Kill Signal = syscall.Note("kill")
23 func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
24 sysattr := &syscall.ProcAttr{
25 Dir: attr.Dir,
26 Env: attr.Env,
27 Sys: attr.Sys,
30 for _, f := range attr.Files {
31 sysattr.Files = append(sysattr.Files, f.Fd())
34 pid, h, e := syscall.StartProcess(name, argv, sysattr)
35 if e != nil {
36 return nil, &PathError{"fork/exec", name, e}
39 return newProcess(pid, h), nil
42 func (p *Process) writeProcFile(file string, data string) error {
43 f, e := OpenFile("/proc/"+itoa(p.Pid)+"/"+file, O_WRONLY, 0)
44 if e != nil {
45 return e
47 defer f.Close()
48 _, e = f.Write([]byte(data))
49 return e
52 func (p *Process) signal(sig Signal) error {
53 if p.done() {
54 return errors.New("os: process already finished")
56 if e := p.writeProcFile("note", sig.String()); e != nil {
57 return NewSyscallError("signal", e)
59 return nil
62 func (p *Process) kill() error {
63 return p.signal(Kill)
66 func (p *Process) wait() (ps *ProcessState, err error) {
67 var waitmsg syscall.Waitmsg
69 if p.Pid == -1 {
70 return nil, ErrInvalid
72 err = syscall.WaitProcess(p.Pid, &waitmsg)
73 if err != nil {
74 return nil, NewSyscallError("wait", err)
77 p.setDone()
78 ps = &ProcessState{
79 pid: waitmsg.Pid,
80 status: &waitmsg,
82 return ps, nil
85 func (p *Process) release() error {
86 // NOOP for Plan 9.
87 p.Pid = -1
88 // no need for a finalizer anymore
89 runtime.SetFinalizer(p, nil)
90 return nil
93 func findProcess(pid int) (p *Process, err error) {
94 // NOOP for Plan 9.
95 return newProcess(pid, 0), nil
98 // ProcessState stores information about a process, as reported by Wait.
99 type ProcessState struct {
100 pid int // The process's id.
101 status *syscall.Waitmsg // System-dependent status info.
104 // Pid returns the process id of the exited process.
105 func (p *ProcessState) Pid() int {
106 return p.pid
109 func (p *ProcessState) exited() bool {
110 return p.status.Exited()
113 func (p *ProcessState) success() bool {
114 return p.status.ExitStatus() == 0
117 func (p *ProcessState) sys() interface{} {
118 return p.status
121 func (p *ProcessState) sysUsage() interface{} {
122 return p.status
125 func (p *ProcessState) userTime() time.Duration {
126 return time.Duration(p.status.Time[0]) * time.Millisecond
129 func (p *ProcessState) systemTime() time.Duration {
130 return time.Duration(p.status.Time[1]) * time.Millisecond
133 func (p *ProcessState) String() string {
134 if p == nil {
135 return "<nil>"
137 return "exit status: " + p.status.Msg