mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-03-12 07:01:03 -04:00
A number of PRs have come through which modified the vendor folder without recording the proper information. This resets everything back to the recorded version.
139 lines
2.1 KiB
Go
139 lines
2.1 KiB
Go
// +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
|
|
}
|