Daily bump.
[official-gcc.git] / libgo / go / os / exec_plan9.go
blob2bd5b6888d98b07a0ec2acef6336e9c9ab638fa8
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 on all systems
15 // are Interrupt (send the process an interrupt) and Kill (force
16 // the process to exit).
17 var (
18 Interrupt Signal = syscall.Note("interrupt")
19 Kill Signal = syscall.Note("kill")
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,
29 for _, f := range attr.Files {
30 sysattr.Files = append(sysattr.Files, f.Fd())
33 pid, h, e := syscall.StartProcess(name, argv, sysattr)
34 if e != nil {
35 return nil, &PathError{"fork/exec", name, e}
38 return newProcess(pid, h), nil
41 func (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
46 defer f.Close()
47 _, e = f.Write([]byte(data))
48 return e
51 func (p *Process) signal(sig Signal) error {
52 if p.done() {
53 return errors.New("os: process already finished")
55 if sig == Kill {
56 // Special-case the kill signal since it doesn't use /proc/$pid/note.
57 return p.Kill()
59 if e := p.writeProcFile("note", sig.String()); e != nil {
60 return NewSyscallError("signal", e)
62 return nil
65 func (p *Process) kill() error {
66 if e := p.writeProcFile("ctl", "kill"); e != nil {
67 return NewSyscallError("kill", e)
69 return nil
72 func (p *Process) wait() (ps *ProcessState, err error) {
73 var waitmsg syscall.Waitmsg
75 if p.Pid == -1 {
76 return nil, ErrInvalid
78 err = syscall.WaitProcess(p.Pid, &waitmsg)
79 if err != nil {
80 return nil, NewSyscallError("wait", err)
83 p.setDone()
84 ps = &ProcessState{
85 pid: waitmsg.Pid,
86 status: &waitmsg,
88 return ps, nil
91 func (p *Process) release() error {
92 // NOOP for Plan 9.
93 p.Pid = -1
94 // no need for a finalizer anymore
95 runtime.SetFinalizer(p, nil)
96 return nil
99 func findProcess(pid int) (p *Process, err error) {
100 // NOOP for Plan 9.
101 return newProcess(pid, 0), nil
104 // ProcessState stores information about a process, as reported by Wait.
105 type ProcessState struct {
106 pid int // The process's id.
107 status *syscall.Waitmsg // System-dependent status info.
110 // Pid returns the process id of the exited process.
111 func (p *ProcessState) Pid() int {
112 return p.pid
115 func (p *ProcessState) exited() bool {
116 return p.status.Exited()
119 func (p *ProcessState) success() bool {
120 return p.status.ExitStatus() == 0
123 func (p *ProcessState) sys() interface{} {
124 return p.status
127 func (p *ProcessState) sysUsage() interface{} {
128 return p.status
131 func (p *ProcessState) userTime() time.Duration {
132 return time.Duration(p.status.Time[0]) * time.Millisecond
135 func (p *ProcessState) systemTime() time.Duration {
136 return time.Duration(p.status.Time[1]) * time.Millisecond
139 func (p *ProcessState) String() string {
140 if p == nil {
141 return "<nil>"
143 return "exit status: " + p.status.Msg