summaryrefslogtreecommitdiff
path: root/vendor/github.com/mitchellh/go-ps
diff options
context:
space:
mode:
authorKali Kaneko (leap communications) <kali@leap.se>2019-01-12 18:39:45 +0100
committerRuben Pollan <meskio@sindominio.net>2019-01-17 12:30:32 +0100
commitb1247d2d0d51108c910a73891ff3116e5f032ab1 (patch)
treee9948964f0bfb1ad2df3bc7bad02aa1f41ccfbd8 /vendor/github.com/mitchellh/go-ps
parentefcb8312e31b5c2261b1a1e95ace55b322cfcc27 (diff)
[pkg] all your deps are vendored to us
Diffstat (limited to 'vendor/github.com/mitchellh/go-ps')
-rw-r--r--vendor/github.com/mitchellh/go-ps/LICENSE.md21
-rw-r--r--vendor/github.com/mitchellh/go-ps/README.md34
-rw-r--r--vendor/github.com/mitchellh/go-ps/Vagrantfile43
-rw-r--r--vendor/github.com/mitchellh/go-ps/process.go40
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_darwin.go138
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_darwin_test.go11
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_freebsd.go260
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_linux.go35
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_solaris.go96
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_test.go45
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_unix.go101
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_unix_test.go11
-rw-r--r--vendor/github.com/mitchellh/go-ps/process_windows.go119
13 files changed, 954 insertions, 0 deletions
diff --git a/vendor/github.com/mitchellh/go-ps/LICENSE.md b/vendor/github.com/mitchellh/go-ps/LICENSE.md
new file mode 100644
index 0000000..2298515
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Mitchell Hashimoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/go-ps/README.md b/vendor/github.com/mitchellh/go-ps/README.md
new file mode 100644
index 0000000..8e8baf9
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/README.md
@@ -0,0 +1,34 @@
+# Process List Library for Go
+
+go-ps is a library for Go that implements OS-specific APIs to list and
+manipulate processes in a platform-safe way. The library can find and
+list processes on Linux, Mac OS X, Solaris, and Windows.
+
+If you're new to Go, this library has a good amount of advanced Go educational
+value as well. It uses some advanced features of Go: build tags, accessing
+DLL methods for Windows, cgo for Darwin, etc.
+
+How it works:
+
+ * **Darwin** uses the `sysctl` syscall to retrieve the process table.
+ * **Unix** uses the procfs at `/proc` to inspect the process tree.
+ * **Windows** uses the Windows API, and methods such as
+ `CreateToolhelp32Snapshot` to get a point-in-time snapshot of
+ the process table.
+
+## Installation
+
+Install using standard `go get`:
+
+```
+$ go get github.com/mitchellh/go-ps
+...
+```
+
+## TODO
+
+Want to contribute? Here is a short TODO list of things that aren't
+implemented for this library that would be nice:
+
+ * FreeBSD support
+ * Plan9 support
diff --git a/vendor/github.com/mitchellh/go-ps/Vagrantfile b/vendor/github.com/mitchellh/go-ps/Vagrantfile
new file mode 100644
index 0000000..61662ab
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/Vagrantfile
@@ -0,0 +1,43 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+VAGRANTFILE_API_VERSION = "2"
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+ config.vm.box = "chef/ubuntu-12.04"
+
+ config.vm.provision "shell", inline: $script
+
+ ["vmware_fusion", "vmware_workstation"].each do |p|
+ config.vm.provider "p" do |v|
+ v.vmx["memsize"] = "1024"
+ v.vmx["numvcpus"] = "2"
+ v.vmx["cpuid.coresPerSocket"] = "1"
+ end
+ end
+end
+
+$script = <<SCRIPT
+SRCROOT="/opt/go"
+
+# Install Go
+sudo apt-get update
+sudo apt-get install -y build-essential mercurial
+sudo hg clone -u release https://code.google.com/p/go ${SRCROOT}
+cd ${SRCROOT}/src
+sudo ./all.bash
+
+# Setup the GOPATH
+sudo mkdir -p /opt/gopath
+cat <<EOF >/tmp/gopath.sh
+export GOPATH="/opt/gopath"
+export PATH="/opt/go/bin:\$GOPATH/bin:\$PATH"
+EOF
+sudo mv /tmp/gopath.sh /etc/profile.d/gopath.sh
+sudo chmod 0755 /etc/profile.d/gopath.sh
+
+# Make sure the gopath is usable by bamboo
+sudo chown -R vagrant:vagrant $SRCROOT
+sudo chown -R vagrant:vagrant /opt/gopath
+SCRIPT
diff --git a/vendor/github.com/mitchellh/go-ps/process.go b/vendor/github.com/mitchellh/go-ps/process.go
new file mode 100644
index 0000000..2b5e8ed
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process.go
@@ -0,0 +1,40 @@
+// ps provides an API for finding and listing processes in a platform-agnostic
+// way.
+//
+// NOTE: If you're reading these docs online via GoDocs or some other system,
+// you might only see the Unix docs. This project makes heavy use of
+// platform-specific implementations. We recommend reading the source if you
+// are interested.
+package ps
+
+// Process is the generic interface that is implemented on every platform
+// and provides common operations for processes.
+type Process interface {
+ // Pid is the process ID for this process.
+ Pid() int
+
+ // PPid is the parent process ID for this process.
+ PPid() int
+
+ // Executable name running this process. This is not a path to the
+ // executable.
+ Executable() string
+}
+
+// Processes returns all processes.
+//
+// This of course will be a point-in-time snapshot of when this method was
+// called. Some operating systems don't provide snapshot capability of the
+// process table, in which case the process table returned might contain
+// ephemeral entities that happened to be running when this was called.
+func Processes() ([]Process, error) {
+ return processes()
+}
+
+// FindProcess looks up a single process by pid.
+//
+// Process will be nil and error will be nil if a matching process is
+// not found.
+func FindProcess(pid int) (Process, error) {
+ return findProcess(pid)
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_darwin.go b/vendor/github.com/mitchellh/go-ps/process_darwin.go
new file mode 100644
index 0000000..5ee87fb
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_darwin.go
@@ -0,0 +1,138 @@
+// +build darwin
+
+package ps
+
+import (
+ "bytes"
+ "encoding/binary"
+ "syscall"
+ "unsafe"
+)
+
+type DarwinProcess struct {
+ pid int
+ ppid int
+ binary string
+}
+
+func (p *DarwinProcess) Pid() int {
+ return p.pid
+}
+
+func (p *DarwinProcess) PPid() int {
+ return p.ppid
+}
+
+func (p *DarwinProcess) Executable() string {
+ return p.binary
+}
+
+func findProcess(pid int) (Process, error) {
+ ps, err := processes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, p := range ps {
+ if p.Pid() == pid {
+ return p, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func processes() ([]Process, error) {
+ buf, err := darwinSyscall()
+ if err != nil {
+ return nil, err
+ }
+
+ procs := make([]*kinfoProc, 0, 50)
+ k := 0
+ for i := _KINFO_STRUCT_SIZE; i < buf.Len(); i += _KINFO_STRUCT_SIZE {
+ proc := &kinfoProc{}
+ err = binary.Read(bytes.NewBuffer(buf.Bytes()[k:i]), binary.LittleEndian, proc)
+ if err != nil {
+ return nil, err
+ }
+
+ k = i
+ procs = append(procs, proc)
+ }
+
+ darwinProcs := make([]Process, len(procs))
+ for i, p := range procs {
+ darwinProcs[i] = &DarwinProcess{
+ pid: int(p.Pid),
+ ppid: int(p.PPid),
+ binary: darwinCstring(p.Comm),
+ }
+ }
+
+ return darwinProcs, nil
+}
+
+func darwinCstring(s [16]byte) string {
+ i := 0
+ for _, b := range s {
+ if b != 0 {
+ i++
+ } else {
+ break
+ }
+ }
+
+ return string(s[:i])
+}
+
+func darwinSyscall() (*bytes.Buffer, error) {
+ mib := [4]int32{_CTRL_KERN, _KERN_PROC, _KERN_PROC_ALL, 0}
+ size := uintptr(0)
+
+ _, _, errno := syscall.Syscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(unsafe.Pointer(&mib[0])),
+ 4,
+ 0,
+ uintptr(unsafe.Pointer(&size)),
+ 0,
+ 0)
+
+ if errno != 0 {
+ return nil, errno
+ }
+
+ bs := make([]byte, size)
+ _, _, errno = syscall.Syscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(unsafe.Pointer(&mib[0])),
+ 4,
+ uintptr(unsafe.Pointer(&bs[0])),
+ uintptr(unsafe.Pointer(&size)),
+ 0,
+ 0)
+
+ if errno != 0 {
+ return nil, errno
+ }
+
+ return bytes.NewBuffer(bs[0:size]), nil
+}
+
+const (
+ _CTRL_KERN = 1
+ _KERN_PROC = 14
+ _KERN_PROC_ALL = 0
+ _KINFO_STRUCT_SIZE = 648
+)
+
+type kinfoProc struct {
+ _ [40]byte
+ Pid int32
+ _ [199]byte
+ Comm [16]byte
+ _ [301]byte
+ PPid int32
+ _ [84]byte
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_darwin_test.go b/vendor/github.com/mitchellh/go-ps/process_darwin_test.go
new file mode 100644
index 0000000..ee04c5c
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_darwin_test.go
@@ -0,0 +1,11 @@
+// +build darwin
+
+package ps
+
+import (
+ "testing"
+)
+
+func TestDarwinProcess_impl(t *testing.T) {
+ var _ Process = new(DarwinProcess)
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_freebsd.go b/vendor/github.com/mitchellh/go-ps/process_freebsd.go
new file mode 100644
index 0000000..0212b66
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_freebsd.go
@@ -0,0 +1,260 @@
+// +build freebsd,amd64
+
+package ps
+
+import (
+ "bytes"
+ "encoding/binary"
+ "syscall"
+ "unsafe"
+)
+
+// copied from sys/sysctl.h
+const (
+ CTL_KERN = 1 // "high kernel": proc, limits
+ KERN_PROC = 14 // struct: process entries
+ KERN_PROC_PID = 1 // by process id
+ KERN_PROC_PROC = 8 // only return procs
+ KERN_PROC_PATHNAME = 12 // path to executable
+)
+
+// copied from sys/user.h
+type Kinfo_proc struct {
+ Ki_structsize int32
+ Ki_layout int32
+ Ki_args int64
+ Ki_paddr int64
+ Ki_addr int64
+ Ki_tracep int64
+ Ki_textvp int64
+ Ki_fd int64
+ Ki_vmspace int64
+ Ki_wchan int64
+ Ki_pid int32
+ Ki_ppid int32
+ Ki_pgid int32
+ Ki_tpgid int32
+ Ki_sid int32
+ Ki_tsid int32
+ Ki_jobc [2]byte
+ Ki_spare_short1 [2]byte
+ Ki_tdev int32
+ Ki_siglist [16]byte
+ Ki_sigmask [16]byte
+ Ki_sigignore [16]byte
+ Ki_sigcatch [16]byte
+ Ki_uid int32
+ Ki_ruid int32
+ Ki_svuid int32
+ Ki_rgid int32
+ Ki_svgid int32
+ Ki_ngroups [2]byte
+ Ki_spare_short2 [2]byte
+ Ki_groups [64]byte
+ Ki_size int64
+ Ki_rssize int64
+ Ki_swrss int64
+ Ki_tsize int64
+ Ki_dsize int64
+ Ki_ssize int64
+ Ki_xstat [2]byte
+ Ki_acflag [2]byte
+ Ki_pctcpu int32
+ Ki_estcpu int32
+ Ki_slptime int32
+ Ki_swtime int32
+ Ki_cow int32
+ Ki_runtime int64
+ Ki_start [16]byte
+ Ki_childtime [16]byte
+ Ki_flag int64
+ Ki_kiflag int64
+ Ki_traceflag int32
+ Ki_stat [1]byte
+ Ki_nice [1]byte
+ Ki_lock [1]byte
+ Ki_rqindex [1]byte
+ Ki_oncpu [1]byte
+ Ki_lastcpu [1]byte
+ Ki_ocomm [17]byte
+ Ki_wmesg [9]byte
+ Ki_login [18]byte
+ Ki_lockname [9]byte
+ Ki_comm [20]byte
+ Ki_emul [17]byte
+ Ki_sparestrings [68]byte
+ Ki_spareints [36]byte
+ Ki_cr_flags int32
+ Ki_jid int32
+ Ki_numthreads int32
+ Ki_tid int32
+ Ki_pri int32
+ Ki_rusage [144]byte
+ Ki_rusage_ch [144]byte
+ Ki_pcb int64
+ Ki_kstack int64
+ Ki_udata int64
+ Ki_tdaddr int64
+ Ki_spareptrs [48]byte
+ Ki_spareint64s [96]byte
+ Ki_sflag int64
+ Ki_tdflags int64
+}
+
+// UnixProcess is an implementation of Process that contains Unix-specific
+// fields and information.
+type UnixProcess struct {
+ pid int
+ ppid int
+ state rune
+ pgrp int
+ sid int
+
+ binary string
+}
+
+func (p *UnixProcess) Pid() int {
+ return p.pid
+}
+
+func (p *UnixProcess) PPid() int {
+ return p.ppid
+}
+
+func (p *UnixProcess) Executable() string {
+ return p.binary
+}
+
+// Refresh reloads all the data associated with this process.
+func (p *UnixProcess) Refresh() error {
+
+ mib := []int32{CTL_KERN, KERN_PROC, KERN_PROC_PID, int32(p.pid)}
+
+ buf, length, err := call_syscall(mib)
+ if err != nil {
+ return err
+ }
+ proc_k := Kinfo_proc{}
+ if length != uint64(unsafe.Sizeof(proc_k)) {
+ return err
+ }
+
+ k, err := parse_kinfo_proc(buf)
+ if err != nil {
+ return err
+ }
+
+ p.ppid, p.pgrp, p.sid, p.binary = copy_params(&k)
+ return nil
+}
+
+func copy_params(k *Kinfo_proc) (int, int, int, string) {
+ n := -1
+ for i, b := range k.Ki_comm {
+ if b == 0 {
+ break
+ }
+ n = i + 1
+ }
+ comm := string(k.Ki_comm[:n])
+
+ return int(k.Ki_ppid), int(k.Ki_pgid), int(k.Ki_sid), comm
+}
+
+func findProcess(pid int) (Process, error) {
+ mib := []int32{CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, int32(pid)}
+
+ _, _, err := call_syscall(mib)
+ if err != nil {
+ return nil, err
+ }
+
+ return newUnixProcess(pid)
+}
+
+func processes() ([]Process, error) {
+ results := make([]Process, 0, 50)
+
+ mib := []int32{CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0}
+ buf, length, err := call_syscall(mib)
+ if err != nil {
+ return results, err
+ }
+
+ // get kinfo_proc size
+ k := Kinfo_proc{}
+ procinfo_len := int(unsafe.Sizeof(k))
+ count := int(length / uint64(procinfo_len))
+
+ // parse buf to procs
+ for i := 0; i < count; i++ {
+ b := buf[i*procinfo_len : i*procinfo_len+procinfo_len]
+ k, err := parse_kinfo_proc(b)
+ if err != nil {
+ continue
+ }
+ p, err := newUnixProcess(int(k.Ki_pid))
+ if err != nil {
+ continue
+ }
+ p.ppid, p.pgrp, p.sid, p.binary = copy_params(&k)
+
+ results = append(results, p)
+ }
+
+ return results, nil
+}
+
+func parse_kinfo_proc(buf []byte) (Kinfo_proc, error) {
+ var k Kinfo_proc
+ br := bytes.NewReader(buf)
+ err := binary.Read(br, binary.LittleEndian, &k)
+ if err != nil {
+ return k, err
+ }
+
+ return k, nil
+}
+
+func call_syscall(mib []int32) ([]byte, uint64, error) {
+ miblen := uint64(len(mib))
+
+ // get required buffer size
+ length := uint64(0)
+ _, _, err := syscall.RawSyscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(unsafe.Pointer(&mib[0])),
+ uintptr(miblen),
+ 0,
+ uintptr(unsafe.Pointer(&length)),
+ 0,
+ 0)
+ if err != 0 {
+ b := make([]byte, 0)
+ return b, length, err
+ }
+ if length == 0 {
+ b := make([]byte, 0)
+ return b, length, err
+ }
+ // get proc info itself
+ buf := make([]byte, length)
+ _, _, err = syscall.RawSyscall6(
+ syscall.SYS___SYSCTL,
+ uintptr(unsafe.Pointer(&mib[0])),
+ uintptr(miblen),
+ uintptr(unsafe.Pointer(&buf[0])),
+ uintptr(unsafe.Pointer(&length)),
+ 0,
+ 0)
+ if err != 0 {
+ return buf, length, err
+ }
+
+ return buf, length, nil
+}
+
+func newUnixProcess(pid int) (*UnixProcess, error) {
+ p := &UnixProcess{pid: pid}
+ return p, p.Refresh()
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_linux.go b/vendor/github.com/mitchellh/go-ps/process_linux.go
new file mode 100644
index 0000000..c1558f7
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_linux.go
@@ -0,0 +1,35 @@
+// +build linux
+
+package ps
+
+import (
+ "fmt"
+ "io/ioutil"
+ "strings"
+)
+
+// Refresh reloads all the data associated with this process.
+func (p *UnixProcess) Refresh() error {
+ statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
+ dataBytes, err := ioutil.ReadFile(statPath)
+ if err != nil {
+ return err
+ }
+
+ // First, parse out the image name
+ data := string(dataBytes)
+ binStart := strings.IndexRune(data, '(') + 1
+ binEnd := strings.IndexRune(data[binStart:], ')')
+ p.binary = data[binStart : binStart+binEnd]
+
+ // Move past the image name and start parsing the rest
+ data = data[binStart+binEnd+2:]
+ _, err = fmt.Sscanf(data,
+ "%c %d %d %d",
+ &p.state,
+ &p.ppid,
+ &p.pgrp,
+ &p.sid)
+
+ return err
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_solaris.go b/vendor/github.com/mitchellh/go-ps/process_solaris.go
new file mode 100644
index 0000000..014c416
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_solaris.go
@@ -0,0 +1,96 @@
+// +build solaris
+
+package ps
+
+import (
+ "encoding/binary"
+ "fmt"
+ "os"
+)
+
+type ushort_t uint16
+
+type id_t int32
+type pid_t int32
+type uid_t int32
+type gid_t int32
+
+type dev_t uint64
+type size_t uint64
+type uintptr_t uint64
+
+type timestruc_t [16]byte
+
+// This is copy from /usr/include/sys/procfs.h
+type psinfo_t struct {
+ Pr_flag int32 /* process flags (DEPRECATED; do not use) */
+ Pr_nlwp int32 /* number of active lwps in the process */
+ Pr_pid pid_t /* unique process id */
+ Pr_ppid pid_t /* process id of parent */
+ Pr_pgid pid_t /* pid of process group leader */
+ Pr_sid pid_t /* session id */
+ Pr_uid uid_t /* real user id */
+ Pr_euid uid_t /* effective user id */
+ Pr_gid gid_t /* real group id */
+ Pr_egid gid_t /* effective group id */
+ Pr_addr uintptr_t /* address of process */
+ Pr_size size_t /* size of process image in Kbytes */
+ Pr_rssize size_t /* resident set size in Kbytes */
+ Pr_pad1 size_t
+ Pr_ttydev dev_t /* controlling tty device (or PRNODEV) */
+
+ // Guess this following 2 ushort_t values require a padding to properly
+ // align to the 64bit mark.
+ Pr_pctcpu ushort_t /* % of recent cpu time used by all lwps */
+ Pr_pctmem ushort_t /* % of system memory used by process */
+ Pr_pad64bit [4]byte
+
+ Pr_start timestruc_t /* process start time, from the epoch */
+ Pr_time timestruc_t /* usr+sys cpu time for this process */
+ Pr_ctime timestruc_t /* usr+sys cpu time for reaped children */
+ Pr_fname [16]byte /* name of execed file */
+ Pr_psargs [80]byte /* initial characters of arg list */
+ Pr_wstat int32 /* if zombie, the wait() status */
+ Pr_argc int32 /* initial argument count */
+ Pr_argv uintptr_t /* address of initial argument vector */
+ Pr_envp uintptr_t /* address of initial environment vector */
+ Pr_dmodel [1]byte /* data model of the process */
+ Pr_pad2 [3]byte
+ Pr_taskid id_t /* task id */
+ Pr_projid id_t /* project id */
+ Pr_nzomb int32 /* number of zombie lwps in the process */
+ Pr_poolid id_t /* pool id */
+ Pr_zoneid id_t /* zone id */
+ Pr_contract id_t /* process contract */
+ Pr_filler int32 /* reserved for future use */
+ Pr_lwp [128]byte /* information for representative lwp */
+}
+
+func (p *UnixProcess) Refresh() error {
+ var psinfo psinfo_t
+
+ path := fmt.Sprintf("/proc/%d/psinfo", p.pid)
+ fh, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+ defer fh.Close()
+
+ err = binary.Read(fh, binary.LittleEndian, &psinfo)
+ if err != nil {
+ return err
+ }
+
+ p.ppid = int(psinfo.Pr_ppid)
+ p.binary = toString(psinfo.Pr_fname[:], 16)
+ return nil
+}
+
+func toString(array []byte, len int) string {
+ for i := 0; i < len; i++ {
+ if array[i] == 0 {
+ return string(array[:i])
+ }
+ }
+ return string(array[:])
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_test.go b/vendor/github.com/mitchellh/go-ps/process_test.go
new file mode 100644
index 0000000..1bcbc32
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_test.go
@@ -0,0 +1,45 @@
+package ps
+
+import (
+ "os"
+ "testing"
+)
+
+func TestFindProcess(t *testing.T) {
+ p, err := FindProcess(os.Getpid())
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+ if p == nil {
+ t.Fatal("should have process")
+ }
+
+ if p.Pid() != os.Getpid() {
+ t.Fatalf("bad: %#v", p.Pid())
+ }
+}
+
+func TestProcesses(t *testing.T) {
+ // This test works because there will always be SOME processes
+ // running.
+ p, err := Processes()
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+
+ if len(p) <= 0 {
+ t.Fatal("should have processes")
+ }
+
+ found := false
+ for _, p1 := range p {
+ if p1.Executable() == "go" || p1.Executable() == "go.exe" {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ t.Fatal("should have Go")
+ }
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_unix.go b/vendor/github.com/mitchellh/go-ps/process_unix.go
new file mode 100644
index 0000000..3b733ce
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_unix.go
@@ -0,0 +1,101 @@
+// +build linux solaris
+
+package ps
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+)
+
+// UnixProcess is an implementation of Process that contains Unix-specific
+// fields and information.
+type UnixProcess struct {
+ pid int
+ ppid int
+ state rune
+ pgrp int
+ sid int
+
+ binary string
+}
+
+func (p *UnixProcess) Pid() int {
+ return p.pid
+}
+
+func (p *UnixProcess) PPid() int {
+ return p.ppid
+}
+
+func (p *UnixProcess) Executable() string {
+ return p.binary
+}
+
+func findProcess(pid int) (Process, error) {
+ dir := fmt.Sprintf("/proc/%d", pid)
+ _, err := os.Stat(dir)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil, nil
+ }
+
+ return nil, err
+ }
+
+ return newUnixProcess(pid)
+}
+
+func processes() ([]Process, error) {
+ d, err := os.Open("/proc")
+ if err != nil {
+ return nil, err
+ }
+ defer d.Close()
+
+ results := make([]Process, 0, 50)
+ for {
+ fis, err := d.Readdir(10)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ for _, fi := range fis {
+ // We only care about directories, since all pids are dirs
+ if !fi.IsDir() {
+ continue
+ }
+
+ // We only care if the name starts with a numeric
+ name := fi.Name()
+ if name[0] < '0' || name[0] > '9' {
+ continue
+ }
+
+ // From this point forward, any errors we just ignore, because
+ // it might simply be that the process doesn't exist anymore.
+ pid, err := strconv.ParseInt(name, 10, 0)
+ if err != nil {
+ continue
+ }
+
+ p, err := newUnixProcess(int(pid))
+ if err != nil {
+ continue
+ }
+
+ results = append(results, p)
+ }
+ }
+
+ return results, nil
+}
+
+func newUnixProcess(pid int) (*UnixProcess, error) {
+ p := &UnixProcess{pid: pid}
+ return p, p.Refresh()
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_unix_test.go b/vendor/github.com/mitchellh/go-ps/process_unix_test.go
new file mode 100644
index 0000000..754073e
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_unix_test.go
@@ -0,0 +1,11 @@
+// +build linux solaris
+
+package ps
+
+import (
+ "testing"
+)
+
+func TestUnixProcess_impl(t *testing.T) {
+ var _ Process = new(UnixProcess)
+}
diff --git a/vendor/github.com/mitchellh/go-ps/process_windows.go b/vendor/github.com/mitchellh/go-ps/process_windows.go
new file mode 100644
index 0000000..f151974
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-ps/process_windows.go
@@ -0,0 +1,119 @@
+// +build windows
+
+package ps
+
+import (
+ "fmt"
+ "syscall"
+ "unsafe"
+)
+
+// Windows API functions
+var (
+ modKernel32 = syscall.NewLazyDLL("kernel32.dll")
+ procCloseHandle = modKernel32.NewProc("CloseHandle")
+ procCreateToolhelp32Snapshot = modKernel32.NewProc("CreateToolhelp32Snapshot")
+ procProcess32First = modKernel32.NewProc("Process32FirstW")
+ procProcess32Next = modKernel32.NewProc("Process32NextW")
+)
+
+// Some constants from the Windows API
+const (
+ ERROR_NO_MORE_FILES = 0x12
+ MAX_PATH = 260
+)
+
+// PROCESSENTRY32 is the Windows API structure that contains a process's
+// information.
+type PROCESSENTRY32 struct {
+ Size uint32
+ CntUsage uint32
+ ProcessID uint32
+ DefaultHeapID uintptr
+ ModuleID uint32
+ CntThreads uint32
+ ParentProcessID uint32
+ PriorityClassBase int32
+ Flags uint32
+ ExeFile [MAX_PATH]uint16
+}
+
+// WindowsProcess is an implementation of Process for Windows.
+type WindowsProcess struct {
+ pid int
+ ppid int
+ exe string
+}
+
+func (p *WindowsProcess) Pid() int {
+ return p.pid
+}
+
+func (p *WindowsProcess) PPid() int {
+ return p.ppid
+}
+
+func (p *WindowsProcess) Executable() string {
+ return p.exe
+}
+
+func newWindowsProcess(e *PROCESSENTRY32) *WindowsProcess {
+ // Find when the string ends for decoding
+ end := 0
+ for {
+ if e.ExeFile[end] == 0 {
+ break
+ }
+ end++
+ }
+
+ return &WindowsProcess{
+ pid: int(e.ProcessID),
+ ppid: int(e.ParentProcessID),
+ exe: syscall.UTF16ToString(e.ExeFile[:end]),
+ }
+}
+
+func findProcess(pid int) (Process, error) {
+ ps, err := processes()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, p := range ps {
+ if p.Pid() == pid {
+ return p, nil
+ }
+ }
+
+ return nil, nil
+}
+
+func processes() ([]Process, error) {
+ handle, _, _ := procCreateToolhelp32Snapshot.Call(
+ 0x00000002,
+ 0)
+ if handle < 0 {
+ return nil, syscall.GetLastError()
+ }
+ defer procCloseHandle.Call(handle)
+
+ var entry PROCESSENTRY32
+ entry.Size = uint32(unsafe.Sizeof(entry))
+ ret, _, _ := procProcess32First.Call(handle, uintptr(unsafe.Pointer(&entry)))
+ if ret == 0 {
+ return nil, fmt.Errorf("Error retrieving process info.")
+ }
+
+ results := make([]Process, 0, 50)
+ for {
+ results = append(results, newWindowsProcess(&entry))
+
+ ret, _, _ := procProcess32Next.Call(handle, uintptr(unsafe.Pointer(&entry)))
+ if ret == 0 {
+ break
+ }
+ }
+
+ return results, nil
+}