vendorify
diff --git a/go/vendor/github.com/shirou/gopsutil/internal/common/common.go b/go/vendor/github.com/shirou/gopsutil/internal/common/common.go
new file mode 100644
index 0000000..71c2257
--- /dev/null
+++ b/go/vendor/github.com/shirou/gopsutil/internal/common/common.go
@@ -0,0 +1,392 @@
+package common
+
+//
+// gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
+// This covers these architectures.
+//  - linux (amd64, arm)
+//  - freebsd (amd64)
+//  - windows (amd64)
+import (
+	"bufio"
+	"bytes"
+	"context"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"net/url"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	Timeout    = 3 * time.Second
+	ErrTimeout = errors.New("command timed out")
+)
+
+type Invoker interface {
+	Command(string, ...string) ([]byte, error)
+	CommandWithContext(context.Context, string, ...string) ([]byte, error)
+}
+
+type Invoke struct{}
+
+func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), Timeout)
+	defer cancel()
+	return i.CommandWithContext(ctx, name, arg...)
+}
+
+func (i Invoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) {
+	cmd := exec.CommandContext(ctx, name, arg...)
+
+	var buf bytes.Buffer
+	cmd.Stdout = &buf
+	cmd.Stderr = &buf
+
+	if err := cmd.Start(); err != nil {
+		return buf.Bytes(), err
+	}
+
+	if err := cmd.Wait(); err != nil {
+		return buf.Bytes(), err
+	}
+
+	return buf.Bytes(), nil
+}
+
+type FakeInvoke struct {
+	Suffix string // Suffix species expected file name suffix such as "fail"
+	Error  error  // If Error specfied, return the error.
+}
+
+// Command in FakeInvoke returns from expected file if exists.
+func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
+	if i.Error != nil {
+		return []byte{}, i.Error
+	}
+
+	arch := runtime.GOOS
+
+	commandName := filepath.Base(name)
+
+	fname := strings.Join(append([]string{commandName}, arg...), "")
+	fname = url.QueryEscape(fname)
+	fpath := path.Join("testdata", arch, fname)
+	if i.Suffix != "" {
+		fpath += "_" + i.Suffix
+	}
+	if PathExists(fpath) {
+		return ioutil.ReadFile(fpath)
+	}
+	return []byte{}, fmt.Errorf("could not find testdata: %s", fpath)
+}
+
+func (i FakeInvoke) CommandWithContext(ctx context.Context, name string, arg ...string) ([]byte, error) {
+	return i.Command(name, arg...)
+}
+
+var ErrNotImplementedError = errors.New("not implemented yet")
+
+// ReadLines reads contents from a file and splits them by new lines.
+// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
+func ReadLines(filename string) ([]string, error) {
+	return ReadLinesOffsetN(filename, 0, -1)
+}
+
+// ReadLines reads contents from file and splits them by new line.
+// The offset tells at which line number to start.
+// The count determines the number of lines to read (starting from offset):
+//   n >= 0: at most n lines
+//   n < 0: whole file
+func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return []string{""}, err
+	}
+	defer f.Close()
+
+	var ret []string
+
+	r := bufio.NewReader(f)
+	for i := 0; i < n+int(offset) || n < 0; i++ {
+		line, err := r.ReadString('\n')
+		if err != nil {
+			break
+		}
+		if i < int(offset) {
+			continue
+		}
+		ret = append(ret, strings.Trim(line, "\n"))
+	}
+
+	return ret, nil
+}
+
+func IntToString(orig []int8) string {
+	ret := make([]byte, len(orig))
+	size := -1
+	for i, o := range orig {
+		if o == 0 {
+			size = i
+			break
+		}
+		ret[i] = byte(o)
+	}
+	if size == -1 {
+		size = len(orig)
+	}
+
+	return string(ret[0:size])
+}
+
+func UintToString(orig []uint8) string {
+	ret := make([]byte, len(orig))
+	size := -1
+	for i, o := range orig {
+		if o == 0 {
+			size = i
+			break
+		}
+		ret[i] = byte(o)
+	}
+	if size == -1 {
+		size = len(orig)
+	}
+
+	return string(ret[0:size])
+}
+
+func ByteToString(orig []byte) string {
+	n := -1
+	l := -1
+	for i, b := range orig {
+		// skip left side null
+		if l == -1 && b == 0 {
+			continue
+		}
+		if l == -1 {
+			l = i
+		}
+
+		if b == 0 {
+			break
+		}
+		n = i + 1
+	}
+	if n == -1 {
+		return string(orig)
+	}
+	return string(orig[l:n])
+}
+
+// ReadInts reads contents from single line file and returns them as []int32.
+func ReadInts(filename string) ([]int64, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return []int64{}, err
+	}
+	defer f.Close()
+
+	var ret []int64
+
+	r := bufio.NewReader(f)
+
+	// The int files that this is concerned with should only be one liners.
+	line, err := r.ReadString('\n')
+	if err != nil {
+		return []int64{}, err
+	}
+
+	i, err := strconv.ParseInt(strings.Trim(line, "\n"), 10, 32)
+	if err != nil {
+		return []int64{}, err
+	}
+	ret = append(ret, i)
+
+	return ret, nil
+}
+
+// Parse to int32 without error
+func mustParseInt32(val string) int32 {
+	vv, _ := strconv.ParseInt(val, 10, 32)
+	return int32(vv)
+}
+
+// Parse to uint64 without error
+func mustParseUint64(val string) uint64 {
+	vv, _ := strconv.ParseInt(val, 10, 64)
+	return uint64(vv)
+}
+
+// Parse to Float64 without error
+func mustParseFloat64(val string) float64 {
+	vv, _ := strconv.ParseFloat(val, 64)
+	return vv
+}
+
+// StringsHas checks the target string slice contains src or not
+func StringsHas(target []string, src string) bool {
+	for _, t := range target {
+		if strings.TrimSpace(t) == src {
+			return true
+		}
+	}
+	return false
+}
+
+// StringsContains checks the src in any string of the target string slice
+func StringsContains(target []string, src string) bool {
+	for _, t := range target {
+		if strings.Contains(t, src) {
+			return true
+		}
+	}
+	return false
+}
+
+// IntContains checks the src in any int of the target int slice.
+func IntContains(target []int, src int) bool {
+	for _, t := range target {
+		if src == t {
+			return true
+		}
+	}
+	return false
+}
+
+// get struct attributes.
+// This method is used only for debugging platform dependent code.
+func attributes(m interface{}) map[string]reflect.Type {
+	typ := reflect.TypeOf(m)
+	if typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+	}
+
+	attrs := make(map[string]reflect.Type)
+	if typ.Kind() != reflect.Struct {
+		return nil
+	}
+
+	for i := 0; i < typ.NumField(); i++ {
+		p := typ.Field(i)
+		if !p.Anonymous {
+			attrs[p.Name] = p.Type
+		}
+	}
+
+	return attrs
+}
+
+func PathExists(filename string) bool {
+	if _, err := os.Stat(filename); err == nil {
+		return true
+	}
+	return false
+}
+
+//GetEnv retrieves the environment variable key. If it does not exist it returns the default.
+func GetEnv(key string, dfault string, combineWith ...string) string {
+	value := os.Getenv(key)
+	if value == "" {
+		value = dfault
+	}
+
+	switch len(combineWith) {
+	case 0:
+		return value
+	case 1:
+		return filepath.Join(value, combineWith[0])
+	default:
+		all := make([]string, len(combineWith)+1)
+		all[0] = value
+		copy(all[1:], combineWith)
+		return filepath.Join(all...)
+	}
+	panic("invalid switch case")
+}
+
+func HostProc(combineWith ...string) string {
+	return GetEnv("HOST_PROC", "/proc", combineWith...)
+}
+
+func HostSys(combineWith ...string) string {
+	return GetEnv("HOST_SYS", "/sys", combineWith...)
+}
+
+func HostEtc(combineWith ...string) string {
+	return GetEnv("HOST_ETC", "/etc", combineWith...)
+}
+
+func HostVar(combineWith ...string) string {
+	return GetEnv("HOST_VAR", "/var", combineWith...)
+}
+
+func HostRun(combineWith ...string) string {
+	return GetEnv("HOST_RUN", "/run", combineWith...)
+}
+
+// https://gist.github.com/kylelemons/1525278
+func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) {
+	// Require at least one command
+	if len(cmds) < 1 {
+		return nil, nil, nil
+	}
+
+	// Collect the output from the command(s)
+	var output bytes.Buffer
+	var stderr bytes.Buffer
+
+	last := len(cmds) - 1
+	for i, cmd := range cmds[:last] {
+		var err error
+		// Connect each command's stdin to the previous command's stdout
+		if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil {
+			return nil, nil, err
+		}
+		// Connect each command's stderr to a buffer
+		cmd.Stderr = &stderr
+	}
+
+	// Connect the output and error for the last command
+	cmds[last].Stdout, cmds[last].Stderr = &output, &stderr
+
+	// Start each command
+	for _, cmd := range cmds {
+		if err := cmd.Start(); err != nil {
+			return output.Bytes(), stderr.Bytes(), err
+		}
+	}
+
+	// Wait for each command to complete
+	for _, cmd := range cmds {
+		if err := cmd.Wait(); err != nil {
+			return output.Bytes(), stderr.Bytes(), err
+		}
+	}
+
+	// Return the pipeline output and the collected standard error
+	return output.Bytes(), stderr.Bytes(), nil
+}
+
+// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running
+// sysctl commands (see DoSysctrl).
+func getSysctrlEnv(env []string) []string {
+	foundLC := false
+	for i, line := range env {
+		if strings.HasPrefix(line, "LC_ALL") {
+			env[i] = "LC_ALL=C"
+			foundLC = true
+		}
+	}
+	if !foundLC {
+		env = append(env, "LC_ALL=C")
+	}
+	return env
+}