github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/os/exec_plan9.go (about)

     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  
     5  package os
     6  
     7  import (
     8  	"errors"
     9  	"runtime"
    10  	"syscall"
    11  	"time"
    12  )
    13  
    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")
    20  )
    21  
    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,
    27  	}
    28  
    29  	for _, f := range attr.Files {
    30  		sysattr.Files = append(sysattr.Files, f.Fd())
    31  	}
    32  
    33  	pid, h, e := syscall.StartProcess(name, argv, sysattr)
    34  	if e != nil {
    35  		return nil, &PathError{"fork/exec", name, e}
    36  	}
    37  
    38  	return newProcess(pid, h), nil
    39  }
    40  
    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
    45  	}
    46  	defer f.Close()
    47  	_, e = f.Write([]byte(data))
    48  	return e
    49  }
    50  
    51  func (p *Process) signal(sig Signal) error {
    52  	if p.done() {
    53  		return errors.New("os: process already finished")
    54  	}
    55  	if e := p.writeProcFile("note", sig.String()); e != nil {
    56  		return NewSyscallError("signal", e)
    57  	}
    58  	return nil
    59  }
    60  
    61  func (p *Process) kill() error {
    62  	return p.signal(Kill)
    63  }
    64  
    65  func (p *Process) wait() (ps *ProcessState, err error) {
    66  	var waitmsg syscall.Waitmsg
    67  
    68  	if p.Pid == -1 {
    69  		return nil, ErrInvalid
    70  	}
    71  	err = syscall.WaitProcess(p.Pid, &waitmsg)
    72  	if err != nil {
    73  		return nil, NewSyscallError("wait", err)
    74  	}
    75  
    76  	p.setDone()
    77  	ps = &ProcessState{
    78  		pid:    waitmsg.Pid,
    79  		status: &waitmsg,
    80  	}
    81  	return ps, nil
    82  }
    83  
    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
    90  }
    91  
    92  func findProcess(pid int) (p *Process, err error) {
    93  	// NOOP for Plan 9.
    94  	return newProcess(pid, 0), nil
    95  }
    96  
    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.
   101  }
   102  
   103  // Pid returns the process id of the exited process.
   104  func (p *ProcessState) Pid() int {
   105  	return p.pid
   106  }
   107  
   108  func (p *ProcessState) exited() bool {
   109  	return p.status.Exited()
   110  }
   111  
   112  func (p *ProcessState) success() bool {
   113  	return p.status.ExitStatus() == 0
   114  }
   115  
   116  func (p *ProcessState) sys() interface{} {
   117  	return p.status
   118  }
   119  
   120  func (p *ProcessState) sysUsage() interface{} {
   121  	return p.status
   122  }
   123  
   124  func (p *ProcessState) userTime() time.Duration {
   125  	return time.Duration(p.status.Time[0]) * time.Millisecond
   126  }
   127  
   128  func (p *ProcessState) systemTime() time.Duration {
   129  	return time.Duration(p.status.Time[1]) * time.Millisecond
   130  }
   131  
   132  func (p *ProcessState) String() string {
   133  	if p == nil {
   134  		return "<nil>"
   135  	}
   136  	return "exit status: " + p.status.Msg
   137  }