Rebase.
[official-gcc.git] / libgo / go / os / exec_plan9.go
blob676be36ac775e10b269d6164a1dbe87fde26f701
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 e := p.writeProcFile("note", sig.String()); e != nil {
56 return NewSyscallError("signal", e)
58 return nil
61 func (p *Process) kill() error {
62 return p.signal(Kill)
65 func (p *Process) wait() (ps *ProcessState, err error) {
66 var waitmsg syscall.Waitmsg
68 if p.Pid == -1 {
69 return nil, ErrInvalid
71 err = syscall.WaitProcess(p.Pid, &waitmsg)
72 if err != nil {
73 return nil, NewSyscallError("wait", err)
76 p.setDone()
77 ps = &ProcessState{
78 pid: waitmsg.Pid,
79 status: &waitmsg,
81 return ps, nil
84 func (p *Process) release() error {
85 // NOOP for Plan 9.
86 p.Pid = -1
87 // no need for a finalizer anymore
88 runtime.SetFinalizer(p, nil)
89 return nil
92 func findProcess(pid int) (p *Process, err error) {
93 // NOOP for Plan 9.
94 return newProcess(pid, 0), nil
97 // ProcessState stores information about a process, as reported by Wait.
98 type ProcessState struct {
99 pid int // The process's id.
100 status *syscall.Waitmsg // System-dependent status info.
103 // Pid returns the process id of the exited process.
104 func (p *ProcessState) Pid() int {
105 return p.pid
108 func (p *ProcessState) exited() bool {
109 return p.status.Exited()
112 func (p *ProcessState) success() bool {
113 return p.status.ExitStatus() == 0
116 func (p *ProcessState) sys() interface{} {
117 return p.status
120 func (p *ProcessState) sysUsage() interface{} {
121 return p.status
124 func (p *ProcessState) userTime() time.Duration {
125 return time.Duration(p.status.Time[0]) * time.Millisecond
128 func (p *ProcessState) systemTime() time.Duration {
129 return time.Duration(p.status.Time[1]) * time.Millisecond
132 func (p *ProcessState) String() string {
133 if p == nil {
134 return "<nil>"
136 return "exit status: " + p.status.Msg