vendor: update go-ps to not require cgo on darwin
This commit is contained in:
parent
3a9fd99cb3
commit
a23ea646f3
|
@ -0,0 +1,2 @@
|
|||
# temporary symlink for testing
|
||||
testing/data/symlink
|
|
@ -0,0 +1,27 @@
|
|||
language: go
|
||||
sudo: required
|
||||
go:
|
||||
- 1.4.2
|
||||
- 1.5.3
|
||||
- 1.6
|
||||
- tip
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
env:
|
||||
- GOARCH=amd64 DOCKER_VERSION=1.8.3
|
||||
- GOARCH=386 DOCKER_VERSION=1.8.3
|
||||
- GOARCH=amd64 DOCKER_VERSION=1.9.1
|
||||
- GOARCH=386 DOCKER_VERSION=1.9.1
|
||||
- GOARCH=amd64 DOCKER_VERSION=1.10.3
|
||||
- GOARCH=386 DOCKER_VERSION=1.10.3
|
||||
install:
|
||||
- travis_retry travis-scripts/install.bash
|
||||
script:
|
||||
- travis-scripts/run-tests.bash
|
||||
services:
|
||||
- docker
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
|
@ -10,8 +10,7 @@ DLL methods for Windows, cgo for Darwin, etc.
|
|||
|
||||
How it works:
|
||||
|
||||
* **Darwin** uses the `sysctl` syscall to retrieve the process table, via
|
||||
cgo.
|
||||
* **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
|
||||
|
@ -33,4 +32,3 @@ implemented for this library that would be nice:
|
|||
|
||||
* FreeBSD support
|
||||
* Plan9 support
|
||||
* Eliminate the need for cgo with Darwin
|
||||
|
|
|
@ -2,18 +2,13 @@
|
|||
|
||||
package ps
|
||||
|
||||
// #include "process_darwin.h"
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This lock is what verifies that C calling back into Go is only
|
||||
// modifying data once at a time.
|
||||
var darwinLock sync.Mutex
|
||||
var darwinProcs []Process
|
||||
|
||||
type DarwinProcess struct {
|
||||
pid int
|
||||
ppid int
|
||||
|
@ -32,17 +27,6 @@ func (p *DarwinProcess) Executable() string {
|
|||
return p.binary
|
||||
}
|
||||
|
||||
//export go_darwin_append_proc
|
||||
func go_darwin_append_proc(pid C.pid_t, ppid C.pid_t, comm *C.char) {
|
||||
proc := &DarwinProcess{
|
||||
pid: int(pid),
|
||||
ppid: int(ppid),
|
||||
binary: C.GoString(comm),
|
||||
}
|
||||
|
||||
darwinProcs = append(darwinProcs, proc)
|
||||
}
|
||||
|
||||
func findProcess(pid int) (Process, error) {
|
||||
ps, err := processes()
|
||||
if err != nil {
|
||||
|
@ -59,14 +43,96 @@ func findProcess(pid int) (Process, error) {
|
|||
}
|
||||
|
||||
func processes() ([]Process, error) {
|
||||
darwinLock.Lock()
|
||||
defer darwinLock.Unlock()
|
||||
darwinProcs = make([]Process, 0, 50)
|
||||
|
||||
_, err := C.darwinProcesses()
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
// +build darwin
|
||||
|
||||
#ifndef _GO_PROCESSDARWIN_H_INCLUDED
|
||||
#define _GO_PROCESSDARWIN_H_INCLUDED
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
// This is declared in process_darwin.go
|
||||
extern void go_darwin_append_proc(pid_t, pid_t, char *);
|
||||
|
||||
// Loads the process table and calls the exported Go function to insert
|
||||
// the data back into the Go space.
|
||||
//
|
||||
// This function is implemented in C because while it would technically
|
||||
// be possible to do this all in Go, I didn't want to go spelunking through
|
||||
// header files to get all the structures properly. It is much easier to just
|
||||
// call it in C and be done with it.
|
||||
static inline int darwinProcesses() {
|
||||
int err = 0;
|
||||
int i = 0;
|
||||
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
|
||||
size_t length = 0;
|
||||
struct kinfo_proc *result = NULL;
|
||||
size_t resultCount = 0;
|
||||
|
||||
// Get the length first
|
||||
err = sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1,
|
||||
NULL, &length, NULL, 0);
|
||||
if (err != 0) {
|
||||
goto ERREXIT;
|
||||
}
|
||||
|
||||
// Allocate the appropriate sized buffer to read the process list
|
||||
result = malloc(length);
|
||||
|
||||
// Call sysctl again with our buffer to fill it with the process list
|
||||
err = sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1,
|
||||
result, &length,
|
||||
NULL, 0);
|
||||
if (err != 0) {
|
||||
goto ERREXIT;
|
||||
}
|
||||
|
||||
resultCount = length / sizeof(struct kinfo_proc);
|
||||
for (i = 0; i < resultCount; i++) {
|
||||
struct kinfo_proc *single = &result[i];
|
||||
go_darwin_append_proc(
|
||||
single->kp_proc.p_pid,
|
||||
single->kp_eproc.e_ppid,
|
||||
single->kp_proc.p_comm);
|
||||
}
|
||||
|
||||
ERREXIT:
|
||||
if (result != NULL) {
|
||||
free(result);
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
return errno;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1878,6 +1878,13 @@
|
|||
"path": "github.com/mitchellh/go-linereader",
|
||||
"revision": "07bab5fdd9580500aea6ada0e09df4aa28e68abd"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "DVXnx4zyb0wkeIdIRjwjvR7Dslo=",
|
||||
"origin": "github.com/hashicorp/terraform/vendor/github.com/mitchellh/go-ps",
|
||||
"path": "github.com/mitchellh/go-ps",
|
||||
"revision": "e2d21980687ce16e58469d98dcee92d27fbbd7fb",
|
||||
"revisionTime": "2016-08-22T16:54:47Z"
|
||||
},
|
||||
{
|
||||
"path": "github.com/mitchellh/hashstructure",
|
||||
"revision": "6b17d669fac5e2f71c16658d781ec3fdd3802b69"
|
||||
|
|
Loading…
Reference in New Issue