blob: 676be36ac775e10b269d6164a1dbe87fde26f701 [file] [log] [blame]
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -07001// 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 (
Anthony Martincabe0e62011-11-08 09:06:02 -05008 "errors"
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -07009 "runtime"
10 "syscall"
Rob Pikeccacab62012-02-21 14:10:34 +110011 "time"
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070012)
13
Anthony Martinfe5005f2012-05-04 03:44:41 -070014// 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
Russ Cox30db6d42012-03-01 21:56:54 -050022func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070023 sysattr := &syscall.ProcAttr{
24 Dir: attr.Dir,
25 Env: attr.Env,
Russ Cox4d0f2e92011-06-14 10:49:34 -040026 Sys: attr.Sys,
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070027 }
28
David du Colombier11f4a6c2012-02-16 14:04:51 -050029 for _, f := range attr.Files {
30 sysattr.Files = append(sysattr.Files, f.Fd())
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070031 }
32
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070033 pid, h, e := syscall.StartProcess(name, argv, sysattr)
Russ Coxc017a822011-11-13 22:44:52 -050034 if e != nil {
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070035 return nil, &PathError{"fork/exec", name, e}
36 }
37
38 return newProcess(pid, h), nil
39}
40
Anthony Martinfe5005f2012-05-04 03:44:41 -070041func (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
Yuval Pavel Zholkover0bf36ce2011-07-13 16:29:37 -070049}
50
Russ Cox30db6d42012-03-01 21:56:54 -050051func (p *Process) signal(sig Signal) error {
Dave Cheney122a5582012-08-21 10:41:31 +100052 if p.done() {
Anthony Martincabe0e62011-11-08 09:06:02 -050053 return errors.New("os: process already finished")
Yuval Pavel Zholkover0bf36ce2011-07-13 16:29:37 -070054 }
Anthony Martinfe5005f2012-05-04 03:44:41 -070055 if e := p.writeProcFile("note", sig.String()); e != nil {
Yuval Pavel Zholkover0bf36ce2011-07-13 16:29:37 -070056 return NewSyscallError("signal", e)
57 }
Anthony Martinfe5005f2012-05-04 03:44:41 -070058 return nil
Yuval Pavel Zholkover0bf36ce2011-07-13 16:29:37 -070059}
60
Russ Cox30db6d42012-03-01 21:56:54 -050061func (p *Process) kill() error {
Anthony Martin189397d2014-03-12 18:12:56 -070062 return p.signal(Kill)
Yuval Pavel Zholkover18112432011-06-14 11:20:34 -040063}
64
Russ Cox30db6d42012-03-01 21:56:54 -050065func (p *Process) wait() (ps *ProcessState, err error) {
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070066 var waitmsg syscall.Waitmsg
67
68 if p.Pid == -1 {
Rob Pike56069f02012-02-17 10:04:29 +110069 return nil, ErrInvalid
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070070 }
Akshat Kumarb6284702013-01-18 16:43:25 -050071 err = syscall.WaitProcess(p.Pid, &waitmsg)
72 if err != nil {
73 return nil, NewSyscallError("wait", err)
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070074 }
75
Akshat Kumarb6284702013-01-18 16:43:25 -050076 p.setDone()
Rob Pikeccacab62012-02-21 14:10:34 +110077 ps = &ProcessState{
78 pid: waitmsg.Pid,
Rob Pike880cda52012-02-23 07:51:49 +110079 status: &waitmsg,
Rob Pikeccacab62012-02-21 14:10:34 +110080 }
81 return ps, nil
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070082}
83
Alex Brainmaned238ca2012-03-01 17:36:35 +110084func (p *Process) release() error {
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070085 // NOOP for Plan 9.
86 p.Pid = -1
87 // no need for a finalizer anymore
88 runtime.SetFinalizer(p, nil)
89 return nil
90}
91
Alex Brainman994e0642012-01-17 16:51:54 +110092func findProcess(pid int) (p *Process, err error) {
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -070093 // NOOP for Plan 9.
94 return newProcess(pid, 0), nil
95}
96
Rob Pike36d9ee42012-03-02 14:07:26 +110097// ProcessState stores information about a process, as reported by Wait.
Rob Pikeccacab62012-02-21 14:10:34 +110098type ProcessState struct {
Rob Pike880cda52012-02-23 07:51:49 +110099 pid int // The process's id.
100 status *syscall.Waitmsg // System-dependent status info.
Rob Pikeccacab62012-02-21 14:10:34 +1100101}
102
103// Pid returns the process id of the exited process.
104func (p *ProcessState) Pid() int {
105 return p.pid
106}
107
Russ Cox30db6d42012-03-01 21:56:54 -0500108func (p *ProcessState) exited() bool {
Rob Pikeccacab62012-02-21 14:10:34 +1100109 return p.status.Exited()
110}
111
Russ Cox30db6d42012-03-01 21:56:54 -0500112func (p *ProcessState) success() bool {
Rob Pikeccacab62012-02-21 14:10:34 +1100113 return p.status.ExitStatus() == 0
114}
115
Russ Cox30db6d42012-03-01 21:56:54 -0500116func (p *ProcessState) sys() interface{} {
Rob Pike880cda52012-02-23 07:51:49 +1100117 return p.status
Rob Pikeccacab62012-02-21 14:10:34 +1100118}
119
Russ Cox30db6d42012-03-01 21:56:54 -0500120func (p *ProcessState) sysUsage() interface{} {
Rob Pike880cda52012-02-23 07:51:49 +1100121 return p.status
Rob Pikeccacab62012-02-21 14:10:34 +1100122}
123
Russ Cox30db6d42012-03-01 21:56:54 -0500124func (p *ProcessState) userTime() time.Duration {
Rob Pikeccacab62012-02-21 14:10:34 +1100125 return time.Duration(p.status.Time[0]) * time.Millisecond
126}
127
Russ Cox30db6d42012-03-01 21:56:54 -0500128func (p *ProcessState) systemTime() time.Duration {
Rob Pikeccacab62012-02-21 14:10:34 +1100129 return time.Duration(p.status.Time[1]) * time.Millisecond
130}
131
132func (p *ProcessState) String() string {
133 if p == nil {
Graham Millercf201ed2011-06-20 15:42:17 -0400134 return "<nil>"
135 }
Rob Pikeccacab62012-02-21 14:10:34 +1100136 return "exit status: " + p.status.Msg
Yuval Pavel Zholkoverc256f0a2011-04-02 14:28:58 -0700137}