Add github.com/shirou/gopsutil/host to vendor

This is needed for a coming PR to measure system uptime.
I separated vendor changes out, because they are larger while easier to
review.

This done via:
GO111MODULE=on go get github.com/shirou/gopsutil/host
GO111MODULE=on go mod vendor
This commit is contained in:
Xuewei Zhang
2019-06-27 12:01:01 -07:00
parent 29b0740f4c
commit 935fab705e
105 changed files with 21044 additions and 0 deletions

189
vendor/github.com/shirou/gopsutil/cpu/cpu.go generated vendored Normal file
View File

@@ -0,0 +1,189 @@
package cpu
import (
"context"
"encoding/json"
"fmt"
"runtime"
"strconv"
"strings"
"sync"
"time"
"github.com/shirou/gopsutil/internal/common"
)
// TimesStat contains the amounts of time the CPU has spent performing different
// kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of
// a second). It is based on linux /proc/stat file.
type TimesStat struct {
CPU string `json:"cpu"`
User float64 `json:"user"`
System float64 `json:"system"`
Idle float64 `json:"idle"`
Nice float64 `json:"nice"`
Iowait float64 `json:"iowait"`
Irq float64 `json:"irq"`
Softirq float64 `json:"softirq"`
Steal float64 `json:"steal"`
Guest float64 `json:"guest"`
GuestNice float64 `json:"guestNice"`
Stolen float64 `json:"stolen"`
}
type InfoStat struct {
CPU int32 `json:"cpu"`
VendorID string `json:"vendorId"`
Family string `json:"family"`
Model string `json:"model"`
Stepping int32 `json:"stepping"`
PhysicalID string `json:"physicalId"`
CoreID string `json:"coreId"`
Cores int32 `json:"cores"`
ModelName string `json:"modelName"`
Mhz float64 `json:"mhz"`
CacheSize int32 `json:"cacheSize"`
Flags []string `json:"flags"`
Microcode string `json:"microcode"`
}
type lastPercent struct {
sync.Mutex
lastCPUTimes []TimesStat
lastPerCPUTimes []TimesStat
}
var lastCPUPercent lastPercent
var invoke common.Invoker = common.Invoke{}
func init() {
lastCPUPercent.Lock()
lastCPUPercent.lastCPUTimes, _ = Times(false)
lastCPUPercent.lastPerCPUTimes, _ = Times(true)
lastCPUPercent.Unlock()
}
func Counts(logical bool) (int, error) {
return CountsWithContext(context.Background(), logical)
}
func CountsWithContext(ctx context.Context, logical bool) (int, error) {
return runtime.NumCPU(), nil
}
func (c TimesStat) String() string {
v := []string{
`"cpu":"` + c.CPU + `"`,
`"user":` + strconv.FormatFloat(c.User, 'f', 1, 64),
`"system":` + strconv.FormatFloat(c.System, 'f', 1, 64),
`"idle":` + strconv.FormatFloat(c.Idle, 'f', 1, 64),
`"nice":` + strconv.FormatFloat(c.Nice, 'f', 1, 64),
`"iowait":` + strconv.FormatFloat(c.Iowait, 'f', 1, 64),
`"irq":` + strconv.FormatFloat(c.Irq, 'f', 1, 64),
`"softirq":` + strconv.FormatFloat(c.Softirq, 'f', 1, 64),
`"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64),
`"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64),
`"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64),
`"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64),
}
return `{` + strings.Join(v, ",") + `}`
}
// Total returns the total number of seconds in a CPUTimesStat
func (c TimesStat) Total() float64 {
total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal +
c.Guest + c.GuestNice + c.Idle + c.Stolen
return total
}
func (c InfoStat) String() string {
s, _ := json.Marshal(c)
return string(s)
}
func getAllBusy(t TimesStat) (float64, float64) {
busy := t.User + t.System + t.Nice + t.Iowait + t.Irq +
t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen
return busy + t.Idle, busy
}
func calculateBusy(t1, t2 TimesStat) float64 {
t1All, t1Busy := getAllBusy(t1)
t2All, t2Busy := getAllBusy(t2)
if t2Busy <= t1Busy {
return 0
}
if t2All <= t1All {
return 1
}
return (t2Busy - t1Busy) / (t2All - t1All) * 100
}
func calculateAllBusy(t1, t2 []TimesStat) ([]float64, error) {
// Make sure the CPU measurements have the same length.
if len(t1) != len(t2) {
return nil, fmt.Errorf(
"received two CPU counts: %d != %d",
len(t1), len(t2),
)
}
ret := make([]float64, len(t1))
for i, t := range t2 {
ret[i] = calculateBusy(t1[i], t)
}
return ret, nil
}
// Percent calculates the percentage of cpu used either per CPU or combined.
// If an interval of 0 is given it will compare the current cpu times against the last call.
// Returns one value per cpu, or a single value if percpu is set to false.
func Percent(interval time.Duration, percpu bool) ([]float64, error) {
return PercentWithContext(context.Background(), interval, percpu)
}
func PercentWithContext(ctx context.Context, interval time.Duration, percpu bool) ([]float64, error) {
if interval <= 0 {
return percentUsedFromLastCall(percpu)
}
// Get CPU usage at the start of the interval.
cpuTimes1, err := Times(percpu)
if err != nil {
return nil, err
}
time.Sleep(interval)
// And at the end of the interval.
cpuTimes2, err := Times(percpu)
if err != nil {
return nil, err
}
return calculateAllBusy(cpuTimes1, cpuTimes2)
}
func percentUsedFromLastCall(percpu bool) ([]float64, error) {
cpuTimes, err := Times(percpu)
if err != nil {
return nil, err
}
lastCPUPercent.Lock()
defer lastCPUPercent.Unlock()
var lastTimes []TimesStat
if percpu {
lastTimes = lastCPUPercent.lastPerCPUTimes
lastCPUPercent.lastPerCPUTimes = cpuTimes
} else {
lastTimes = lastCPUPercent.lastCPUTimes
lastCPUPercent.lastCPUTimes = cpuTimes
}
if lastTimes == nil {
return nil, fmt.Errorf("error getting times for cpu percent. lastTimes was nil")
}
return calculateAllBusy(lastTimes, cpuTimes)
}

115
vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go generated vendored Normal file
View File

@@ -0,0 +1,115 @@
// +build darwin
package cpu
import (
"context"
"os/exec"
"strconv"
"strings"
)
// sys/resource.h
const (
CPUser = 0
CPNice = 1
CPSys = 2
CPIntr = 3
CPIdle = 4
CPUStates = 5
)
// default value. from time.h
var ClocksPerSec = float64(128)
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
if percpu {
return perCPUTimes()
}
return allCPUTimes()
}
// Returns only one CPUInfoStat on FreeBSD
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
var ret []InfoStat
sysctl, err := exec.LookPath("/usr/sbin/sysctl")
if err != nil {
return ret, err
}
out, err := invoke.CommandWithContext(ctx, sysctl, "machdep.cpu")
if err != nil {
return ret, err
}
c := InfoStat{}
for _, line := range strings.Split(string(out), "\n") {
values := strings.Fields(line)
if len(values) < 1 {
continue
}
t, err := strconv.ParseInt(values[1], 10, 64)
// err is not checked here because some value is string.
if strings.HasPrefix(line, "machdep.cpu.brand_string") {
c.ModelName = strings.Join(values[1:], " ")
} else if strings.HasPrefix(line, "machdep.cpu.family") {
c.Family = values[1]
} else if strings.HasPrefix(line, "machdep.cpu.model") {
c.Model = values[1]
} else if strings.HasPrefix(line, "machdep.cpu.stepping") {
if err != nil {
return ret, err
}
c.Stepping = int32(t)
} else if strings.HasPrefix(line, "machdep.cpu.features") {
for _, v := range values[1:] {
c.Flags = append(c.Flags, strings.ToLower(v))
}
} else if strings.HasPrefix(line, "machdep.cpu.leaf7_features") {
for _, v := range values[1:] {
c.Flags = append(c.Flags, strings.ToLower(v))
}
} else if strings.HasPrefix(line, "machdep.cpu.extfeatures") {
for _, v := range values[1:] {
c.Flags = append(c.Flags, strings.ToLower(v))
}
} else if strings.HasPrefix(line, "machdep.cpu.core_count") {
if err != nil {
return ret, err
}
c.Cores = int32(t)
} else if strings.HasPrefix(line, "machdep.cpu.cache.size") {
if err != nil {
return ret, err
}
c.CacheSize = int32(t)
} else if strings.HasPrefix(line, "machdep.cpu.vendor") {
c.VendorID = values[1]
}
}
// Use the rated frequency of the CPU. This is a static value and does not
// account for low power or Turbo Boost modes.
out, err = invoke.CommandWithContext(ctx, sysctl, "hw.cpufrequency")
if err != nil {
return ret, err
}
values := strings.Fields(string(out))
hz, err := strconv.ParseFloat(values[1], 64)
if err != nil {
return ret, err
}
c.Mhz = hz / 1000000.0
return append(ret, c), nil
}

111
vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go generated vendored Normal file
View File

@@ -0,0 +1,111 @@
// +build darwin
// +build cgo
package cpu
/*
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/mount.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#if TARGET_OS_MAC
#include <libproc.h>
#endif
#include <mach/processor_info.h>
#include <mach/vm_map.h>
*/
import "C"
import (
"bytes"
"encoding/binary"
"fmt"
"unsafe"
)
// these CPU times for darwin is borrowed from influxdb/telegraf.
func perCPUTimes() ([]TimesStat, error) {
var (
count C.mach_msg_type_number_t
cpuload *C.processor_cpu_load_info_data_t
ncpu C.natural_t
)
status := C.host_processor_info(C.host_t(C.mach_host_self()),
C.PROCESSOR_CPU_LOAD_INFO,
&ncpu,
(*C.processor_info_array_t)(unsafe.Pointer(&cpuload)),
&count)
if status != C.KERN_SUCCESS {
return nil, fmt.Errorf("host_processor_info error=%d", status)
}
// jump through some cgo casting hoops and ensure we properly free
// the memory that cpuload points to
target := C.vm_map_t(C.mach_task_self_)
address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload)))
defer C.vm_deallocate(target, address, C.vm_size_t(ncpu))
// the body of struct processor_cpu_load_info
// aka processor_cpu_load_info_data_t
var cpu_ticks [C.CPU_STATE_MAX]uint32
// copy the cpuload array to a []byte buffer
// where we can binary.Read the data
size := int(ncpu) * binary.Size(cpu_ticks)
buf := (*[1 << 30]byte)(unsafe.Pointer(cpuload))[:size:size]
bbuf := bytes.NewBuffer(buf)
var ret []TimesStat
for i := 0; i < int(ncpu); i++ {
err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks)
if err != nil {
return nil, err
}
c := TimesStat{
CPU: fmt.Sprintf("cpu%d", i),
User: float64(cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
}
ret = append(ret, c)
}
return ret, nil
}
func allCPUTimes() ([]TimesStat, error) {
var count C.mach_msg_type_number_t
var cpuload C.host_cpu_load_info_data_t
count = C.HOST_CPU_LOAD_INFO_COUNT
status := C.host_statistics(C.host_t(C.mach_host_self()),
C.HOST_CPU_LOAD_INFO,
C.host_info_t(unsafe.Pointer(&cpuload)),
&count)
if status != C.KERN_SUCCESS {
return nil, fmt.Errorf("host_statistics error=%d", status)
}
c := TimesStat{
CPU: "cpu-total",
User: float64(cpuload.cpu_ticks[C.CPU_STATE_USER]) / ClocksPerSec,
System: float64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM]) / ClocksPerSec,
Nice: float64(cpuload.cpu_ticks[C.CPU_STATE_NICE]) / ClocksPerSec,
Idle: float64(cpuload.cpu_ticks[C.CPU_STATE_IDLE]) / ClocksPerSec,
}
return []TimesStat{c}, nil
}

View File

@@ -0,0 +1,14 @@
// +build darwin
// +build !cgo
package cpu
import "github.com/shirou/gopsutil/internal/common"
func perCPUTimes() ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}
func allCPUTimes() ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}

25
vendor/github.com/shirou/gopsutil/cpu/cpu_fallback.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows
package cpu
import (
"context"
"github.com/shirou/gopsutil/internal/common"
)
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
return []InfoStat{}, common.ErrNotImplementedError
}

168
vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go generated vendored Normal file
View File

@@ -0,0 +1,168 @@
package cpu
import (
"context"
"fmt"
"os/exec"
"reflect"
"regexp"
"strconv"
"strings"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
var ClocksPerSec = float64(128)
var cpuMatch = regexp.MustCompile(`^CPU:`)
var originMatch = regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Family\s*=\s*(.+)\s+Model\s*=\s*(.+)\s+Stepping\s*=\s*(.+)`)
var featuresMatch = regexp.MustCompile(`Features=.+<(.+)>`)
var featuresMatch2 = regexp.MustCompile(`Features2=[a-f\dx]+<(.+)>`)
var cpuEnd = regexp.MustCompile(`^Trying to mount root`)
var cpuCores = regexp.MustCompile(`FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)`)
var cpuTimesSize int
var emptyTimes cpuTimes
func init() {
getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := invoke.Command(getconf, "CLK_TCK")
// ignore errors
if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
if err == nil {
ClocksPerSec = float64(i)
}
}
}
func timeStat(name string, t *cpuTimes) *TimesStat {
return &TimesStat{
User: float64(t.User) / ClocksPerSec,
Nice: float64(t.Nice) / ClocksPerSec,
System: float64(t.Sys) / ClocksPerSec,
Idle: float64(t.Idle) / ClocksPerSec,
Irq: float64(t.Intr) / ClocksPerSec,
CPU: name,
}
}
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
if percpu {
buf, err := unix.SysctlRaw("kern.cp_times")
if err != nil {
return nil, err
}
// We can't do this in init due to the conflict with cpu.init()
if cpuTimesSize == 0 {
cpuTimesSize = int(reflect.TypeOf(cpuTimes{}).Size())
}
ncpus := len(buf) / cpuTimesSize
ret := make([]TimesStat, 0, ncpus)
for i := 0; i < ncpus; i++ {
times := (*cpuTimes)(unsafe.Pointer(&buf[i*cpuTimesSize]))
if *times == emptyTimes {
// CPU not present
continue
}
ret = append(ret, *timeStat(fmt.Sprintf("cpu%d", len(ret)), times))
}
return ret, nil
}
buf, err := unix.SysctlRaw("kern.cp_time")
if err != nil {
return nil, err
}
times := (*cpuTimes)(unsafe.Pointer(&buf[0]))
return []TimesStat{*timeStat("cpu-total", times)}, nil
}
// Returns only one InfoStat on FreeBSD. The information regarding core
// count, however is accurate and it is assumed that all InfoStat attributes
// are the same across CPUs.
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
const dmesgBoot = "/var/run/dmesg.boot"
c, num, err := parseDmesgBoot(dmesgBoot)
if err != nil {
return nil, err
}
var u32 uint32
if u32, err = unix.SysctlUint32("hw.clockrate"); err != nil {
return nil, err
}
c.Mhz = float64(u32)
if u32, err = unix.SysctlUint32("hw.ncpu"); err != nil {
return nil, err
}
c.Cores = int32(u32)
if c.ModelName, err = unix.Sysctl("hw.model"); err != nil {
return nil, err
}
ret := make([]InfoStat, num)
for i := 0; i < num; i++ {
ret[i] = c
}
return ret, nil
}
func parseDmesgBoot(fileName string) (InfoStat, int, error) {
c := InfoStat{}
lines, _ := common.ReadLines(fileName)
cpuNum := 1 // default cpu num is 1
for _, line := range lines {
if matches := cpuEnd.FindStringSubmatch(line); matches != nil {
break
} else if matches := originMatch.FindStringSubmatch(line); matches != nil {
c.VendorID = matches[1]
c.Family = matches[3]
c.Model = matches[4]
t, err := strconv.ParseInt(matches[5], 10, 32)
if err != nil {
return c, 0, fmt.Errorf("unable to parse FreeBSD CPU stepping information from %q: %v", line, err)
}
c.Stepping = int32(t)
} else if matches := featuresMatch.FindStringSubmatch(line); matches != nil {
for _, v := range strings.Split(matches[1], ",") {
c.Flags = append(c.Flags, strings.ToLower(v))
}
} else if matches := featuresMatch2.FindStringSubmatch(line); matches != nil {
for _, v := range strings.Split(matches[1], ",") {
c.Flags = append(c.Flags, strings.ToLower(v))
}
} else if matches := cpuCores.FindStringSubmatch(line); matches != nil {
t, err := strconv.ParseInt(matches[1], 10, 32)
if err != nil {
return c, 0, fmt.Errorf("unable to parse FreeBSD CPU Nums from %q: %v", line, err)
}
cpuNum = int(t)
t2, err := strconv.ParseInt(matches[2], 10, 32)
if err != nil {
return c, 0, fmt.Errorf("unable to parse FreeBSD CPU cores from %q: %v", line, err)
}
c.Cores = int32(t2)
}
}
return c, cpuNum, nil
}

View File

@@ -0,0 +1,9 @@
package cpu
type cpuTimes struct {
User uint32
Nice uint32
Sys uint32
Intr uint32
Idle uint32
}

View File

@@ -0,0 +1,9 @@
package cpu
type cpuTimes struct {
User uint64
Nice uint64
Sys uint64
Intr uint64
Idle uint64
}

284
vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go generated vendored Normal file
View File

@@ -0,0 +1,284 @@
// +build linux
package cpu
import (
"context"
"errors"
"fmt"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
var CPUTick = float64(100)
func init() {
getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := invoke.CommandWithContext(context.Background(), getconf, "CLK_TCK")
// ignore errors
if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
if err == nil {
CPUTick = i
}
}
}
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
filename := common.HostProc("stat")
var lines = []string{}
if percpu {
statlines, err := common.ReadLines(filename)
if err != nil || len(statlines) < 2 {
return []TimesStat{}, nil
}
for _, line := range statlines[1:] {
if !strings.HasPrefix(line, "cpu") {
break
}
lines = append(lines, line)
}
} else {
lines, _ = common.ReadLinesOffsetN(filename, 0, 1)
}
ret := make([]TimesStat, 0, len(lines))
for _, line := range lines {
ct, err := parseStatLine(line)
if err != nil {
continue
}
ret = append(ret, *ct)
}
return ret, nil
}
func sysCPUPath(cpu int32, relPath string) string {
return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath)
}
func finishCPUInfo(c *InfoStat) error {
var lines []string
var err error
var value float64
if len(c.CoreID) == 0 {
lines, err = common.ReadLines(sysCPUPath(c.CPU, "topology/core_id"))
if err == nil {
c.CoreID = lines[0]
}
}
// override the value of c.Mhz with cpufreq/cpuinfo_max_freq regardless
// of the value from /proc/cpuinfo because we want to report the maximum
// clock-speed of the CPU for c.Mhz, matching the behaviour of Windows
lines, err = common.ReadLines(sysCPUPath(c.CPU, "cpufreq/cpuinfo_max_freq"))
// if we encounter errors below such as there are no cpuinfo_max_freq file,
// we just ignore. so let Mhz is 0.
if err != nil {
return nil
}
value, err = strconv.ParseFloat(lines[0], 64)
if err != nil {
return nil
}
c.Mhz = value / 1000.0 // value is in kHz
if c.Mhz > 9999 {
c.Mhz = c.Mhz / 1000.0 // value in Hz
}
return nil
}
// CPUInfo on linux will return 1 item per physical thread.
//
// CPUs have three levels of counting: sockets, cores, threads.
// Cores with HyperThreading count as having 2 threads per core.
// Sockets often come with many physical CPU cores.
// For example a single socket board with two cores each with HT will
// return 4 CPUInfoStat structs on Linux and the "Cores" field set to 1.
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
filename := common.HostProc("cpuinfo")
lines, _ := common.ReadLines(filename)
var ret []InfoStat
var processorName string
c := InfoStat{CPU: -1, Cores: 1}
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) < 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.TrimSpace(fields[1])
switch key {
case "Processor":
processorName = value
case "processor":
if c.CPU >= 0 {
err := finishCPUInfo(&c)
if err != nil {
return ret, err
}
ret = append(ret, c)
}
c = InfoStat{Cores: 1, ModelName: processorName}
t, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return ret, err
}
c.CPU = int32(t)
case "vendorId", "vendor_id":
c.VendorID = value
case "cpu family":
c.Family = value
case "model":
c.Model = value
case "model name", "cpu":
c.ModelName = value
if strings.Contains(value, "POWER8") ||
strings.Contains(value, "POWER7") {
c.Model = strings.Split(value, " ")[0]
c.Family = "POWER"
c.VendorID = "IBM"
}
case "stepping", "revision":
val := value
if key == "revision" {
val = strings.Split(value, ".")[0]
}
t, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return ret, err
}
c.Stepping = int32(t)
case "cpu MHz", "clock":
// treat this as the fallback value, thus we ignore error
if t, err := strconv.ParseFloat(strings.Replace(value, "MHz", "", 1), 64); err == nil {
c.Mhz = t
}
case "cache size":
t, err := strconv.ParseInt(strings.Replace(value, " KB", "", 1), 10, 64)
if err != nil {
return ret, err
}
c.CacheSize = int32(t)
case "physical id":
c.PhysicalID = value
case "core id":
c.CoreID = value
case "flags", "Features":
c.Flags = strings.FieldsFunc(value, func(r rune) bool {
return r == ',' || r == ' '
})
case "microcode":
c.Microcode = value
}
}
if c.CPU >= 0 {
err := finishCPUInfo(&c)
if err != nil {
return ret, err
}
ret = append(ret, c)
}
return ret, nil
}
func parseStatLine(line string) (*TimesStat, error) {
fields := strings.Fields(line)
if len(fields) == 0 {
return nil, errors.New("stat does not contain cpu info")
}
if strings.HasPrefix(fields[0], "cpu") == false {
return nil, errors.New("not contain cpu")
}
cpu := fields[0]
if cpu == "cpu" {
cpu = "cpu-total"
}
user, err := strconv.ParseFloat(fields[1], 64)
if err != nil {
return nil, err
}
nice, err := strconv.ParseFloat(fields[2], 64)
if err != nil {
return nil, err
}
system, err := strconv.ParseFloat(fields[3], 64)
if err != nil {
return nil, err
}
idle, err := strconv.ParseFloat(fields[4], 64)
if err != nil {
return nil, err
}
iowait, err := strconv.ParseFloat(fields[5], 64)
if err != nil {
return nil, err
}
irq, err := strconv.ParseFloat(fields[6], 64)
if err != nil {
return nil, err
}
softirq, err := strconv.ParseFloat(fields[7], 64)
if err != nil {
return nil, err
}
ct := &TimesStat{
CPU: cpu,
User: user / CPUTick,
Nice: nice / CPUTick,
System: system / CPUTick,
Idle: idle / CPUTick,
Iowait: iowait / CPUTick,
Irq: irq / CPUTick,
Softirq: softirq / CPUTick,
}
if len(fields) > 8 { // Linux >= 2.6.11
steal, err := strconv.ParseFloat(fields[8], 64)
if err != nil {
return nil, err
}
ct.Steal = steal / CPUTick
}
if len(fields) > 9 { // Linux >= 2.6.24
guest, err := strconv.ParseFloat(fields[9], 64)
if err != nil {
return nil, err
}
ct.Guest = guest / CPUTick
}
if len(fields) > 10 { // Linux >= 3.2.0
guestNice, err := strconv.ParseFloat(fields[10], 64)
if err != nil {
return nil, err
}
ct.GuestNice = guestNice / CPUTick
}
return ct, nil
}

119
vendor/github.com/shirou/gopsutil/cpu/cpu_openbsd.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
// +build openbsd
package cpu
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
// sys/sched.h
const (
CPUser = 0
CPNice = 1
CPSys = 2
CPIntr = 3
CPIdle = 4
CPUStates = 5
)
// sys/sysctl.h
const (
CTLKern = 1 // "high kernel": proc, limits
KernCptime = 40 // KERN_CPTIME
KernCptime2 = 71 // KERN_CPTIME2
)
var ClocksPerSec = float64(128)
func init() {
getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := invoke.Command(getconf, "CLK_TCK")
// ignore errors
if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
if err == nil {
ClocksPerSec = float64(i)
}
}
}
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
var ret []TimesStat
var ncpu int
if percpu {
ncpu, _ = Counts(true)
} else {
ncpu = 1
}
for i := 0; i < ncpu; i++ {
var cpuTimes [CPUStates]int64
var mib []int32
if percpu {
mib = []int32{CTLKern, KernCptime}
} else {
mib = []int32{CTLKern, KernCptime2, int32(i)}
}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return ret, err
}
br := bytes.NewReader(buf)
err = binary.Read(br, binary.LittleEndian, &cpuTimes)
if err != nil {
return ret, err
}
c := TimesStat{
User: float64(cpuTimes[CPUser]) / ClocksPerSec,
Nice: float64(cpuTimes[CPNice]) / ClocksPerSec,
System: float64(cpuTimes[CPSys]) / ClocksPerSec,
Idle: float64(cpuTimes[CPIdle]) / ClocksPerSec,
Irq: float64(cpuTimes[CPIntr]) / ClocksPerSec,
}
if !percpu {
c.CPU = "cpu-total"
} else {
c.CPU = fmt.Sprintf("cpu%d", i)
}
ret = append(ret, c)
}
return ret, nil
}
// Returns only one (minimal) CPUInfoStat on OpenBSD
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
var ret []InfoStat
c := InfoStat{}
v, err := unix.Sysctl("hw.model")
if err != nil {
return nil, err
}
c.ModelName = v
return append(ret, c), nil
}

198
vendor/github.com/shirou/gopsutil/cpu/cpu_solaris.go generated vendored Normal file
View File

@@ -0,0 +1,198 @@
package cpu
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
"sort"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
var ClocksPerSec = float64(128)
func init() {
getconf, err := exec.LookPath("/usr/bin/getconf")
if err != nil {
return
}
out, err := invoke.Command(getconf, "CLK_TCK")
// ignore errors
if err == nil {
i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64)
if err == nil {
ClocksPerSec = float64(i)
}
}
}
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
return []TimesStat{}, common.ErrNotImplementedError
}
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
psrInfo, err := exec.LookPath("/usr/sbin/psrinfo")
if err != nil {
return nil, fmt.Errorf("cannot find psrinfo: %s", err)
}
psrInfoOut, err := invoke.CommandWithContext(ctx, psrInfo, "-p", "-v")
if err != nil {
return nil, fmt.Errorf("cannot execute psrinfo: %s", err)
}
isaInfo, err := exec.LookPath("/usr/bin/isainfo")
if err != nil {
return nil, fmt.Errorf("cannot find isainfo: %s", err)
}
isaInfoOut, err := invoke.CommandWithContext(ctx, isaInfo, "-b", "-v")
if err != nil {
return nil, fmt.Errorf("cannot execute isainfo: %s", err)
}
procs, err := parseProcessorInfo(string(psrInfoOut))
if err != nil {
return nil, fmt.Errorf("error parsing psrinfo output: %s", err)
}
flags, err := parseISAInfo(string(isaInfoOut))
if err != nil {
return nil, fmt.Errorf("error parsing isainfo output: %s", err)
}
result := make([]InfoStat, 0, len(flags))
for _, proc := range procs {
procWithFlags := proc
procWithFlags.Flags = flags
result = append(result, procWithFlags)
}
return result, nil
}
var flagsMatch = regexp.MustCompile(`[\w\.]+`)
func parseISAInfo(cmdOutput string) ([]string, error) {
words := flagsMatch.FindAllString(cmdOutput, -1)
// Sanity check the output
if len(words) < 4 || words[1] != "bit" || words[3] != "applications" {
return nil, errors.New("attempted to parse invalid isainfo output")
}
flags := make([]string, len(words)-4)
for i, val := range words[4:] {
flags[i] = val
}
sort.Strings(flags)
return flags, nil
}
var psrInfoMatch = regexp.MustCompile(`The physical processor has (?:([\d]+) virtual processor \(([\d]+)\)|([\d]+) cores and ([\d]+) virtual processors[^\n]+)\n(?:\s+ The core has.+\n)*\s+.+ \((\w+) ([\S]+) family (.+) model (.+) step (.+) clock (.+) MHz\)\n[\s]*(.*)`)
const (
psrNumCoresOffset = 1
psrNumCoresHTOffset = 3
psrNumHTOffset = 4
psrVendorIDOffset = 5
psrFamilyOffset = 7
psrModelOffset = 8
psrStepOffset = 9
psrClockOffset = 10
psrModelNameOffset = 11
)
func parseProcessorInfo(cmdOutput string) ([]InfoStat, error) {
matches := psrInfoMatch.FindAllStringSubmatch(cmdOutput, -1)
var infoStatCount int32
result := make([]InfoStat, 0, len(matches))
for physicalIndex, physicalCPU := range matches {
var step int32
var clock float64
if physicalCPU[psrStepOffset] != "" {
stepParsed, err := strconv.ParseInt(physicalCPU[psrStepOffset], 10, 32)
if err != nil {
return nil, fmt.Errorf("cannot parse value %q for step as 32-bit integer: %s", physicalCPU[9], err)
}
step = int32(stepParsed)
}
if physicalCPU[psrClockOffset] != "" {
clockParsed, err := strconv.ParseInt(physicalCPU[psrClockOffset], 10, 64)
if err != nil {
return nil, fmt.Errorf("cannot parse value %q for clock as 32-bit integer: %s", physicalCPU[10], err)
}
clock = float64(clockParsed)
}
var err error
var numCores int64
var numHT int64
switch {
case physicalCPU[psrNumCoresOffset] != "":
numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresOffset], 10, 32)
if err != nil {
return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[1], err)
}
for i := 0; i < int(numCores); i++ {
result = append(result, InfoStat{
CPU: infoStatCount,
PhysicalID: strconv.Itoa(physicalIndex),
CoreID: strconv.Itoa(i),
Cores: 1,
VendorID: physicalCPU[psrVendorIDOffset],
ModelName: physicalCPU[psrModelNameOffset],
Family: physicalCPU[psrFamilyOffset],
Model: physicalCPU[psrModelOffset],
Stepping: step,
Mhz: clock,
})
infoStatCount++
}
case physicalCPU[psrNumCoresHTOffset] != "":
numCores, err = strconv.ParseInt(physicalCPU[psrNumCoresHTOffset], 10, 32)
if err != nil {
return nil, fmt.Errorf("cannot parse value %q for core count as 32-bit integer: %s", physicalCPU[3], err)
}
numHT, err = strconv.ParseInt(physicalCPU[psrNumHTOffset], 10, 32)
if err != nil {
return nil, fmt.Errorf("cannot parse value %q for hyperthread count as 32-bit integer: %s", physicalCPU[4], err)
}
for i := 0; i < int(numCores); i++ {
result = append(result, InfoStat{
CPU: infoStatCount,
PhysicalID: strconv.Itoa(physicalIndex),
CoreID: strconv.Itoa(i),
Cores: int32(numHT) / int32(numCores),
VendorID: physicalCPU[psrVendorIDOffset],
ModelName: physicalCPU[psrModelNameOffset],
Family: physicalCPU[psrFamilyOffset],
Model: physicalCPU[psrModelOffset],
Stepping: step,
Mhz: clock,
})
infoStatCount++
}
default:
return nil, errors.New("values for cores with and without hyperthreading are both set")
}
}
return result, nil
}

171
vendor/github.com/shirou/gopsutil/cpu/cpu_windows.go generated vendored Normal file
View File

@@ -0,0 +1,171 @@
// +build windows
package cpu
import (
"context"
"fmt"
"unsafe"
"github.com/StackExchange/wmi"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/windows"
)
type Win32_Processor struct {
LoadPercentage *uint16
Family uint16
Manufacturer string
Name string
NumberOfLogicalProcessors uint32
ProcessorID *string
Stepping *string
MaxClockSpeed uint32
}
type win32_PerfRawData_Counters_ProcessorInformation struct {
Name string
PercentDPCTime uint64
PercentIdleTime uint64
PercentUserTime uint64
PercentProcessorTime uint64
PercentInterruptTime uint64
PercentPriorityTime uint64
PercentPrivilegedTime uint64
InterruptsPerSec uint32
ProcessorFrequency uint32
DPCRate uint32
}
// Win32_PerfFormattedData_PerfOS_System struct to have count of processes and processor queue length
type Win32_PerfFormattedData_PerfOS_System struct {
Processes uint32
ProcessorQueueLength uint32
}
const (
win32_TicksPerSecond = 10000000.0
)
// Times returns times stat per cpu and combined for all CPUs
func Times(percpu bool) ([]TimesStat, error) {
return TimesWithContext(context.Background(), percpu)
}
func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) {
if percpu {
return perCPUTimesWithContext(ctx)
}
var ret []TimesStat
var lpIdleTime common.FILETIME
var lpKernelTime common.FILETIME
var lpUserTime common.FILETIME
r, _, _ := common.ProcGetSystemTimes.Call(
uintptr(unsafe.Pointer(&lpIdleTime)),
uintptr(unsafe.Pointer(&lpKernelTime)),
uintptr(unsafe.Pointer(&lpUserTime)))
if r == 0 {
return ret, windows.GetLastError()
}
LOT := float64(0.0000001)
HIT := (LOT * 4294967296.0)
idle := ((HIT * float64(lpIdleTime.DwHighDateTime)) + (LOT * float64(lpIdleTime.DwLowDateTime)))
user := ((HIT * float64(lpUserTime.DwHighDateTime)) + (LOT * float64(lpUserTime.DwLowDateTime)))
kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime)))
system := (kernel - idle)
ret = append(ret, TimesStat{
CPU: "cpu-total",
Idle: float64(idle),
User: float64(user),
System: float64(system),
})
return ret, nil
}
func Info() ([]InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) ([]InfoStat, error) {
var ret []InfoStat
var dst []Win32_Processor
q := wmi.CreateQuery(&dst, "")
if err := common.WMIQueryWithContext(ctx, q, &dst); err != nil {
return ret, err
}
var procID string
for i, l := range dst {
procID = ""
if l.ProcessorID != nil {
procID = *l.ProcessorID
}
cpu := InfoStat{
CPU: int32(i),
Family: fmt.Sprintf("%d", l.Family),
VendorID: l.Manufacturer,
ModelName: l.Name,
Cores: int32(l.NumberOfLogicalProcessors),
PhysicalID: procID,
Mhz: float64(l.MaxClockSpeed),
Flags: []string{},
}
ret = append(ret, cpu)
}
return ret, nil
}
// PerfInfo returns the performance counter's instance value for ProcessorInformation.
// Name property is the key by which overall, per cpu and per core metric is known.
func perfInfoWithContext(ctx context.Context) ([]win32_PerfRawData_Counters_ProcessorInformation, error) {
var ret []win32_PerfRawData_Counters_ProcessorInformation
q := wmi.CreateQuery(&ret, "WHERE NOT Name LIKE '%_Total'")
err := common.WMIQueryWithContext(ctx, q, &ret)
if err != nil {
return []win32_PerfRawData_Counters_ProcessorInformation{}, err
}
return ret, err
}
// ProcInfo returns processes count and processor queue length in the system.
// There is a single queue for processor even on multiprocessors systems.
func ProcInfo() ([]Win32_PerfFormattedData_PerfOS_System, error) {
return ProcInfoWithContext(context.Background())
}
func ProcInfoWithContext(ctx context.Context) ([]Win32_PerfFormattedData_PerfOS_System, error) {
var ret []Win32_PerfFormattedData_PerfOS_System
q := wmi.CreateQuery(&ret, "")
err := common.WMIQueryWithContext(ctx, q, &ret)
if err != nil {
return []Win32_PerfFormattedData_PerfOS_System{}, err
}
return ret, err
}
// perCPUTimes returns times stat per cpu, per core and overall for all CPUs
func perCPUTimesWithContext(ctx context.Context) ([]TimesStat, error) {
var ret []TimesStat
stats, err := perfInfoWithContext(ctx)
if err != nil {
return nil, err
}
for _, v := range stats {
c := TimesStat{
CPU: v.Name,
User: float64(v.PercentUserTime) / win32_TicksPerSecond,
System: float64(v.PercentPrivilegedTime) / win32_TicksPerSecond,
Idle: float64(v.PercentIdleTime) / win32_TicksPerSecond,
Irq: float64(v.PercentInterruptTime) / win32_TicksPerSecond,
}
ret = append(ret, c)
}
return ret, nil
}

53
vendor/github.com/shirou/gopsutil/host/host.go generated vendored Normal file
View File

@@ -0,0 +1,53 @@
package host
import (
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
)
var invoke common.Invoker = common.Invoke{}
// A HostInfoStat describes the host status.
// This is not in the psutil but it useful.
type InfoStat struct {
Hostname string `json:"hostname"`
Uptime uint64 `json:"uptime"`
BootTime uint64 `json:"bootTime"`
Procs uint64 `json:"procs"` // number of processes
OS string `json:"os"` // ex: freebsd, linux
Platform string `json:"platform"` // ex: ubuntu, linuxmint
PlatformFamily string `json:"platformFamily"` // ex: debian, rhel
PlatformVersion string `json:"platformVersion"` // version of the complete OS
KernelVersion string `json:"kernelVersion"` // version of the OS kernel (if available)
VirtualizationSystem string `json:"virtualizationSystem"`
VirtualizationRole string `json:"virtualizationRole"` // guest or host
HostID string `json:"hostid"` // ex: uuid
}
type UserStat struct {
User string `json:"user"`
Terminal string `json:"terminal"`
Host string `json:"host"`
Started int `json:"started"`
}
type TemperatureStat struct {
SensorKey string `json:"sensorKey"`
Temperature float64 `json:"sensorTemperature"`
}
func (h InfoStat) String() string {
s, _ := json.Marshal(h)
return string(s)
}
func (u UserStat) String() string {
s, _ := json.Marshal(u)
return string(s)
}
func (t TemperatureStat) String() string {
s, _ := json.Marshal(t)
return string(s)
}

232
vendor/github.com/shirou/gopsutil/host/host_darwin.go generated vendored Normal file
View File

@@ -0,0 +1,232 @@
// +build darwin
package host
import (
"bytes"
"context"
"encoding/binary"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
)
// from utmpx.h
const USER_PROCESS = 7
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "darwin",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
kernelVersion, err := KernelVersionWithContext(ctx)
if err == nil {
ret.KernelVersion = kernelVersion
}
platform, family, pver, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = pver
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
values, err := common.DoSysctrlWithContext(ctx, "kern.uuid")
if err == nil && len(values) == 1 && values[0] != "" {
ret.HostID = strings.ToLower(values[0])
}
return ret, nil
}
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
values, err := common.DoSysctrlWithContext(ctx, "kern.boottime")
if err != nil {
return 0, err
}
// ex: { sec = 1392261637, usec = 627534 } Thu Feb 13 12:20:37 2014
v := strings.Replace(values[2], ",", "", 1)
boottime, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return 0, err
}
t = uint64(boottime)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
utmpfile := "/var/run/utmpx"
var ret []UserStat
file, err := os.Open(utmpfile)
if err != nil {
return ret, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return ret, err
}
u := Utmpx{}
entrySize := int(unsafe.Sizeof(u))
count := len(buf) / entrySize
for i := 0; i < count; i++ {
b := buf[i*entrySize : i*entrySize+entrySize]
var u Utmpx
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil {
continue
}
if u.Type != USER_PROCESS {
continue
}
user := UserStat{
User: common.IntToString(u.User[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Tv.Sec),
}
ret = append(ret, user)
}
return ret, nil
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform := ""
family := ""
pver := ""
sw_vers, err := exec.LookPath("sw_vers")
if err != nil {
return "", "", "", err
}
uname, err := exec.LookPath("uname")
if err != nil {
return "", "", "", err
}
out, err := invoke.CommandWithContext(ctx, uname, "-s")
if err == nil {
platform = strings.ToLower(strings.TrimSpace(string(out)))
}
out, err = invoke.CommandWithContext(ctx, sw_vers, "-productVersion")
if err == nil {
pver = strings.ToLower(strings.TrimSpace(string(out)))
}
return platform, family, pver, nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
uname, err := exec.LookPath("uname")
if err != nil {
return "", err
}
out, err := invoke.CommandWithContext(ctx, uname, "-r")
if err != nil {
return "", err
}
version := strings.ToLower(strings.TrimSpace(string(out)))
return version, err
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}

View File

@@ -0,0 +1,19 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_darwin.go
package host
type Utmpx struct {
User [256]int8
ID [4]int8
Line [32]int8
Pid int32
Type int16
Pad_cgo_0 [6]byte
Tv Timeval
Host [256]int8
Pad [16]uint32
}
type Timeval struct {
Sec int32
}

View File

@@ -0,0 +1,19 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_darwin.go
package host
type Utmpx struct {
User [256]int8
ID [4]int8
Line [32]int8
Pid int32
Type int16
Pad_cgo_0 [6]byte
Tv Timeval
Host [256]int8
Pad [16]uint32
}
type Timeval struct {
Sec int32
}

View File

@@ -0,0 +1,65 @@
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows
package host
import (
"context"
"github.com/shirou/gopsutil/internal/common"
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
return nil, common.ErrNotImplementedError
}
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
return 0, common.ErrNotImplementedError
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
return "", "", "", common.ErrNotImplementedError
}

245
vendor/github.com/shirou/gopsutil/host/host_freebsd.go generated vendored Normal file
View File

@@ -0,0 +1,245 @@
// +build freebsd
package host
import (
"bytes"
"context"
"encoding/binary"
"io/ioutil"
"os"
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
"golang.org/x/sys/unix"
)
const (
UTNameSize = 16 /* see MAXLOGNAME in <sys/param.h> */
UTLineSize = 8
UTHostSize = 16
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "freebsd",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
ret.KernelVersion = version
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
hostid, err := unix.Sysctl("kern.hostuuid")
if err == nil && hostid != "" {
ret.HostID = strings.ToLower(hostid)
}
return ret, nil
}
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
buf, err := unix.SysctlRaw("kern.boottime")
if err != nil {
return 0, err
}
tv := *(*syscall.Timeval)(unsafe.Pointer((&buf[0])))
atomic.StoreUint64(&cachedBootTime, uint64(tv.Sec))
return t, nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
utmpfile := "/var/run/utx.active"
if !common.PathExists(utmpfile) {
utmpfile = "/var/run/utmp" // before 9.0
return getUsersFromUtmp(utmpfile)
}
var ret []UserStat
file, err := os.Open(utmpfile)
if err != nil {
return ret, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return ret, err
}
entrySize := sizeOfUtmpx
count := len(buf) / entrySize
for i := 0; i < count; i++ {
b := buf[i*sizeOfUtmpx : (i+1)*sizeOfUtmpx]
var u Utmpx
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil || u.Type != 4 {
continue
}
sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO:
user := UserStat{
User: common.IntToString(u.User[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(sec),
}
ret = append(ret, user)
}
return ret, nil
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform, err := unix.Sysctl("kern.ostype")
if err != nil {
return "", "", "", err
}
version, err := unix.Sysctl("kern.osrelease")
if err != nil {
return "", "", "", err
}
return strings.ToLower(platform), "", strings.ToLower(version), nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
// before 9.0
func getUsersFromUtmp(utmpfile string) ([]UserStat, error) {
var ret []UserStat
file, err := os.Open(utmpfile)
if err != nil {
return ret, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return ret, err
}
u := Utmp{}
entrySize := int(unsafe.Sizeof(u))
count := len(buf) / entrySize
for i := 0; i < count; i++ {
b := buf[i*entrySize : i*entrySize+entrySize]
var u Utmp
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil || u.Time == 0 {
continue
}
user := UserStat{
User: common.IntToString(u.Name[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Time),
}
ret = append(ret, user)
}
return ret, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
return version, err
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmpx = 197 // TODO why should 197
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type Utmp struct {
Line [8]int8
Name [16]int8
Host [16]int8
Time int32
}
type Utmpx struct {
Type int16
Tv Timeval
Id [8]int8
Pid int32
User [32]int8
Line [16]int8
Host [125]int8
// X__ut_spare [64]int8
}
type Timeval struct {
Sec [4]byte
Usec [3]byte
}

View File

@@ -0,0 +1,44 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmpx = 197 // TODO: why should 197, not 0x118
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Utmp struct {
Line [8]int8
Name [16]int8
Host [16]int8
Time int32
}
type Utmpx struct {
Type int16
Tv Timeval
Id [8]int8
Pid int32
User [32]int8
Line [16]int8
Host [125]int8
// Host [128]int8
// X__ut_spare [64]int8
}
type Timeval struct {
Sec [4]byte
Usec [3]byte
}

View File

@@ -0,0 +1,44 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmpx = 197 // TODO: why should 197, not 0x118
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type Utmp struct {
Line [8]int8
Name [16]int8
Host [16]int8
Time int32
}
type Utmpx struct {
Type int16
Tv Timeval
Id [8]int8
Pid int32
User [32]int8
Line [16]int8
Host [125]int8
// Host [128]int8
// X__ut_spare [64]int8
}
type Timeval struct {
Sec [4]byte
Usec [3]byte
}

682
vendor/github.com/shirou/gopsutil/host/host_linux.go generated vendored Normal file
View File

@@ -0,0 +1,682 @@
// +build linux
package host
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/shirou/gopsutil/internal/common"
)
type LSB struct {
ID string
Release string
Codename string
Description string
}
// from utmp.h
const USER_PROCESS = 7
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
}
kernelVersion, err := KernelVersion()
if err == nil {
ret.KernelVersion = kernelVersion
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
if numProcs, err := common.NumProcs(); err == nil {
ret.Procs = numProcs
}
sysProductUUID := common.HostSys("class/dmi/id/product_uuid")
machineID := common.HostEtc("machine-id")
switch {
// In order to read this file, needs to be supported by kernel/arch and run as root
// so having fallback is important
case common.PathExists(sysProductUUID):
lines, err := common.ReadLines(sysProductUUID)
if err == nil && len(lines) > 0 && lines[0] != "" {
ret.HostID = strings.ToLower(lines[0])
break
}
fallthrough
// Fallback on GNU Linux systems with systemd, readable by everyone
case common.PathExists(machineID):
lines, err := common.ReadLines(machineID)
if err == nil && len(lines) > 0 && len(lines[0]) == 32 {
st := lines[0]
ret.HostID = fmt.Sprintf("%s-%s-%s-%s-%s", st[0:8], st[8:12], st[12:16], st[16:20], st[20:32])
break
}
fallthrough
// Not stable between reboot, but better than nothing
default:
values, err := common.DoSysctrl("kernel.random.boot_id")
if err == nil && len(values) == 1 && values[0] != "" {
ret.HostID = strings.ToLower(values[0])
}
}
return ret, nil
}
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
// BootTime returns the system boot time expressed in seconds since the epoch.
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
system, role, err := Virtualization()
if err != nil {
return 0, err
}
statFile := "stat"
if system == "lxc" && role == "guest" {
// if lxc, /proc/uptime is used.
statFile = "uptime"
} else if system == "docker" && role == "guest" {
// also docker, guest
statFile = "uptime"
}
filename := common.HostProc(statFile)
lines, err := common.ReadLines(filename)
if err != nil {
return 0, err
}
if statFile == "stat" {
for _, line := range lines {
if strings.HasPrefix(line, "btime") {
f := strings.Fields(line)
if len(f) != 2 {
return 0, fmt.Errorf("wrong btime format")
}
b, err := strconv.ParseInt(f[1], 10, 64)
if err != nil {
return 0, err
}
t = uint64(b)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
}
} else if statFile == "uptime" {
if len(lines) != 1 {
return 0, fmt.Errorf("wrong uptime format")
}
f := strings.Fields(lines[0])
b, err := strconv.ParseFloat(f[0], 64)
if err != nil {
return 0, err
}
t = uint64(time.Now().Unix()) - uint64(b)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
return 0, fmt.Errorf("could not find btime")
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
utmpfile := common.HostVar("run/utmp")
file, err := os.Open(utmpfile)
if err != nil {
return nil, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return nil, err
}
count := len(buf) / sizeOfUtmp
ret := make([]UserStat, 0, count)
for i := 0; i < count; i++ {
b := buf[i*sizeOfUtmp : (i+1)*sizeOfUtmp]
var u utmp
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil {
continue
}
if u.Type != USER_PROCESS {
continue
}
user := UserStat{
User: common.IntToString(u.User[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Tv.Sec),
}
ret = append(ret, user)
}
return ret, nil
}
func getOSRelease() (platform string, version string, err error) {
contents, err := common.ReadLines(common.HostEtc("os-release"))
if err != nil {
return "", "", nil // return empty
}
for _, line := range contents {
field := strings.Split(line, "=")
if len(field) < 2 {
continue
}
switch field[0] {
case "ID": // use ID for lowercase
platform = field[1]
case "VERSION":
version = field[1]
}
}
return platform, version, nil
}
func getLSB() (*LSB, error) {
ret := &LSB{}
if common.PathExists(common.HostEtc("lsb-release")) {
contents, err := common.ReadLines(common.HostEtc("lsb-release"))
if err != nil {
return ret, err // return empty
}
for _, line := range contents {
field := strings.Split(line, "=")
if len(field) < 2 {
continue
}
switch field[0] {
case "DISTRIB_ID":
ret.ID = field[1]
case "DISTRIB_RELEASE":
ret.Release = field[1]
case "DISTRIB_CODENAME":
ret.Codename = field[1]
case "DISTRIB_DESCRIPTION":
ret.Description = field[1]
}
}
} else if common.PathExists("/usr/bin/lsb_release") {
lsb_release, err := exec.LookPath("/usr/bin/lsb_release")
if err != nil {
return ret, err
}
out, err := invoke.Command(lsb_release)
if err != nil {
return ret, err
}
for _, line := range strings.Split(string(out), "\n") {
field := strings.Split(line, ":")
if len(field) < 2 {
continue
}
switch field[0] {
case "Distributor ID":
ret.ID = field[1]
case "Release":
ret.Release = field[1]
case "Codename":
ret.Codename = field[1]
case "Description":
ret.Description = field[1]
}
}
}
return ret, nil
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
lsb, err := getLSB()
if err != nil {
lsb = &LSB{}
}
if common.PathExists(common.HostEtc("oracle-release")) {
platform = "oracle"
contents, err := common.ReadLines(common.HostEtc("oracle-release"))
if err == nil {
version = getRedhatishVersion(contents)
}
} else if common.PathExists(common.HostEtc("enterprise-release")) {
platform = "oracle"
contents, err := common.ReadLines(common.HostEtc("enterprise-release"))
if err == nil {
version = getRedhatishVersion(contents)
}
} else if common.PathExists(common.HostEtc("slackware-version")) {
platform = "slackware"
contents, err := common.ReadLines(common.HostEtc("slackware-version"))
if err == nil {
version = getSlackwareVersion(contents)
}
} else if common.PathExists(common.HostEtc("debian_version")) {
if lsb.ID == "Ubuntu" {
platform = "ubuntu"
version = lsb.Release
} else if lsb.ID == "LinuxMint" {
platform = "linuxmint"
version = lsb.Release
} else {
if common.PathExists("/usr/bin/raspi-config") {
platform = "raspbian"
} else {
platform = "debian"
}
contents, err := common.ReadLines(common.HostEtc("debian_version"))
if err == nil {
version = contents[0]
}
}
} else if common.PathExists(common.HostEtc("redhat-release")) {
contents, err := common.ReadLines(common.HostEtc("redhat-release"))
if err == nil {
version = getRedhatishVersion(contents)
platform = getRedhatishPlatform(contents)
}
} else if common.PathExists(common.HostEtc("system-release")) {
contents, err := common.ReadLines(common.HostEtc("system-release"))
if err == nil {
version = getRedhatishVersion(contents)
platform = getRedhatishPlatform(contents)
}
} else if common.PathExists(common.HostEtc("gentoo-release")) {
platform = "gentoo"
contents, err := common.ReadLines(common.HostEtc("gentoo-release"))
if err == nil {
version = getRedhatishVersion(contents)
}
} else if common.PathExists(common.HostEtc("SuSE-release")) {
contents, err := common.ReadLines(common.HostEtc("SuSE-release"))
if err == nil {
version = getSuseVersion(contents)
platform = getSusePlatform(contents)
}
// TODO: slackware detecion
} else if common.PathExists(common.HostEtc("arch-release")) {
platform = "arch"
version = lsb.Release
} else if common.PathExists(common.HostEtc("alpine-release")) {
platform = "alpine"
contents, err := common.ReadLines(common.HostEtc("alpine-release"))
if err == nil && len(contents) > 0 {
version = contents[0]
}
} else if common.PathExists(common.HostEtc("os-release")) {
p, v, err := getOSRelease()
if err == nil {
platform = p
version = v
}
} else if lsb.ID == "RedHat" {
platform = "redhat"
version = lsb.Release
} else if lsb.ID == "Amazon" {
platform = "amazon"
version = lsb.Release
} else if lsb.ID == "ScientificSL" {
platform = "scientific"
version = lsb.Release
} else if lsb.ID == "XenServer" {
platform = "xenserver"
version = lsb.Release
} else if lsb.ID != "" {
platform = strings.ToLower(lsb.ID)
version = lsb.Release
}
switch platform {
case "debian", "ubuntu", "linuxmint", "raspbian":
family = "debian"
case "fedora":
family = "fedora"
case "oracle", "centos", "redhat", "scientific", "enterpriseenterprise", "amazon", "xenserver", "cloudlinux", "ibm_powerkvm":
family = "rhel"
case "suse", "opensuse":
family = "suse"
case "gentoo":
family = "gentoo"
case "slackware":
family = "slackware"
case "arch":
family = "arch"
case "exherbo":
family = "exherbo"
case "alpine":
family = "alpine"
case "coreos":
family = "coreos"
}
return platform, family, version, nil
}
func KernelVersion() (version string, err error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (version string, err error) {
filename := common.HostProc("sys/kernel/osrelease")
if common.PathExists(filename) {
contents, err := common.ReadLines(filename)
if err != nil {
return "", err
}
if len(contents) > 0 {
version = contents[0]
}
}
return version, nil
}
func getSlackwareVersion(contents []string) string {
c := strings.ToLower(strings.Join(contents, ""))
c = strings.Replace(c, "slackware ", "", 1)
return c
}
func getRedhatishVersion(contents []string) string {
c := strings.ToLower(strings.Join(contents, ""))
if strings.Contains(c, "rawhide") {
return "rawhide"
}
if matches := regexp.MustCompile(`release (\d[\d.]*)`).FindStringSubmatch(c); matches != nil {
return matches[1]
}
return ""
}
func getRedhatishPlatform(contents []string) string {
c := strings.ToLower(strings.Join(contents, ""))
if strings.Contains(c, "red hat") {
return "redhat"
}
f := strings.Split(c, " ")
return f[0]
}
func getSuseVersion(contents []string) string {
version := ""
for _, line := range contents {
if matches := regexp.MustCompile(`VERSION = ([\d.]+)`).FindStringSubmatch(line); matches != nil {
version = matches[1]
} else if matches := regexp.MustCompile(`PATCHLEVEL = ([\d]+)`).FindStringSubmatch(line); matches != nil {
version = version + "." + matches[1]
}
}
return version
}
func getSusePlatform(contents []string) string {
c := strings.ToLower(strings.Join(contents, ""))
if strings.Contains(c, "opensuse") {
return "opensuse"
}
return "suse"
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
var system string
var role string
filename := common.HostProc("xen")
if common.PathExists(filename) {
system = "xen"
role = "guest" // assume guest
if common.PathExists(filepath.Join(filename, "capabilities")) {
contents, err := common.ReadLines(filepath.Join(filename, "capabilities"))
if err == nil {
if common.StringsContains(contents, "control_d") {
role = "host"
}
}
}
}
filename = common.HostProc("modules")
if common.PathExists(filename) {
contents, err := common.ReadLines(filename)
if err == nil {
if common.StringsContains(contents, "kvm") {
system = "kvm"
role = "host"
} else if common.StringsContains(contents, "vboxdrv") {
system = "vbox"
role = "host"
} else if common.StringsContains(contents, "vboxguest") {
system = "vbox"
role = "guest"
} else if common.StringsContains(contents, "vmware") {
system = "vmware"
role = "guest"
}
}
}
filename = common.HostProc("cpuinfo")
if common.PathExists(filename) {
contents, err := common.ReadLines(filename)
if err == nil {
if common.StringsContains(contents, "QEMU Virtual CPU") ||
common.StringsContains(contents, "Common KVM processor") ||
common.StringsContains(contents, "Common 32-bit KVM processor") {
system = "kvm"
role = "guest"
}
}
}
filename = common.HostProc()
if common.PathExists(filepath.Join(filename, "bc", "0")) {
system = "openvz"
role = "host"
} else if common.PathExists(filepath.Join(filename, "vz")) {
system = "openvz"
role = "guest"
}
// not use dmidecode because it requires root
if common.PathExists(filepath.Join(filename, "self", "status")) {
contents, err := common.ReadLines(filepath.Join(filename, "self", "status"))
if err == nil {
if common.StringsContains(contents, "s_context:") ||
common.StringsContains(contents, "VxID:") {
system = "linux-vserver"
}
// TODO: guest or host
}
}
if common.PathExists(filepath.Join(filename, "self", "cgroup")) {
contents, err := common.ReadLines(filepath.Join(filename, "self", "cgroup"))
if err == nil {
if common.StringsContains(contents, "lxc") {
system = "lxc"
role = "guest"
} else if common.StringsContains(contents, "docker") {
system = "docker"
role = "guest"
} else if common.StringsContains(contents, "machine-rkt") {
system = "rkt"
role = "guest"
} else if common.PathExists("/usr/bin/lxc-version") {
system = "lxc"
role = "host"
}
}
}
if common.PathExists(common.HostEtc("os-release")) {
p, _, err := getOSRelease()
if err == nil && p == "coreos" {
system = "rkt" // Is it true?
role = "host"
}
}
return system, role, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var temperatures []TemperatureStat
files, err := filepath.Glob(common.HostSys("/class/hwmon/hwmon*/temp*_*"))
if err != nil {
return temperatures, err
}
if len(files) == 0 {
// CentOS has an intermediate /device directory:
// https://github.com/giampaolo/psutil/issues/971
files, err = filepath.Glob(common.HostSys("/class/hwmon/hwmon*/device/temp*_*"))
if err != nil {
return temperatures, err
}
}
// example directory
// device/ temp1_crit_alarm temp2_crit_alarm temp3_crit_alarm temp4_crit_alarm temp5_crit_alarm temp6_crit_alarm temp7_crit_alarm
// name temp1_input temp2_input temp3_input temp4_input temp5_input temp6_input temp7_input
// power/ temp1_label temp2_label temp3_label temp4_label temp5_label temp6_label temp7_label
// subsystem/ temp1_max temp2_max temp3_max temp4_max temp5_max temp6_max temp7_max
// temp1_crit temp2_crit temp3_crit temp4_crit temp5_crit temp6_crit temp7_crit uevent
for _, file := range files {
filename := strings.Split(filepath.Base(file), "_")
if filename[1] == "label" {
// Do not try to read the temperature of the label file
continue
}
// Get the label of the temperature you are reading
var label string
c, _ := ioutil.ReadFile(filepath.Join(filepath.Dir(file), filename[0]+"_label"))
if c != nil {
//format the label from "Core 0" to "core0_"
label = fmt.Sprintf("%s_", strings.Join(strings.Split(strings.TrimSpace(strings.ToLower(string(c))), " "), ""))
}
// Get the name of the tempearture you are reading
name, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), "name"))
if err != nil {
return temperatures, err
}
// Get the temperature reading
current, err := ioutil.ReadFile(file)
if err != nil {
return temperatures, err
}
temperature, err := strconv.ParseFloat(strings.TrimSpace(string(current)), 64)
if err != nil {
continue
}
tempName := strings.TrimSpace(strings.ToLower(string(strings.Join(filename[1:], ""))))
temperatures = append(temperatures, TemperatureStat{
SensorKey: fmt.Sprintf("%s_%s%s", strings.TrimSpace(string(name)), label, tempName),
Temperature: temperature / 1000.0,
})
}
return temperatures, nil
}

View File

@@ -0,0 +1,45 @@
// ATTENTION - FILE MANUAL FIXED AFTER CGO.
// Fixed line: Tv _Ctype_struct_timeval -> Tv UtTv
// Created by cgo -godefs, MANUAL FIXED
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
ID [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv UtTv
Addr_v6 [4]int32
X__unused [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type UtTv struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,48 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv _Ctype_struct___0
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int64
Usec int64
}
type _Ctype_struct___0 struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go | sed "s/uint8/int8/g"
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int64
Usec int64
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__unused [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__unused [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__unused [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,43 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__unused [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int32
Usec int32
}

View File

@@ -0,0 +1,45 @@
// +build linux
// +build ppc64le
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int64
Usec int64
}

View File

@@ -0,0 +1,45 @@
// +build linux
// +build s390x
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_linux.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x180
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type utmp struct {
Type int16
Pad_cgo_0 [2]byte
Pid int32
Line [32]int8
Id [4]int8
User [32]int8
Host [256]int8
Exit exit_status
Session int32
Tv timeval
Addr_v6 [4]int32
X__glibc_reserved [20]int8
}
type exit_status struct {
Termination int16
Exit int16
}
type timeval struct {
Sec int64
Usec int64
}

195
vendor/github.com/shirou/gopsutil/host/host_openbsd.go generated vendored Normal file
View File

@@ -0,0 +1,195 @@
// +build openbsd
package host
import (
"bytes"
"context"
"encoding/binary"
"io/ioutil"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"time"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/process"
)
const (
UTNameSize = 32 /* see MAXLOGNAME in <sys/param.h> */
UTLineSize = 8
UTHostSize = 16
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
PlatformFamily: "openbsd",
}
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
platform, family, version, err := PlatformInformation()
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
}
system, role, err := Virtualization()
if err == nil {
ret.VirtualizationSystem = system
ret.VirtualizationRole = role
}
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime = uptime(boot)
}
return ret, nil
}
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
val, err := common.DoSysctrl("kern.boottime")
if err != nil {
return 0, err
}
boottime, err := strconv.ParseUint(val[0], 10, 64)
if err != nil {
return 0, err
}
return boottime, nil
}
func uptime(boot uint64) uint64 {
return uint64(time.Now().Unix()) - boot
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
boot, err := BootTime()
if err != nil {
return 0, err
}
return uptime(boot), nil
}
func PlatformInformation() (string, string, string, error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (string, string, string, error) {
platform := ""
family := ""
version := ""
uname, err := exec.LookPath("uname")
if err != nil {
return "", "", "", err
}
out, err := invoke.CommandWithContext(ctx, uname, "-s")
if err == nil {
platform = strings.ToLower(strings.TrimSpace(string(out)))
}
out, err = invoke.CommandWithContext(ctx, uname, "-r")
if err == nil {
version = strings.ToLower(strings.TrimSpace(string(out)))
}
return platform, family, version, nil
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
utmpfile := "/var/run/utmp"
file, err := os.Open(utmpfile)
if err != nil {
return ret, err
}
defer file.Close()
buf, err := ioutil.ReadAll(file)
if err != nil {
return ret, err
}
u := Utmp{}
entrySize := int(unsafe.Sizeof(u))
count := len(buf) / entrySize
for i := 0; i < count; i++ {
b := buf[i*entrySize : i*entrySize+entrySize]
var u Utmp
br := bytes.NewReader(b)
err := binary.Read(br, binary.LittleEndian, &u)
if err != nil || u.Time == 0 {
continue
}
user := UserStat{
User: common.IntToString(u.Name[:]),
Terminal: common.IntToString(u.Line[:]),
Host: common.IntToString(u.Host[:]),
Started: int(u.Time),
}
ret = append(ret, user)
}
return ret, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
return version, err
}

View File

@@ -0,0 +1,31 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_openbsd.go
package host
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
sizeOfUtmp = 0x130
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Utmp struct {
Line [8]int8
Name [32]int8
Host [256]int8
Time int64
}
type Timeval struct {
Sec int64
Usec int64
}

248
vendor/github.com/shirou/gopsutil/host/host_solaris.go generated vendored Normal file
View File

@@ -0,0 +1,248 @@
package host
import (
"bufio"
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"runtime"
"strconv"
"strings"
"time"
"github.com/shirou/gopsutil/internal/common"
)
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
result := &InfoStat{
OS: runtime.GOOS,
}
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
result.Hostname = hostname
// Parse versions from output of `uname(1)`
uname, err := exec.LookPath("/usr/bin/uname")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, uname, "-srv")
if err != nil {
return nil, err
}
fields := strings.Fields(string(out))
if len(fields) >= 1 {
result.PlatformFamily = fields[0]
}
if len(fields) >= 2 {
result.KernelVersion = fields[1]
}
if len(fields) == 3 {
result.PlatformVersion = fields[2]
}
// Find distribution name from /etc/release
fh, err := os.Open("/etc/release")
if err != nil {
return nil, err
}
defer fh.Close()
sc := bufio.NewScanner(fh)
if sc.Scan() {
line := strings.TrimSpace(sc.Text())
switch {
case strings.HasPrefix(line, "SmartOS"):
result.Platform = "SmartOS"
case strings.HasPrefix(line, "OpenIndiana"):
result.Platform = "OpenIndiana"
case strings.HasPrefix(line, "OmniOS"):
result.Platform = "OmniOS"
case strings.HasPrefix(line, "Open Storage"):
result.Platform = "NexentaStor"
case strings.HasPrefix(line, "Solaris"):
result.Platform = "Solaris"
case strings.HasPrefix(line, "Oracle Solaris"):
result.Platform = "Solaris"
default:
result.Platform = strings.Fields(line)[0]
}
}
switch result.Platform {
case "SmartOS":
// If everything works, use the current zone ID as the HostID if present.
zonename, err := exec.LookPath("/usr/bin/zonename")
if err == nil {
out, err := invoke.CommandWithContext(ctx, zonename)
if err == nil {
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := sc.Text()
// If we're in the global zone, rely on the hostname.
if line == "global" {
hostname, err := os.Hostname()
if err == nil {
result.HostID = hostname
}
} else {
result.HostID = strings.TrimSpace(line)
break
}
}
}
}
}
// If HostID is still empty, use hostid(1), which can lie to callers but at
// this point there are no hardware facilities available. This behavior
// matches that of other supported OSes.
if result.HostID == "" {
hostID, err := exec.LookPath("/usr/bin/hostid")
if err == nil {
out, err := invoke.CommandWithContext(ctx, hostID)
if err == nil {
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := sc.Text()
result.HostID = strings.TrimSpace(line)
break
}
}
}
}
// Find the boot time and calculate uptime relative to it
bootTime, err := BootTime()
if err != nil {
return nil, err
}
result.BootTime = bootTime
result.Uptime = uptimeSince(bootTime)
// Count number of processes based on the number of entries in /proc
dirs, err := ioutil.ReadDir("/proc")
if err != nil {
return nil, err
}
result.Procs = uint64(len(dirs))
return result, nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
kstat, err := exec.LookPath("/usr/bin/kstat")
if err != nil {
return 0, err
}
out, err := invoke.CommandWithContext(ctx, kstat, "-p", "unix:0:system_misc:boot_time")
if err != nil {
return 0, err
}
kstats := kstatMatch.FindAllStringSubmatch(string(out), -1)
if len(kstats) != 1 {
return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats))
}
return strconv.ParseUint(kstats[0][2], 10, 64)
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
bootTime, err := BootTime()
if err != nil {
return 0, err
}
return uptimeSince(bootTime), nil
}
func uptimeSince(since uint64) uint64 {
return uint64(time.Now().Unix()) - since
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
return []UserStat{}, common.ErrNotImplementedError
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
return []TemperatureStat{}, common.ErrNotImplementedError
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
// Parse versions from output of `uname(1)`
uname, err := exec.LookPath("/usr/bin/uname")
if err != nil {
return "", err
}
out, err := invoke.CommandWithContext(ctx, uname, "-srv")
if err != nil {
return "", err
}
fields := strings.Fields(string(out))
if len(fields) >= 2 {
return fields[1], nil
}
return "", fmt.Errorf("could not get kernel version")
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
/* This is not finished yet at all. Please contribute! */
version, err = KernelVersion()
if err != nil {
return "", "", "", err
}
return "solaris", "solaris", version, nil
}

295
vendor/github.com/shirou/gopsutil/host/host_windows.go generated vendored Normal file
View File

@@ -0,0 +1,295 @@
// +build windows
package host
import (
"context"
"fmt"
"math"
"os"
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
"unsafe"
"github.com/StackExchange/wmi"
"github.com/shirou/gopsutil/internal/common"
process "github.com/shirou/gopsutil/process"
"golang.org/x/sys/windows"
)
var (
procGetSystemTimeAsFileTime = common.Modkernel32.NewProc("GetSystemTimeAsFileTime")
procGetTickCount32 = common.Modkernel32.NewProc("GetTickCount")
procGetTickCount64 = common.Modkernel32.NewProc("GetTickCount64")
procRtlGetVersion = common.ModNt.NewProc("RtlGetVersion")
)
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_osversioninfoexw
type osVersionInfoExW struct {
dwOSVersionInfoSize uint32
dwMajorVersion uint32
dwMinorVersion uint32
dwBuildNumber uint32
dwPlatformId uint32
szCSDVersion [128]uint16
wServicePackMajor uint16
wServicePackMinor uint16
wSuiteMask uint16
wProductType uint8
wReserved uint8
}
type msAcpi_ThermalZoneTemperature struct {
Active bool
CriticalTripPoint uint32
CurrentTemperature uint32
InstanceName string
}
func Info() (*InfoStat, error) {
return InfoWithContext(context.Background())
}
func InfoWithContext(ctx context.Context) (*InfoStat, error) {
ret := &InfoStat{
OS: runtime.GOOS,
}
{
hostname, err := os.Hostname()
if err == nil {
ret.Hostname = hostname
}
}
{
platform, family, version, err := PlatformInformationWithContext(ctx)
if err == nil {
ret.Platform = platform
ret.PlatformFamily = family
ret.PlatformVersion = version
} else {
return ret, err
}
}
{
boot, err := BootTime()
if err == nil {
ret.BootTime = boot
ret.Uptime, _ = Uptime()
}
}
{
hostID, err := getMachineGuid()
if err == nil {
ret.HostID = strings.ToLower(hostID)
}
}
{
procs, err := process.Pids()
if err == nil {
ret.Procs = uint64(len(procs))
}
}
return ret, nil
}
func getMachineGuid() (string, error) {
// there has been reports of issues on 32bit using golang.org/x/sys/windows/registry, see https://github.com/shirou/gopsutil/pull/312#issuecomment-277422612
// for rationale of using windows.RegOpenKeyEx/RegQueryValueEx instead of registry.OpenKey/GetStringValue
var h windows.Handle
err := windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h)
if err != nil {
return "", err
}
defer windows.RegCloseKey(h)
const windowsRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16
const uuidLen = 36
var regBuf [windowsRegBufLen]uint16
bufLen := uint32(windowsRegBufLen)
var valType uint32
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(&regBuf[0])), &bufLen)
if err != nil {
return "", err
}
hostID := windows.UTF16ToString(regBuf[:])
hostIDLen := len(hostID)
if hostIDLen != uuidLen {
return "", fmt.Errorf("HostID incorrect: %q\n", hostID)
}
return hostID, nil
}
func Uptime() (uint64, error) {
return UptimeWithContext(context.Background())
}
func UptimeWithContext(ctx context.Context) (uint64, error) {
procGetTickCount := procGetTickCount64
err := procGetTickCount64.Find()
if err != nil {
procGetTickCount = procGetTickCount32 // handle WinXP, but keep in mind that "the time will wrap around to zero if the system is run continuously for 49.7 days." from MSDN
}
r1, _, lastErr := syscall.Syscall(procGetTickCount.Addr(), 0, 0, 0, 0)
if lastErr != 0 {
return 0, lastErr
}
return uint64((time.Duration(r1) * time.Millisecond).Seconds()), nil
}
func bootTimeFromUptime(up uint64) uint64 {
return uint64(time.Now().Unix()) - up
}
// cachedBootTime must be accessed via atomic.Load/StoreUint64
var cachedBootTime uint64
func BootTime() (uint64, error) {
return BootTimeWithContext(context.Background())
}
func BootTimeWithContext(ctx context.Context) (uint64, error) {
t := atomic.LoadUint64(&cachedBootTime)
if t != 0 {
return t, nil
}
up, err := Uptime()
if err != nil {
return 0, err
}
t = bootTimeFromUptime(up)
atomic.StoreUint64(&cachedBootTime, t)
return t, nil
}
func PlatformInformation() (platform string, family string, version string, err error) {
return PlatformInformationWithContext(context.Background())
}
func PlatformInformationWithContext(ctx context.Context) (platform string, family string, version string, err error) {
// GetVersionEx lies on Windows 8.1 and returns as Windows 8 if we don't declare compatibility in manifest
// RtlGetVersion bypasses this lying layer and returns the true Windows version
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-rtlgetversion
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_osversioninfoexw
var osInfo osVersionInfoExW
osInfo.dwOSVersionInfoSize = uint32(unsafe.Sizeof(osInfo))
ret, _, err := procRtlGetVersion.Call(uintptr(unsafe.Pointer(&osInfo)))
if ret != 0 {
return
}
// Platform
var h windows.Handle // like getMachineGuid(), we query the registry using the raw windows.RegOpenKeyEx/RegQueryValueEx
err = windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE, windows.StringToUTF16Ptr(`SOFTWARE\Microsoft\Windows NT\CurrentVersion`), 0, windows.KEY_READ|windows.KEY_WOW64_64KEY, &h)
if err != nil {
return
}
defer windows.RegCloseKey(h)
var bufLen uint32
var valType uint32
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, nil, &bufLen)
if err != nil {
return
}
regBuf := make([]uint16, bufLen/2+1)
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`ProductName`), nil, &valType, (*byte)(unsafe.Pointer(&regBuf[0])), &bufLen)
if err != nil {
return
}
platform = windows.UTF16ToString(regBuf[:])
if !strings.HasPrefix(platform, "Microsoft") {
platform = "Microsoft " + platform
}
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`CSDVersion`), nil, &valType, nil, &bufLen) // append Service Pack number, only on success
if err == nil { // don't return an error if only the Service Pack retrieval fails
regBuf = make([]uint16, bufLen/2+1)
err = windows.RegQueryValueEx(h, windows.StringToUTF16Ptr(`CSDVersion`), nil, &valType, (*byte)(unsafe.Pointer(&regBuf[0])), &bufLen)
if err == nil {
platform += " " + windows.UTF16ToString(regBuf[:])
}
}
// PlatformFamily
switch osInfo.wProductType {
case 1:
family = "Standalone Workstation"
case 2:
family = "Server (Domain Controller)"
case 3:
family = "Server"
}
// Platform Version
version = fmt.Sprintf("%d.%d.%d Build %d", osInfo.dwMajorVersion, osInfo.dwMinorVersion, osInfo.dwBuildNumber, osInfo.dwBuildNumber)
return platform, family, version, nil
}
func Users() ([]UserStat, error) {
return UsersWithContext(context.Background())
}
func UsersWithContext(ctx context.Context) ([]UserStat, error) {
var ret []UserStat
return ret, nil
}
func SensorsTemperatures() ([]TemperatureStat, error) {
return SensorsTemperaturesWithContext(context.Background())
}
func SensorsTemperaturesWithContext(ctx context.Context) ([]TemperatureStat, error) {
var ret []TemperatureStat
var dst []msAcpi_ThermalZoneTemperature
q := wmi.CreateQuery(&dst, "")
if err := common.WMIQueryWithContext(ctx, q, &dst, nil, "root/wmi"); err != nil {
return ret, err
}
for _, v := range dst {
ts := TemperatureStat{
SensorKey: v.InstanceName,
Temperature: kelvinToCelsius(v.CurrentTemperature, 2),
}
ret = append(ret, ts)
}
return ret, nil
}
func kelvinToCelsius(temp uint32, n int) float64 {
// wmi return temperature Kelvin * 10, so need to divide the result by 10,
// and then minus 273.15 to get °Celsius.
t := float64(temp/10) - 273.15
n10 := math.Pow10(n)
return math.Trunc((t+0.5/n10)*n10) / n10
}
func Virtualization() (string, string, error) {
return VirtualizationWithContext(context.Background())
}
func VirtualizationWithContext(ctx context.Context) (string, string, error) {
return "", "", common.ErrNotImplementedError
}
func KernelVersion() (string, error) {
return KernelVersionWithContext(context.Background())
}
func KernelVersionWithContext(ctx context.Context) (string, error) {
_, _, version, err := PlatformInformation()
return version, err
}

17
vendor/github.com/shirou/gopsutil/host/types_darwin.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
// +build ignore
// plus hand editing about timeval
/*
Input to cgo -godefs.
*/
package host
/*
#include <sys/time.h>
#include <utmpx.h>
*/
import "C"
type Utmpx C.struct_utmpx
type Timeval C.struct_timeval

View File

@@ -0,0 +1,44 @@
// +build ignore
/*
Input to cgo -godefs.
*/
package host
/*
#define KERNEL
#include <sys/types.h>
#include <sys/time.h>
#include <utmpx.h>
enum {
sizeofPtr = sizeof(void*),
};
*/
import "C"
// Machine characteristics; for internal use.
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
sizeOfUtmpx = C.sizeof_struct_utmpx
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
type Utmp C.struct_utmp
type Utmpx C.struct_utmpx
type Timeval C.struct_timeval

42
vendor/github.com/shirou/gopsutil/host/types_linux.go generated vendored Normal file
View File

@@ -0,0 +1,42 @@
// +build ignore
/*
Input to cgo -godefs.
*/
package host
/*
#include <sys/types.h>
#include <utmp.h>
enum {
sizeofPtr = sizeof(void*),
};
*/
import "C"
// Machine characteristics; for internal use.
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
sizeOfUtmp = C.sizeof_struct_utmp
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
type utmp C.struct_utmp
type exit_status C.struct_exit_status
type timeval C.struct_timeval

View File

@@ -0,0 +1,43 @@
// +build ignore
/*
Input to cgo -godefs.
*/
package host
/*
#define KERNEL
#include <sys/types.h>
#include <sys/time.h>
#include <utmp.h>
enum {
sizeofPtr = sizeof(void*),
};
*/
import "C"
// Machine characteristics; for internal use.
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
sizeOfUtmp = C.sizeof_struct_utmp
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
type Utmp C.struct_utmp
type Timeval C.struct_timeval

97
vendor/github.com/shirou/gopsutil/mem/mem.go generated vendored Normal file
View File

@@ -0,0 +1,97 @@
package mem
import (
"encoding/json"
"github.com/shirou/gopsutil/internal/common"
)
var invoke common.Invoker = common.Invoke{}
// Memory usage statistics. Total, Available and Used contain numbers of bytes
// for human consumption.
//
// The other fields in this struct contain kernel specific values.
type VirtualMemoryStat struct {
// Total amount of RAM on this system
Total uint64 `json:"total"`
// RAM available for programs to allocate
//
// This value is computed from the kernel specific values.
Available uint64 `json:"available"`
// RAM used by programs
//
// This value is computed from the kernel specific values.
Used uint64 `json:"used"`
// Percentage of RAM used by programs
//
// This value is computed from the kernel specific values.
UsedPercent float64 `json:"usedPercent"`
// This is the kernel's notion of free memory; RAM chips whose bits nobody
// cares about the value of right now. For a human consumable number,
// Available is what you really want.
Free uint64 `json:"free"`
// OS X / BSD specific numbers:
// http://www.macyourself.com/2010/02/17/what-is-free-wired-active-and-inactive-system-memory-ram/
Active uint64 `json:"active"`
Inactive uint64 `json:"inactive"`
Wired uint64 `json:"wired"`
// FreeBSD specific numbers:
// https://reviews.freebsd.org/D8467
Laundry uint64 `json:"laundry"`
// Linux specific numbers
// https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s2-proc-meminfo.html
// https://www.kernel.org/doc/Documentation/filesystems/proc.txt
// https://www.kernel.org/doc/Documentation/vm/overcommit-accounting
Buffers uint64 `json:"buffers"`
Cached uint64 `json:"cached"`
Writeback uint64 `json:"writeback"`
Dirty uint64 `json:"dirty"`
WritebackTmp uint64 `json:"writebacktmp"`
Shared uint64 `json:"shared"`
Slab uint64 `json:"slab"`
SReclaimable uint64 `json:"sreclaimable"`
PageTables uint64 `json:"pagetables"`
SwapCached uint64 `json:"swapcached"`
CommitLimit uint64 `json:"commitlimit"`
CommittedAS uint64 `json:"committedas"`
HighTotal uint64 `json:"hightotal"`
HighFree uint64 `json:"highfree"`
LowTotal uint64 `json:"lowtotal"`
LowFree uint64 `json:"lowfree"`
SwapTotal uint64 `json:"swaptotal"`
SwapFree uint64 `json:"swapfree"`
Mapped uint64 `json:"mapped"`
VMallocTotal uint64 `json:"vmalloctotal"`
VMallocUsed uint64 `json:"vmallocused"`
VMallocChunk uint64 `json:"vmallocchunk"`
HugePagesTotal uint64 `json:"hugepagestotal"`
HugePagesFree uint64 `json:"hugepagesfree"`
HugePageSize uint64 `json:"hugepagesize"`
}
type SwapMemoryStat struct {
Total uint64 `json:"total"`
Used uint64 `json:"used"`
Free uint64 `json:"free"`
UsedPercent float64 `json:"usedPercent"`
Sin uint64 `json:"sin"`
Sout uint64 `json:"sout"`
}
func (m VirtualMemoryStat) String() string {
s, _ := json.Marshal(m)
return string(s)
}
func (m SwapMemoryStat) String() string {
s, _ := json.Marshal(m)
return string(s)
}

74
vendor/github.com/shirou/gopsutil/mem/mem_darwin.go generated vendored Normal file
View File

@@ -0,0 +1,74 @@
// +build darwin
package mem
import (
"context"
"encoding/binary"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
func getHwMemsize() (uint64, error) {
totalString, err := unix.Sysctl("hw.memsize")
if err != nil {
return 0, err
}
// unix.sysctl() helpfully assumes the result is a null-terminated string and
// removes the last byte of the result if it's 0 :/
totalString += "\x00"
total := uint64(binary.LittleEndian.Uint64([]byte(totalString)))
return total, nil
}
// SwapMemory returns swapinfo.
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
var ret *SwapMemoryStat
swapUsage, err := common.DoSysctrlWithContext(ctx, "vm.swapusage")
if err != nil {
return ret, err
}
total := strings.Replace(swapUsage[2], "M", "", 1)
used := strings.Replace(swapUsage[5], "M", "", 1)
free := strings.Replace(swapUsage[8], "M", "", 1)
total_v, err := strconv.ParseFloat(total, 64)
if err != nil {
return nil, err
}
used_v, err := strconv.ParseFloat(used, 64)
if err != nil {
return nil, err
}
free_v, err := strconv.ParseFloat(free, 64)
if err != nil {
return nil, err
}
u := float64(0)
if total_v != 0 {
u = ((total_v - free_v) / total_v) * 100.0
}
// vm.swapusage shows "M", multiply 1024 * 1024 to convert bytes.
ret = &SwapMemoryStat{
Total: uint64(total_v * 1024 * 1024),
Used: uint64(used_v * 1024 * 1024),
Free: uint64(free_v * 1024 * 1024),
UsedPercent: u,
}
return ret, nil
}

View File

@@ -0,0 +1,59 @@
// +build darwin
// +build cgo
package mem
/*
#include <mach/mach_host.h>
*/
import "C"
import (
"context"
"fmt"
"unsafe"
"golang.org/x/sys/unix"
)
// VirtualMemory returns VirtualmemoryStat.
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
count := C.mach_msg_type_number_t(C.HOST_VM_INFO_COUNT)
var vmstat C.vm_statistics_data_t
status := C.host_statistics(C.host_t(C.mach_host_self()),
C.HOST_VM_INFO,
C.host_info_t(unsafe.Pointer(&vmstat)),
&count)
if status != C.KERN_SUCCESS {
return nil, fmt.Errorf("host_statistics error=%d", status)
}
pageSize := uint64(unix.Getpagesize())
total, err := getHwMemsize()
if err != nil {
return nil, err
}
totalCount := C.natural_t(total / pageSize)
availableCount := vmstat.inactive_count + vmstat.free_count
usedPercent := 100 * float64(totalCount-availableCount) / float64(totalCount)
usedCount := totalCount - availableCount
return &VirtualMemoryStat{
Total: total,
Available: pageSize * uint64(availableCount),
Used: pageSize * uint64(usedCount),
UsedPercent: usedPercent,
Free: pageSize * uint64(vmstat.free_count),
Active: pageSize * uint64(vmstat.active_count),
Inactive: pageSize * uint64(vmstat.inactive_count),
Wired: pageSize * uint64(vmstat.wire_count),
}, nil
}

View File

@@ -0,0 +1,94 @@
// +build darwin
// +build !cgo
package mem
import (
"context"
"os/exec"
"strconv"
"strings"
"golang.org/x/sys/unix"
)
// Runs vm_stat and returns Free and inactive pages
func getVMStat(vms *VirtualMemoryStat) error {
vm_stat, err := exec.LookPath("vm_stat")
if err != nil {
return err
}
out, err := invoke.Command(vm_stat)
if err != nil {
return err
}
return parseVMStat(string(out), vms)
}
func parseVMStat(out string, vms *VirtualMemoryStat) error {
var err error
lines := strings.Split(out, "\n")
pagesize := uint64(unix.Getpagesize())
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) < 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.Trim(fields[1], " .")
switch key {
case "Pages free":
free, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Free = free * pagesize
case "Pages inactive":
inactive, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Inactive = inactive * pagesize
case "Pages active":
active, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Active = active * pagesize
case "Pages wired down":
wired, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
vms.Wired = wired * pagesize
}
}
return err
}
// VirtualMemory returns VirtualmemoryStat.
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
ret := &VirtualMemoryStat{}
total, err := getHwMemsize()
if err != nil {
return nil, err
}
err = getVMStat(ret)
if err != nil {
return nil, err
}
ret.Available = ret.Free + ret.Inactive
ret.Total = total
ret.Used = ret.Total - ret.Available
ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total)
return ret, nil
}

25
vendor/github.com/shirou/gopsutil/mem/mem_fallback.go generated vendored Normal file
View File

@@ -0,0 +1,25 @@
// +build !darwin,!linux,!freebsd,!openbsd,!solaris,!windows
package mem
import (
"context"
"github.com/shirou/gopsutil/internal/common"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
return nil, common.ErrNotImplementedError
}
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
return nil, common.ErrNotImplementedError
}

142
vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go generated vendored Normal file
View File

@@ -0,0 +1,142 @@
// +build freebsd
package mem
import (
"context"
"errors"
"unsafe"
"golang.org/x/sys/unix"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
pageSize, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
if err != nil {
return nil, err
}
physmem, err := unix.SysctlUint64("hw.physmem")
if err != nil {
return nil, err
}
free, err := unix.SysctlUint32("vm.stats.vm.v_free_count")
if err != nil {
return nil, err
}
active, err := unix.SysctlUint32("vm.stats.vm.v_active_count")
if err != nil {
return nil, err
}
inactive, err := unix.SysctlUint32("vm.stats.vm.v_inactive_count")
if err != nil {
return nil, err
}
buffers, err := unix.SysctlUint64("vfs.bufspace")
if err != nil {
return nil, err
}
wired, err := unix.SysctlUint32("vm.stats.vm.v_wire_count")
if err != nil {
return nil, err
}
var cached, laundry uint32
osreldate, _ := unix.SysctlUint32("kern.osreldate")
if osreldate < 1102000 {
cached, err = unix.SysctlUint32("vm.stats.vm.v_cache_count")
if err != nil {
return nil, err
}
} else {
laundry, err = unix.SysctlUint32("vm.stats.vm.v_laundry_count")
if err != nil {
return nil, err
}
}
p := uint64(pageSize)
ret := &VirtualMemoryStat{
Total: uint64(physmem),
Free: uint64(free) * p,
Active: uint64(active) * p,
Inactive: uint64(inactive) * p,
Cached: uint64(cached) * p,
Buffers: uint64(buffers),
Wired: uint64(wired) * p,
Laundry: uint64(laundry) * p,
}
ret.Available = ret.Inactive + ret.Cached + ret.Free + ret.Laundry
ret.Used = ret.Total - ret.Available
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
return ret, nil
}
// Return swapinfo
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
// Constants from vm/vm_param.h
// nolint: golint
const (
XSWDEV_VERSION = 1
)
// Types from vm/vm_param.h
type xswdev struct {
Version uint32 // Version is the version
Dev uint32 // Dev is the device identifier
Flags int32 // Flags is the swap flags applied to the device
NBlks int32 // NBlks is the total number of blocks
Used int32 // Used is the number of blocks used
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
// FreeBSD can have multiple swap devices so we total them up
i, err := unix.SysctlUint32("vm.nswapdev")
if err != nil {
return nil, err
}
if i == 0 {
return nil, errors.New("no swap devices found")
}
c := int(i)
i, err = unix.SysctlUint32("vm.stats.vm.v_page_size")
if err != nil {
return nil, err
}
pageSize := uint64(i)
var buf []byte
s := &SwapMemoryStat{}
for n := 0; n < c; n++ {
buf, err = unix.SysctlRaw("vm.swap_info", n)
if err != nil {
return nil, err
}
xsw := (*xswdev)(unsafe.Pointer(&buf[0]))
if xsw.Version != XSWDEV_VERSION {
return nil, errors.New("xswdev version mismatch")
}
s.Total += uint64(xsw.NBlks)
s.Used += uint64(xsw.Used)
}
if s.Total != 0 {
s.UsedPercent = float64(s.Used) / float64(s.Total) * 100
}
s.Total *= pageSize
s.Used *= pageSize
s.Free = s.Total - s.Used
return s, nil
}

158
vendor/github.com/shirou/gopsutil/mem/mem_linux.go generated vendored Normal file
View File

@@ -0,0 +1,158 @@
// +build linux
package mem
import (
"context"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/unix"
)
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
filename := common.HostProc("meminfo")
lines, _ := common.ReadLines(filename)
// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
memavail := false
ret := &VirtualMemoryStat{}
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) != 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.TrimSpace(fields[1])
value = strings.Replace(value, " kB", "", -1)
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, err
}
switch key {
case "MemTotal":
ret.Total = t * 1024
case "MemFree":
ret.Free = t * 1024
case "MemAvailable":
memavail = true
ret.Available = t * 1024
case "Buffers":
ret.Buffers = t * 1024
case "Cached":
ret.Cached = t * 1024
case "Active":
ret.Active = t * 1024
case "Inactive":
ret.Inactive = t * 1024
case "Writeback":
ret.Writeback = t * 1024
case "WritebackTmp":
ret.WritebackTmp = t * 1024
case "Dirty":
ret.Dirty = t * 1024
case "Shmem":
ret.Shared = t * 1024
case "Slab":
ret.Slab = t * 1024
case "SReclaimable":
ret.SReclaimable = t * 1024
case "PageTables":
ret.PageTables = t * 1024
case "SwapCached":
ret.SwapCached = t * 1024
case "CommitLimit":
ret.CommitLimit = t * 1024
case "Committed_AS":
ret.CommittedAS = t * 1024
case "HighTotal":
ret.HighTotal = t * 1024
case "HighFree":
ret.HighFree = t * 1024
case "LowTotal":
ret.LowTotal = t * 1024
case "LowFree":
ret.LowFree = t * 1024
case "SwapTotal":
ret.SwapTotal = t * 1024
case "SwapFree":
ret.SwapFree = t * 1024
case "Mapped":
ret.Mapped = t * 1024
case "VmallocTotal":
ret.VMallocTotal = t * 1024
case "VmallocUsed":
ret.VMallocUsed = t * 1024
case "VmallocChunk":
ret.VMallocChunk = t * 1024
case "HugePages_Total":
ret.HugePagesTotal = t
case "HugePages_Free":
ret.HugePagesFree = t
case "Hugepagesize":
ret.HugePageSize = t * 1024
}
}
ret.Cached += ret.SReclaimable
if !memavail {
ret.Available = ret.Free + ret.Buffers + ret.Cached
}
ret.Used = ret.Total - ret.Free - ret.Buffers - ret.Cached
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
return ret, nil
}
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
sysinfo := &unix.Sysinfo_t{}
if err := unix.Sysinfo(sysinfo); err != nil {
return nil, err
}
ret := &SwapMemoryStat{
Total: uint64(sysinfo.Totalswap) * uint64(sysinfo.Unit),
Free: uint64(sysinfo.Freeswap) * uint64(sysinfo.Unit),
}
ret.Used = ret.Total - ret.Free
//check Infinity
if ret.Total != 0 {
ret.UsedPercent = float64(ret.Total-ret.Free) / float64(ret.Total) * 100.0
} else {
ret.UsedPercent = 0
}
filename := common.HostProc("vmstat")
lines, _ := common.ReadLines(filename)
for _, l := range lines {
fields := strings.Fields(l)
if len(fields) < 2 {
continue
}
switch fields[0] {
case "pswpin":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
}
ret.Sin = value * 4 * 1024
case "pswpout":
value, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
continue
}
ret.Sout = value * 4 * 1024
}
}
return ret, nil
}

124
vendor/github.com/shirou/gopsutil/mem/mem_openbsd.go generated vendored Normal file
View File

@@ -0,0 +1,124 @@
// +build openbsd
package mem
import (
"bytes"
"context"
"encoding/binary"
"errors"
"fmt"
"os/exec"
"github.com/shirou/gopsutil/internal/common"
)
func GetPageSize() (uint64, error) {
return GetPageSizeWithContext(context.Background())
}
func GetPageSizeWithContext(ctx context.Context) (uint64, error) {
mib := []int32{CTLVm, VmUvmexp}
buf, length, err := common.CallSyscall(mib)
if err != nil {
return 0, err
}
if length < sizeOfUvmexp {
return 0, fmt.Errorf("short syscall ret %d bytes", length)
}
var uvmexp Uvmexp
br := bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &uvmexp)
if err != nil {
return 0, err
}
return uint64(uvmexp.Pagesize), nil
}
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
mib := []int32{CTLVm, VmUvmexp}
buf, length, err := common.CallSyscall(mib)
if err != nil {
return nil, err
}
if length < sizeOfUvmexp {
return nil, fmt.Errorf("short syscall ret %d bytes", length)
}
var uvmexp Uvmexp
br := bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &uvmexp)
if err != nil {
return nil, err
}
p := uint64(uvmexp.Pagesize)
ret := &VirtualMemoryStat{
Total: uint64(uvmexp.Npages) * p,
Free: uint64(uvmexp.Free) * p,
Active: uint64(uvmexp.Active) * p,
Inactive: uint64(uvmexp.Inactive) * p,
Cached: 0, // not available
Wired: uint64(uvmexp.Wired) * p,
}
ret.Available = ret.Inactive + ret.Cached + ret.Free
ret.Used = ret.Total - ret.Available
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
mib = []int32{CTLVfs, VfsGeneric, VfsBcacheStat}
buf, length, err = common.CallSyscall(mib)
if err != nil {
return nil, err
}
if length < sizeOfBcachestats {
return nil, fmt.Errorf("short syscall ret %d bytes", length)
}
var bcs Bcachestats
br = bytes.NewReader(buf)
err = common.Read(br, binary.LittleEndian, &bcs)
if err != nil {
return nil, err
}
ret.Buffers = uint64(bcs.Numbufpages) * p
return ret, nil
}
// Return swapctl summary info
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
swapctl, err := exec.LookPath("swapctl")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, swapctl, "-sk")
if err != nil {
return &SwapMemoryStat{}, nil
}
line := string(out)
var total, used, free uint64
_, err = fmt.Sscanf(line,
"total: %d 1K-blocks allocated, %d used, %d available",
&total, &used, &free)
if err != nil {
return nil, errors.New("failed to parse swapctl output")
}
percent := float64(used) / float64(total) * 100
return &SwapMemoryStat{
Total: total * 1024,
Used: used * 1024,
Free: free * 1024,
UsedPercent: percent,
}, nil
}

View File

@@ -0,0 +1,122 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_openbsd.go
package mem
const (
CTLVm = 2
CTLVfs = 10
VmUvmexp = 4
VfsGeneric = 0
VfsBcacheStat = 3
)
const (
sizeOfUvmexp = 0x154
sizeOfBcachestats = 0x78
)
type Uvmexp struct {
Pagesize int32
Pagemask int32
Pageshift int32
Npages int32
Free int32
Active int32
Inactive int32
Paging int32
Wired int32
Zeropages int32
Reserve_pagedaemon int32
Reserve_kernel int32
Anonpages int32
Vnodepages int32
Vtextpages int32
Freemin int32
Freetarg int32
Inactarg int32
Wiredmax int32
Anonmin int32
Vtextmin int32
Vnodemin int32
Anonminpct int32
Vtextminpct int32
Vnodeminpct int32
Nswapdev int32
Swpages int32
Swpginuse int32
Swpgonly int32
Nswget int32
Nanon int32
Nanonneeded int32
Nfreeanon int32
Faults int32
Traps int32
Intrs int32
Swtch int32
Softs int32
Syscalls int32
Pageins int32
Obsolete_swapins int32
Obsolete_swapouts int32
Pgswapin int32
Pgswapout int32
Forks int32
Forks_ppwait int32
Forks_sharevm int32
Pga_zerohit int32
Pga_zeromiss int32
Zeroaborts int32
Fltnoram int32
Fltnoanon int32
Fltpgwait int32
Fltpgrele int32
Fltrelck int32
Fltrelckok int32
Fltanget int32
Fltanretry int32
Fltamcopy int32
Fltnamap int32
Fltnomap int32
Fltlget int32
Fltget int32
Flt_anon int32
Flt_acow int32
Flt_obj int32
Flt_prcopy int32
Flt_przero int32
Pdwoke int32
Pdrevs int32
Pdswout int32
Pdfreed int32
Pdscans int32
Pdanscan int32
Pdobscan int32
Pdreact int32
Pdbusy int32
Pdpageouts int32
Pdpending int32
Pddeact int32
Pdreanon int32
Pdrevnode int32
Pdrevtext int32
Fpswtch int32
Kmapent int32
}
type Bcachestats struct {
Numbufs int64
Numbufpages int64
Numdirtypages int64
Numcleanpages int64
Pendingwrites int64
Pendingreads int64
Numwrites int64
Numreads int64
Cachehits int64
Busymapped int64
Dmapages int64
Highpages int64
Delwribufs int64
Kvaslots int64
Avail int64
}

121
vendor/github.com/shirou/gopsutil/mem/mem_solaris.go generated vendored Normal file
View File

@@ -0,0 +1,121 @@
package mem
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
// VirtualMemory for Solaris is a minimal implementation which only returns
// what Nomad needs. It does take into account global vs zone, however.
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
result := &VirtualMemoryStat{}
zoneName, err := zoneName()
if err != nil {
return nil, err
}
if zoneName == "global" {
cap, err := globalZoneMemoryCapacity()
if err != nil {
return nil, err
}
result.Total = cap
} else {
cap, err := nonGlobalZoneMemoryCapacity()
if err != nil {
return nil, err
}
result.Total = cap
}
return result, nil
}
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
return nil, common.ErrNotImplementedError
}
func zoneName() (string, error) {
zonename, err := exec.LookPath("/usr/bin/zonename")
if err != nil {
return "", err
}
ctx := context.Background()
out, err := invoke.CommandWithContext(ctx, zonename)
if err != nil {
return "", err
}
return strings.TrimSpace(string(out)), nil
}
var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`)
func globalZoneMemoryCapacity() (uint64, error) {
prtconf, err := exec.LookPath("/usr/sbin/prtconf")
if err != nil {
return 0, err
}
ctx := context.Background()
out, err := invoke.CommandWithContext(ctx, prtconf)
if err != nil {
return 0, err
}
match := globalZoneMemoryCapacityMatch.FindAllStringSubmatch(string(out), -1)
if len(match) != 1 {
return 0, errors.New("memory size not contained in output of /usr/sbin/prtconf")
}
totalMB, err := strconv.ParseUint(match[0][1], 10, 64)
if err != nil {
return 0, err
}
return totalMB * 1024 * 1024, nil
}
var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`)
func nonGlobalZoneMemoryCapacity() (uint64, error) {
kstat, err := exec.LookPath("/usr/bin/kstat")
if err != nil {
return 0, err
}
ctx := context.Background()
out, err := invoke.CommandWithContext(ctx, kstat, "-p", "-c", "zone_memory_cap", "memory_cap:*:*:physcap")
if err != nil {
return 0, err
}
kstats := kstatMatch.FindAllStringSubmatch(string(out), -1)
if len(kstats) != 1 {
return 0, fmt.Errorf("expected 1 kstat, found %d", len(kstats))
}
memSizeBytes, err := strconv.ParseUint(kstats[0][2], 10, 64)
if err != nil {
return 0, err
}
return memSizeBytes, nil
}

97
vendor/github.com/shirou/gopsutil/mem/mem_windows.go generated vendored Normal file
View File

@@ -0,0 +1,97 @@
// +build windows
package mem
import (
"context"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/windows"
)
var (
procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx")
procGetPerformanceInfo = common.ModPsapi.NewProc("GetPerformanceInfo")
)
type memoryStatusEx struct {
cbSize uint32
dwMemoryLoad uint32
ullTotalPhys uint64 // in bytes
ullAvailPhys uint64
ullTotalPageFile uint64
ullAvailPageFile uint64
ullTotalVirtual uint64
ullAvailVirtual uint64
ullAvailExtendedVirtual uint64
}
func VirtualMemory() (*VirtualMemoryStat, error) {
return VirtualMemoryWithContext(context.Background())
}
func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
var memInfo memoryStatusEx
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
if mem == 0 {
return nil, windows.GetLastError()
}
ret := &VirtualMemoryStat{
Total: memInfo.ullTotalPhys,
Available: memInfo.ullAvailPhys,
UsedPercent: float64(memInfo.dwMemoryLoad),
}
ret.Used = ret.Total - ret.Available
return ret, nil
}
type performanceInformation struct {
cb uint32
commitTotal uint64
commitLimit uint64
commitPeak uint64
physicalTotal uint64
physicalAvailable uint64
systemCache uint64
kernelTotal uint64
kernelPaged uint64
kernelNonpaged uint64
pageSize uint64
handleCount uint32
processCount uint32
threadCount uint32
}
func SwapMemory() (*SwapMemoryStat, error) {
return SwapMemoryWithContext(context.Background())
}
func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) {
var perfInfo performanceInformation
perfInfo.cb = uint32(unsafe.Sizeof(perfInfo))
mem, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&perfInfo)), uintptr(perfInfo.cb))
if mem == 0 {
return nil, windows.GetLastError()
}
tot := perfInfo.commitLimit * perfInfo.pageSize
used := perfInfo.commitTotal * perfInfo.pageSize
free := tot - used
var usedPercent float64
if tot == 0 {
usedPercent = 0
} else {
usedPercent = float64(used) / float64(tot)
}
ret := &SwapMemoryStat{
Total: tot,
Used: used,
Free: free,
UsedPercent: usedPercent,
}
return ret, nil
}

34
vendor/github.com/shirou/gopsutil/mem/types_openbsd.go generated vendored Normal file
View File

@@ -0,0 +1,34 @@
// +build ignore
/*
Input to cgo -godefs.
*/
package mem
/*
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/sysctl.h>
#include <uvm/uvmexp.h>
*/
import "C"
// Machine characteristics; for internal use.
const (
CTLVm = 2
CTLVfs = 10
VmUvmexp = 4 // get uvmexp
VfsGeneric = 0
VfsBcacheStat = 3
)
const (
sizeOfUvmexp = C.sizeof_struct_uvmexp
sizeOfBcachestats = C.sizeof_struct_bcachestats
)
type Uvmexp C.struct_uvmexp
type Bcachestats C.struct_bcachestats

259
vendor/github.com/shirou/gopsutil/net/net.go generated vendored Normal file
View File

@@ -0,0 +1,259 @@
package net
import (
"context"
"encoding/json"
"fmt"
"net"
"strconv"
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
)
var invoke common.Invoker = common.Invoke{}
type IOCountersStat struct {
Name string `json:"name"` // interface name
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
PacketsSent uint64 `json:"packetsSent"` // number of packets sent
PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
Errin uint64 `json:"errin"` // total number of errors while receiving
Errout uint64 `json:"errout"` // total number of errors while sending
Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
}
// Addr is implemented compatibility to psutil
type Addr struct {
IP string `json:"ip"`
Port uint32 `json:"port"`
}
type ConnectionStat struct {
Fd uint32 `json:"fd"`
Family uint32 `json:"family"`
Type uint32 `json:"type"`
Laddr Addr `json:"localaddr"`
Raddr Addr `json:"remoteaddr"`
Status string `json:"status"`
Uids []int32 `json:"uids"`
Pid int32 `json:"pid"`
}
// System wide stats about different network protocols
type ProtoCountersStat struct {
Protocol string `json:"protocol"`
Stats map[string]int64 `json:"stats"`
}
// NetInterfaceAddr is designed for represent interface addresses
type InterfaceAddr struct {
Addr string `json:"addr"`
}
type InterfaceStat struct {
MTU int `json:"mtu"` // maximum transmission unit
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
HardwareAddr string `json:"hardwareaddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
Addrs []InterfaceAddr `json:"addrs"`
}
type FilterStat struct {
ConnTrackCount int64 `json:"conntrackCount"`
ConnTrackMax int64 `json:"conntrackMax"`
}
var constMap = map[string]int{
"unix": syscall.AF_UNIX,
"TCP": syscall.SOCK_STREAM,
"UDP": syscall.SOCK_DGRAM,
"IPv4": syscall.AF_INET,
"IPv6": syscall.AF_INET6,
}
func (n IOCountersStat) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func (n ConnectionStat) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func (n ProtoCountersStat) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func (a Addr) String() string {
s, _ := json.Marshal(a)
return string(s)
}
func (n InterfaceStat) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func (n InterfaceAddr) String() string {
s, _ := json.Marshal(n)
return string(s)
}
func Interfaces() ([]InterfaceStat, error) {
return InterfacesWithContext(context.Background())
}
func InterfacesWithContext(ctx context.Context) ([]InterfaceStat, error) {
is, err := net.Interfaces()
if err != nil {
return nil, err
}
ret := make([]InterfaceStat, 0, len(is))
for _, ifi := range is {
var flags []string
if ifi.Flags&net.FlagUp != 0 {
flags = append(flags, "up")
}
if ifi.Flags&net.FlagBroadcast != 0 {
flags = append(flags, "broadcast")
}
if ifi.Flags&net.FlagLoopback != 0 {
flags = append(flags, "loopback")
}
if ifi.Flags&net.FlagPointToPoint != 0 {
flags = append(flags, "pointtopoint")
}
if ifi.Flags&net.FlagMulticast != 0 {
flags = append(flags, "multicast")
}
r := InterfaceStat{
Name: ifi.Name,
MTU: ifi.MTU,
HardwareAddr: ifi.HardwareAddr.String(),
Flags: flags,
}
addrs, err := ifi.Addrs()
if err == nil {
r.Addrs = make([]InterfaceAddr, 0, len(addrs))
for _, addr := range addrs {
r.Addrs = append(r.Addrs, InterfaceAddr{
Addr: addr.String(),
})
}
}
ret = append(ret, r)
}
return ret, nil
}
func getIOCountersAll(n []IOCountersStat) ([]IOCountersStat, error) {
r := IOCountersStat{
Name: "all",
}
for _, nic := range n {
r.BytesRecv += nic.BytesRecv
r.PacketsRecv += nic.PacketsRecv
r.Errin += nic.Errin
r.Dropin += nic.Dropin
r.BytesSent += nic.BytesSent
r.PacketsSent += nic.PacketsSent
r.Errout += nic.Errout
r.Dropout += nic.Dropout
}
return []IOCountersStat{r}, nil
}
func parseNetLine(line string) (ConnectionStat, error) {
f := strings.Fields(line)
if len(f) < 8 {
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
}
if len(f) == 8 {
f = append(f, f[7])
f[7] = "unix"
}
pid, err := strconv.Atoi(f[1])
if err != nil {
return ConnectionStat{}, err
}
fd, err := strconv.Atoi(strings.Trim(f[3], "u"))
if err != nil {
return ConnectionStat{}, fmt.Errorf("unknown fd, %s", f[3])
}
netFamily, ok := constMap[f[4]]
if !ok {
return ConnectionStat{}, fmt.Errorf("unknown family, %s", f[4])
}
netType, ok := constMap[f[7]]
if !ok {
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[7])
}
var laddr, raddr Addr
if f[7] == "unix" {
laddr.IP = f[8]
} else {
laddr, raddr, err = parseNetAddr(f[8])
if err != nil {
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s", f[8])
}
}
n := ConnectionStat{
Fd: uint32(fd),
Family: uint32(netFamily),
Type: uint32(netType),
Laddr: laddr,
Raddr: raddr,
Pid: int32(pid),
}
if len(f) == 10 {
n.Status = strings.Trim(f[9], "()")
}
return n, nil
}
func parseNetAddr(line string) (laddr Addr, raddr Addr, err error) {
parse := func(l string) (Addr, error) {
host, port, err := net.SplitHostPort(l)
if err != nil {
return Addr{}, fmt.Errorf("wrong addr, %s", l)
}
lport, err := strconv.Atoi(port)
if err != nil {
return Addr{}, err
}
return Addr{IP: host, Port: uint32(lport)}, nil
}
addrs := strings.Split(line, "->")
if len(addrs) == 0 {
return laddr, raddr, fmt.Errorf("wrong netaddr, %s", line)
}
laddr, err = parse(addrs[0])
if len(addrs) == 2 { // remote addr exists
raddr, err = parse(addrs[1])
if err != nil {
return laddr, raddr, err
}
}
return laddr, raddr, err
}

284
vendor/github.com/shirou/gopsutil/net/net_darwin.go generated vendored Normal file
View File

@@ -0,0 +1,284 @@
// +build darwin
package net
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
)
var (
errNetstatHeader = errors.New("Can't parse header of netstat output")
netstatLinkRegexp = regexp.MustCompile(`^<Link#(\d+)>$`)
)
const endOfLine = "\n"
func parseNetstatLine(line string) (stat *IOCountersStat, linkID *uint, err error) {
var (
numericValue uint64
columns = strings.Fields(line)
)
if columns[0] == "Name" {
err = errNetstatHeader
return
}
// try to extract the numeric value from <Link#123>
if subMatch := netstatLinkRegexp.FindStringSubmatch(columns[2]); len(subMatch) == 2 {
numericValue, err = strconv.ParseUint(subMatch[1], 10, 64)
if err != nil {
return
}
linkIDUint := uint(numericValue)
linkID = &linkIDUint
}
base := 1
numberColumns := len(columns)
// sometimes Address is ommitted
if numberColumns < 12 {
base = 0
}
if numberColumns < 11 || numberColumns > 13 {
err = fmt.Errorf("Line %q do have an invalid number of columns %d", line, numberColumns)
return
}
parsed := make([]uint64, 0, 7)
vv := []string{
columns[base+3], // Ipkts == PacketsRecv
columns[base+4], // Ierrs == Errin
columns[base+5], // Ibytes == BytesRecv
columns[base+6], // Opkts == PacketsSent
columns[base+7], // Oerrs == Errout
columns[base+8], // Obytes == BytesSent
}
if len(columns) == 12 {
vv = append(vv, columns[base+10])
}
for _, target := range vv {
if target == "-" {
parsed = append(parsed, 0)
continue
}
if numericValue, err = strconv.ParseUint(target, 10, 64); err != nil {
return
}
parsed = append(parsed, numericValue)
}
stat = &IOCountersStat{
Name: strings.Trim(columns[0], "*"), // remove the * that sometimes is on right on interface
PacketsRecv: parsed[0],
Errin: parsed[1],
BytesRecv: parsed[2],
PacketsSent: parsed[3],
Errout: parsed[4],
BytesSent: parsed[5],
}
if len(parsed) == 7 {
stat.Dropout = parsed[6]
}
return
}
type netstatInterface struct {
linkID *uint
stat *IOCountersStat
}
func parseNetstatOutput(output string) ([]netstatInterface, error) {
var (
err error
lines = strings.Split(strings.Trim(output, endOfLine), endOfLine)
)
// number of interfaces is number of lines less one for the header
numberInterfaces := len(lines) - 1
interfaces := make([]netstatInterface, numberInterfaces)
// no output beside header
if numberInterfaces == 0 {
return interfaces, nil
}
for index := 0; index < numberInterfaces; index++ {
nsIface := netstatInterface{}
if nsIface.stat, nsIface.linkID, err = parseNetstatLine(lines[index+1]); err != nil {
return nil, err
}
interfaces[index] = nsIface
}
return interfaces, nil
}
// map that hold the name of a network interface and the number of usage
type mapInterfaceNameUsage map[string]uint
func newMapInterfaceNameUsage(ifaces []netstatInterface) mapInterfaceNameUsage {
output := make(mapInterfaceNameUsage)
for index := range ifaces {
if ifaces[index].linkID != nil {
ifaceName := ifaces[index].stat.Name
usage, ok := output[ifaceName]
if ok {
output[ifaceName] = usage + 1
} else {
output[ifaceName] = 1
}
}
}
return output
}
func (min mapInterfaceNameUsage) isTruncated() bool {
for _, usage := range min {
if usage > 1 {
return true
}
}
return false
}
func (min mapInterfaceNameUsage) notTruncated() []string {
output := make([]string, 0)
for ifaceName, usage := range min {
if usage == 1 {
output = append(output, ifaceName)
}
}
return output
}
// example of `netstat -ibdnW` output on yosemite
// Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll Drop
// lo0 16384 <Link#1> 869107 0 169411755 869107 0 169411755 0 0
// lo0 16384 ::1/128 ::1 869107 - 169411755 869107 - 169411755 - -
// lo0 16384 127 127.0.0.1 869107 - 169411755 869107 - 169411755 - -
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
var (
ret []IOCountersStat
retIndex int
)
netstat, err := exec.LookPath("/usr/sbin/netstat")
if err != nil {
return nil, err
}
// try to get all interface metrics, and hope there won't be any truncated
out, err := invoke.CommandWithContext(ctx, netstat, "-ibdnW")
if err != nil {
return nil, err
}
nsInterfaces, err := parseNetstatOutput(string(out))
if err != nil {
return nil, err
}
ifaceUsage := newMapInterfaceNameUsage(nsInterfaces)
notTruncated := ifaceUsage.notTruncated()
ret = make([]IOCountersStat, len(notTruncated))
if !ifaceUsage.isTruncated() {
// no truncated interface name, return stats of all interface with <Link#...>
for index := range nsInterfaces {
if nsInterfaces[index].linkID != nil {
ret[retIndex] = *nsInterfaces[index].stat
retIndex++
}
}
} else {
// duplicated interface, list all interfaces
ifconfig, err := exec.LookPath("/sbin/ifconfig")
if err != nil {
return nil, err
}
if out, err = invoke.CommandWithContext(ctx, ifconfig, "-l"); err != nil {
return nil, err
}
interfaceNames := strings.Fields(strings.TrimRight(string(out), endOfLine))
// for each of the interface name, run netstat if we don't have any stats yet
for _, interfaceName := range interfaceNames {
truncated := true
for index := range nsInterfaces {
if nsInterfaces[index].linkID != nil && nsInterfaces[index].stat.Name == interfaceName {
// handle the non truncated name to avoid execute netstat for them again
ret[retIndex] = *nsInterfaces[index].stat
retIndex++
truncated = false
break
}
}
if truncated {
// run netstat with -I$ifacename
if out, err = invoke.CommandWithContext(ctx, netstat, "-ibdnWI"+interfaceName); err != nil {
return nil, err
}
parsedIfaces, err := parseNetstatOutput(string(out))
if err != nil {
return nil, err
}
if len(parsedIfaces) == 0 {
// interface had been removed since `ifconfig -l` had been executed
continue
}
for index := range parsedIfaces {
if parsedIfaces[index].linkID != nil {
ret = append(ret, *parsedIfaces[index].stat)
break
}
}
}
}
}
if pernic == false {
return getIOCountersAll(ret)
}
return ret, nil
}
// NetIOCountersByFile is an method which is added just a compatibility for linux.
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return IOCountersByFileWithContext(context.Background(), pernic, filename)
}
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
return IOCounters(pernic)
}
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for darwin")
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for Darwin
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for darwin")
}

49
vendor/github.com/shirou/gopsutil/net/net_fallback.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
// +build !darwin,!linux,!freebsd,!openbsd,!windows
package net
import (
"context"
"github.com/shirou/gopsutil/internal/common"
)
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
return []IOCountersStat{}, common.ErrNotImplementedError
}
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return []FilterStat{}, common.ErrNotImplementedError
}
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return []ProtoCountersStat{}, common.ErrNotImplementedError
}
func Connections(kind string) ([]ConnectionStat, error) {
return ConnectionsWithContext(context.Background(), kind)
}
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
return []ConnectionStat{}, common.ErrNotImplementedError
}
func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
return ConnectionsMaxWithContext(context.Background(), kind, max)
}
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
return []ConnectionStat{}, common.ErrNotImplementedError
}

125
vendor/github.com/shirou/gopsutil/net/net_freebsd.go generated vendored Normal file
View File

@@ -0,0 +1,125 @@
// +build freebsd
package net
import (
"context"
"errors"
"os/exec"
"strconv"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
netstat, err := exec.LookPath("/usr/bin/netstat")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, netstat, "-ibdnW")
if err != nil {
return nil, err
}
lines := strings.Split(string(out), "\n")
ret := make([]IOCountersStat, 0, len(lines)-1)
exists := make([]string, 0, len(ret))
for _, line := range lines {
values := strings.Fields(line)
if len(values) < 1 || values[0] == "Name" {
continue
}
if common.StringsHas(exists, values[0]) {
// skip if already get
continue
}
exists = append(exists, values[0])
if len(values) < 12 {
continue
}
base := 1
// sometimes Address is ommitted
if len(values) < 13 {
base = 0
}
parsed := make([]uint64, 0, 8)
vv := []string{
values[base+3], // PacketsRecv
values[base+4], // Errin
values[base+5], // Dropin
values[base+6], // BytesRecvn
values[base+7], // PacketSent
values[base+8], // Errout
values[base+9], // BytesSent
values[base+11], // Dropout
}
for _, target := range vv {
if target == "-" {
parsed = append(parsed, 0)
continue
}
t, err := strconv.ParseUint(target, 10, 64)
if err != nil {
return nil, err
}
parsed = append(parsed, t)
}
n := IOCountersStat{
Name: values[0],
PacketsRecv: parsed[0],
Errin: parsed[1],
Dropin: parsed[2],
BytesRecv: parsed[3],
PacketsSent: parsed[4],
Errout: parsed[5],
BytesSent: parsed[6],
Dropout: parsed[7],
}
ret = append(ret, n)
}
if pernic == false {
return getIOCountersAll(ret)
}
return ret, nil
}
// NetIOCountersByFile is an method which is added just a compatibility for linux.
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return IOCountersByFileWithContext(context.Background(), pernic, filename)
}
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
return IOCounters(pernic)
}
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for freebsd")
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for FreeBSD
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for freebsd")
}

793
vendor/github.com/shirou/gopsutil/net/net_linux.go generated vendored Normal file
View File

@@ -0,0 +1,793 @@
// +build linux
package net
import (
"bytes"
"context"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"net"
"os"
"strconv"
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
)
// NetIOCounters returnes network I/O statistics for every network
// interface installed on the system. If pernic argument is false,
// return only sum of all information (which name is 'all'). If true,
// every network interface installed on the system is returned
// separately.
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
filename := common.HostProc("net/dev")
return IOCountersByFile(pernic, filename)
}
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return IOCountersByFileWithContext(context.Background(), pernic, filename)
}
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
lines, err := common.ReadLines(filename)
if err != nil {
return nil, err
}
parts := make([]string, 2)
statlen := len(lines) - 1
ret := make([]IOCountersStat, 0, statlen)
for _, line := range lines[2:] {
separatorPos := strings.LastIndex(line, ":")
if separatorPos == -1 {
continue
}
parts[0] = line[0:separatorPos]
parts[1] = line[separatorPos+1:]
interfaceName := strings.TrimSpace(parts[0])
if interfaceName == "" {
continue
}
fields := strings.Fields(strings.TrimSpace(parts[1]))
bytesRecv, err := strconv.ParseUint(fields[0], 10, 64)
if err != nil {
return ret, err
}
packetsRecv, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
return ret, err
}
errIn, err := strconv.ParseUint(fields[2], 10, 64)
if err != nil {
return ret, err
}
dropIn, err := strconv.ParseUint(fields[3], 10, 64)
if err != nil {
return ret, err
}
fifoIn, err := strconv.ParseUint(fields[4], 10, 64)
if err != nil {
return ret, err
}
bytesSent, err := strconv.ParseUint(fields[8], 10, 64)
if err != nil {
return ret, err
}
packetsSent, err := strconv.ParseUint(fields[9], 10, 64)
if err != nil {
return ret, err
}
errOut, err := strconv.ParseUint(fields[10], 10, 64)
if err != nil {
return ret, err
}
dropOut, err := strconv.ParseUint(fields[11], 10, 64)
if err != nil {
return ret, err
}
fifoOut, err := strconv.ParseUint(fields[12], 10, 64)
if err != nil {
return ret, err
}
nic := IOCountersStat{
Name: interfaceName,
BytesRecv: bytesRecv,
PacketsRecv: packetsRecv,
Errin: errIn,
Dropin: dropIn,
Fifoin: fifoIn,
BytesSent: bytesSent,
PacketsSent: packetsSent,
Errout: errOut,
Dropout: dropOut,
Fifoout: fifoOut,
}
ret = append(ret, nic)
}
if pernic == false {
return getIOCountersAll(ret)
}
return ret, nil
}
var netProtocols = []string{
"ip",
"icmp",
"icmpmsg",
"tcp",
"udp",
"udplite",
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Available protocols:
// ip,icmp,icmpmsg,tcp,udp,udplite
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
if len(protocols) == 0 {
protocols = netProtocols
}
stats := make([]ProtoCountersStat, 0, len(protocols))
protos := make(map[string]bool, len(protocols))
for _, p := range protocols {
protos[p] = true
}
filename := common.HostProc("net/snmp")
lines, err := common.ReadLines(filename)
if err != nil {
return nil, err
}
linecount := len(lines)
for i := 0; i < linecount; i++ {
line := lines[i]
r := strings.IndexRune(line, ':')
if r == -1 {
return nil, errors.New(filename + " is not fomatted correctly, expected ':'.")
}
proto := strings.ToLower(line[:r])
if !protos[proto] {
// skip protocol and data line
i++
continue
}
// Read header line
statNames := strings.Split(line[r+2:], " ")
// Read data line
i++
statValues := strings.Split(lines[i][r+2:], " ")
if len(statNames) != len(statValues) {
return nil, errors.New(filename + " is not fomatted correctly, expected same number of columns.")
}
stat := ProtoCountersStat{
Protocol: proto,
Stats: make(map[string]int64, len(statNames)),
}
for j := range statNames {
value, err := strconv.ParseInt(statValues[j], 10, 64)
if err != nil {
return nil, err
}
stat.Stats[statNames[j]] = value
}
stats = append(stats, stat)
}
return stats, nil
}
// NetFilterCounters returns iptables conntrack statistics
// the currently in use conntrack count and the max.
// If the file does not exist or is invalid it will return nil.
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
countfile := common.HostProc("sys/net/netfilter/nf_conntrack_count")
maxfile := common.HostProc("sys/net/netfilter/nf_conntrack_max")
count, err := common.ReadInts(countfile)
if err != nil {
return nil, err
}
stats := make([]FilterStat, 0, 1)
max, err := common.ReadInts(maxfile)
if err != nil {
return nil, err
}
payload := FilterStat{
ConnTrackCount: count[0],
ConnTrackMax: max[0],
}
stats = append(stats, payload)
return stats, nil
}
// http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
var TCPStatuses = map[string]string{
"01": "ESTABLISHED",
"02": "SYN_SENT",
"03": "SYN_RECV",
"04": "FIN_WAIT1",
"05": "FIN_WAIT2",
"06": "TIME_WAIT",
"07": "CLOSE",
"08": "CLOSE_WAIT",
"09": "LAST_ACK",
"0A": "LISTEN",
"0B": "CLOSING",
}
type netConnectionKindType struct {
family uint32
sockType uint32
filename string
}
var kindTCP4 = netConnectionKindType{
family: syscall.AF_INET,
sockType: syscall.SOCK_STREAM,
filename: "tcp",
}
var kindTCP6 = netConnectionKindType{
family: syscall.AF_INET6,
sockType: syscall.SOCK_STREAM,
filename: "tcp6",
}
var kindUDP4 = netConnectionKindType{
family: syscall.AF_INET,
sockType: syscall.SOCK_DGRAM,
filename: "udp",
}
var kindUDP6 = netConnectionKindType{
family: syscall.AF_INET6,
sockType: syscall.SOCK_DGRAM,
filename: "udp6",
}
var kindUNIX = netConnectionKindType{
family: syscall.AF_UNIX,
filename: "unix",
}
var netConnectionKindMap = map[string][]netConnectionKindType{
"all": {kindTCP4, kindTCP6, kindUDP4, kindUDP6, kindUNIX},
"tcp": {kindTCP4, kindTCP6},
"tcp4": {kindTCP4},
"tcp6": {kindTCP6},
"udp": {kindUDP4, kindUDP6},
"udp4": {kindUDP4},
"udp6": {kindUDP6},
"unix": {kindUNIX},
"inet": {kindTCP4, kindTCP6, kindUDP4, kindUDP6},
"inet4": {kindTCP4, kindUDP4},
"inet6": {kindTCP6, kindUDP6},
}
type inodeMap struct {
pid int32
fd uint32
}
type connTmp struct {
fd uint32
family uint32
sockType uint32
laddr Addr
raddr Addr
status string
pid int32
boundPid int32
path string
}
// Return a list of network connections opened.
func Connections(kind string) ([]ConnectionStat, error) {
return ConnectionsWithContext(context.Background(), kind)
}
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
return ConnectionsPid(kind, 0)
}
// Return a list of network connections opened returning at most `max`
// connections for each running process.
func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
return ConnectionsMaxWithContext(context.Background(), kind, max)
}
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
return ConnectionsPidMax(kind, 0, max)
}
// Return a list of network connections opened by a process.
func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
return ConnectionsPidWithContext(context.Background(), kind, pid)
}
func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
tmap, ok := netConnectionKindMap[kind]
if !ok {
return nil, fmt.Errorf("invalid kind, %s", kind)
}
root := common.HostProc()
var err error
var inodes map[string][]inodeMap
if pid == 0 {
inodes, err = getProcInodesAll(root, 0)
} else {
inodes, err = getProcInodes(root, pid, 0)
if len(inodes) == 0 {
// no connection for the pid
return []ConnectionStat{}, nil
}
}
if err != nil {
return nil, fmt.Errorf("cound not get pid(s), %d: %s", pid, err)
}
return statsFromInodes(root, pid, tmap, inodes)
}
// Return up to `max` network connections opened by a process.
func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) {
return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max)
}
func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
tmap, ok := netConnectionKindMap[kind]
if !ok {
return nil, fmt.Errorf("invalid kind, %s", kind)
}
root := common.HostProc()
var err error
var inodes map[string][]inodeMap
if pid == 0 {
inodes, err = getProcInodesAll(root, max)
} else {
inodes, err = getProcInodes(root, pid, max)
if len(inodes) == 0 {
// no connection for the pid
return []ConnectionStat{}, nil
}
}
if err != nil {
return nil, fmt.Errorf("cound not get pid(s), %d", pid)
}
return statsFromInodes(root, pid, tmap, inodes)
}
func statsFromInodes(root string, pid int32, tmap []netConnectionKindType, inodes map[string][]inodeMap) ([]ConnectionStat, error) {
dupCheckMap := make(map[string]struct{})
var ret []ConnectionStat
var err error
for _, t := range tmap {
var path string
var connKey string
var ls []connTmp
if pid == 0 {
path = fmt.Sprintf("%s/net/%s", root, t.filename)
} else {
path = fmt.Sprintf("%s/%d/net/%s", root, pid, t.filename)
}
switch t.family {
case syscall.AF_INET, syscall.AF_INET6:
ls, err = processInet(path, t, inodes, pid)
case syscall.AF_UNIX:
ls, err = processUnix(path, t, inodes, pid)
}
if err != nil {
return nil, err
}
for _, c := range ls {
// Build TCP key to id the connection uniquely
// socket type, src ip, src port, dst ip, dst port and state should be enough
// to prevent duplications.
connKey = fmt.Sprintf("%d-%s:%d-%s:%d-%s", c.sockType, c.laddr.IP, c.laddr.Port, c.raddr.IP, c.raddr.Port, c.status)
if _, ok := dupCheckMap[connKey]; ok {
continue
}
conn := ConnectionStat{
Fd: c.fd,
Family: c.family,
Type: c.sockType,
Laddr: c.laddr,
Raddr: c.raddr,
Status: c.status,
Pid: c.pid,
}
if c.pid == 0 {
conn.Pid = c.boundPid
} else {
conn.Pid = c.pid
}
// fetch process owner Real, effective, saved set, and filesystem UIDs
proc := process{Pid: conn.Pid}
conn.Uids, _ = proc.getUids()
ret = append(ret, conn)
dupCheckMap[connKey] = struct{}{}
}
}
return ret, nil
}
// getProcInodes returnes fd of the pid.
func getProcInodes(root string, pid int32, max int) (map[string][]inodeMap, error) {
ret := make(map[string][]inodeMap)
dir := fmt.Sprintf("%s/%d/fd", root, pid)
f, err := os.Open(dir)
if err != nil {
return ret, err
}
defer f.Close()
files, err := f.Readdir(max)
if err != nil {
return ret, err
}
for _, fd := range files {
inodePath := fmt.Sprintf("%s/%d/fd/%s", root, pid, fd.Name())
inode, err := os.Readlink(inodePath)
if err != nil {
continue
}
if !strings.HasPrefix(inode, "socket:[") {
continue
}
// the process is using a socket
l := len(inode)
inode = inode[8 : l-1]
_, ok := ret[inode]
if !ok {
ret[inode] = make([]inodeMap, 0)
}
fd, err := strconv.Atoi(fd.Name())
if err != nil {
continue
}
i := inodeMap{
pid: pid,
fd: uint32(fd),
}
ret[inode] = append(ret[inode], i)
}
return ret, nil
}
// Pids retunres all pids.
// Note: this is a copy of process_linux.Pids()
// FIXME: Import process occures import cycle.
// move to common made other platform breaking. Need consider.
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32
d, err := os.Open(common.HostProc())
if err != nil {
return nil, err
}
defer d.Close()
fnames, err := d.Readdirnames(-1)
if err != nil {
return nil, err
}
for _, fname := range fnames {
pid, err := strconv.ParseInt(fname, 10, 32)
if err != nil {
// if not numeric name, just skip
continue
}
ret = append(ret, int32(pid))
}
return ret, nil
}
// Note: the following is based off process_linux structs and methods
// we need these to fetch the owner of a process ID
// FIXME: Import process occures import cycle.
// see remarks on pids()
type process struct {
Pid int32 `json:"pid"`
uids []int32
}
// Uids returns user ids of the process as a slice of the int
func (p *process) getUids() ([]int32, error) {
err := p.fillFromStatus()
if err != nil {
return []int32{}, err
}
return p.uids, nil
}
// Get status from /proc/(pid)/status
func (p *process) fillFromStatus() error {
pid := p.Pid
statPath := common.HostProc(strconv.Itoa(int(pid)), "status")
contents, err := ioutil.ReadFile(statPath)
if err != nil {
return err
}
lines := strings.Split(string(contents), "\n")
for _, line := range lines {
tabParts := strings.SplitN(line, "\t", 2)
if len(tabParts) < 2 {
continue
}
value := tabParts[1]
switch strings.TrimRight(tabParts[0], ":") {
case "Uid":
p.uids = make([]int32, 0, 4)
for _, i := range strings.Split(value, "\t") {
v, err := strconv.ParseInt(i, 10, 32)
if err != nil {
return err
}
p.uids = append(p.uids, int32(v))
}
}
}
return nil
}
func getProcInodesAll(root string, max int) (map[string][]inodeMap, error) {
pids, err := Pids()
if err != nil {
return nil, err
}
ret := make(map[string][]inodeMap)
for _, pid := range pids {
t, err := getProcInodes(root, pid, max)
if err != nil {
// skip if permission error or no longer exists
if os.IsPermission(err) || os.IsNotExist(err) {
continue
}
return ret, err
}
if len(t) == 0 {
continue
}
// TODO: update ret.
ret = updateMap(ret, t)
}
return ret, nil
}
// decodeAddress decode addresse represents addr in proc/net/*
// ex:
// "0500000A:0016" -> "10.0.0.5", 22
// "0085002452100113070057A13F025401:0035" -> "2400:8500:1301:1052:a157:7:154:23f", 53
func decodeAddress(family uint32, src string) (Addr, error) {
t := strings.Split(src, ":")
if len(t) != 2 {
return Addr{}, fmt.Errorf("does not contain port, %s", src)
}
addr := t[0]
port, err := strconv.ParseInt("0x"+t[1], 0, 64)
if err != nil {
return Addr{}, fmt.Errorf("invalid port, %s", src)
}
decoded, err := hex.DecodeString(addr)
if err != nil {
return Addr{}, fmt.Errorf("decode error, %s", err)
}
var ip net.IP
// Assumes this is little_endian
if family == syscall.AF_INET {
ip = net.IP(Reverse(decoded))
} else { // IPv6
ip, err = parseIPv6HexString(decoded)
if err != nil {
return Addr{}, err
}
}
return Addr{
IP: ip.String(),
Port: uint32(port),
}, nil
}
// Reverse reverses array of bytes.
func Reverse(s []byte) []byte {
return ReverseWithContext(context.Background(), s)
}
func ReverseWithContext(ctx context.Context, s []byte) []byte {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}
// parseIPv6HexString parse array of bytes to IPv6 string
func parseIPv6HexString(src []byte) (net.IP, error) {
if len(src) != 16 {
return nil, fmt.Errorf("invalid IPv6 string")
}
buf := make([]byte, 0, 16)
for i := 0; i < len(src); i += 4 {
r := Reverse(src[i : i+4])
buf = append(buf, r...)
}
return net.IP(buf), nil
}
func processInet(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
if strings.HasSuffix(file, "6") && !common.PathExists(file) {
// IPv6 not supported, return empty.
return []connTmp{}, nil
}
// Read the contents of the /proc file with a single read sys call.
// This minimizes duplicates in the returned connections
// For more info:
// https://github.com/shirou/gopsutil/pull/361
contents, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
lines := bytes.Split(contents, []byte("\n"))
var ret []connTmp
// skip first line
for _, line := range lines[1:] {
l := strings.Fields(string(line))
if len(l) < 10 {
continue
}
laddr := l[1]
raddr := l[2]
status := l[3]
inode := l[9]
pid := int32(0)
fd := uint32(0)
i, exists := inodes[inode]
if exists {
pid = i[0].pid
fd = i[0].fd
}
if filterPid > 0 && filterPid != pid {
continue
}
if kind.sockType == syscall.SOCK_STREAM {
status = TCPStatuses[status]
} else {
status = "NONE"
}
la, err := decodeAddress(kind.family, laddr)
if err != nil {
continue
}
ra, err := decodeAddress(kind.family, raddr)
if err != nil {
continue
}
ret = append(ret, connTmp{
fd: fd,
family: kind.family,
sockType: kind.sockType,
laddr: la,
raddr: ra,
status: status,
pid: pid,
})
}
return ret, nil
}
func processUnix(file string, kind netConnectionKindType, inodes map[string][]inodeMap, filterPid int32) ([]connTmp, error) {
// Read the contents of the /proc file with a single read sys call.
// This minimizes duplicates in the returned connections
// For more info:
// https://github.com/shirou/gopsutil/pull/361
contents, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
lines := bytes.Split(contents, []byte("\n"))
var ret []connTmp
// skip first line
for _, line := range lines[1:] {
tokens := strings.Fields(string(line))
if len(tokens) < 6 {
continue
}
st, err := strconv.Atoi(tokens[4])
if err != nil {
return nil, err
}
inode := tokens[6]
var pairs []inodeMap
pairs, exists := inodes[inode]
if !exists {
pairs = []inodeMap{
{},
}
}
for _, pair := range pairs {
if filterPid > 0 && filterPid != pair.pid {
continue
}
var path string
if len(tokens) == 8 {
path = tokens[len(tokens)-1]
}
ret = append(ret, connTmp{
fd: pair.fd,
family: kind.family,
sockType: uint32(st),
laddr: Addr{
IP: path,
},
pid: pair.pid,
status: "NONE",
path: path,
})
}
}
return ret, nil
}
func updateMap(src map[string][]inodeMap, add map[string][]inodeMap) map[string][]inodeMap {
for key, value := range add {
a, exists := src[key]
if !exists {
src[key] = value
continue
}
src[key] = append(a, value...)
}
return src
}

312
vendor/github.com/shirou/gopsutil/net/net_openbsd.go generated vendored Normal file
View File

@@ -0,0 +1,312 @@
// +build openbsd
package net
import (
"context"
"errors"
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
"syscall"
"github.com/shirou/gopsutil/internal/common"
)
var portMatch = regexp.MustCompile(`(.*)\.(\d+)$`)
func ParseNetstat(output string, mode string,
iocs map[string]IOCountersStat) error {
lines := strings.Split(output, "\n")
exists := make([]string, 0, len(lines)-1)
columns := 6
if mode == "ind" {
columns = 10
}
for _, line := range lines {
values := strings.Fields(line)
if len(values) < 1 || values[0] == "Name" {
continue
}
if common.StringsHas(exists, values[0]) {
// skip if already get
continue
}
if len(values) < columns {
continue
}
base := 1
// sometimes Address is ommitted
if len(values) < columns {
base = 0
}
parsed := make([]uint64, 0, 8)
var vv []string
if mode == "inb" {
vv = []string{
values[base+3], // BytesRecv
values[base+4], // BytesSent
}
} else {
vv = []string{
values[base+3], // Ipkts
values[base+4], // Ierrs
values[base+5], // Opkts
values[base+6], // Oerrs
values[base+8], // Drops
}
}
for _, target := range vv {
if target == "-" {
parsed = append(parsed, 0)
continue
}
t, err := strconv.ParseUint(target, 10, 64)
if err != nil {
return err
}
parsed = append(parsed, t)
}
exists = append(exists, values[0])
n, present := iocs[values[0]]
if !present {
n = IOCountersStat{Name: values[0]}
}
if mode == "inb" {
n.BytesRecv = parsed[0]
n.BytesSent = parsed[1]
} else {
n.PacketsRecv = parsed[0]
n.Errin = parsed[1]
n.PacketsSent = parsed[2]
n.Errout = parsed[3]
n.Dropin = parsed[4]
n.Dropout = parsed[4]
}
iocs[n.Name] = n
}
return nil
}
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
netstat, err := exec.LookPath("netstat")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, netstat, "-inb")
if err != nil {
return nil, err
}
out2, err := invoke.CommandWithContext(ctx, netstat, "-ind")
if err != nil {
return nil, err
}
iocs := make(map[string]IOCountersStat)
lines := strings.Split(string(out), "\n")
ret := make([]IOCountersStat, 0, len(lines)-1)
err = ParseNetstat(string(out), "inb", iocs)
if err != nil {
return nil, err
}
err = ParseNetstat(string(out2), "ind", iocs)
if err != nil {
return nil, err
}
for _, ioc := range iocs {
ret = append(ret, ioc)
}
if pernic == false {
return getIOCountersAll(ret)
}
return ret, nil
}
// NetIOCountersByFile is an method which is added just a compatibility for linux.
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return IOCountersByFileWithContext(context.Background(), pernic, filename)
}
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
return IOCounters(pernic)
}
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for openbsd")
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for OpenBSD
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for openbsd")
}
func parseNetstatLine(line string) (ConnectionStat, error) {
f := strings.Fields(line)
if len(f) < 5 {
return ConnectionStat{}, fmt.Errorf("wrong line,%s", line)
}
var netType, netFamily uint32
switch f[0] {
case "tcp":
netType = syscall.SOCK_STREAM
netFamily = syscall.AF_INET
case "udp":
netType = syscall.SOCK_DGRAM
netFamily = syscall.AF_INET
case "tcp6":
netType = syscall.SOCK_STREAM
netFamily = syscall.AF_INET6
case "udp6":
netType = syscall.SOCK_DGRAM
netFamily = syscall.AF_INET6
default:
return ConnectionStat{}, fmt.Errorf("unknown type, %s", f[0])
}
laddr, raddr, err := parseNetstatAddr(f[3], f[4], netFamily)
if err != nil {
return ConnectionStat{}, fmt.Errorf("failed to parse netaddr, %s %s", f[3], f[4])
}
n := ConnectionStat{
Fd: uint32(0), // not supported
Family: uint32(netFamily),
Type: uint32(netType),
Laddr: laddr,
Raddr: raddr,
Pid: int32(0), // not supported
}
if len(f) == 6 {
n.Status = f[5]
}
return n, nil
}
func parseNetstatAddr(local string, remote string, family uint32) (laddr Addr, raddr Addr, err error) {
parse := func(l string) (Addr, error) {
matches := portMatch.FindStringSubmatch(l)
if matches == nil {
return Addr{}, fmt.Errorf("wrong addr, %s", l)
}
host := matches[1]
port := matches[2]
if host == "*" {
switch family {
case syscall.AF_INET:
host = "0.0.0.0"
case syscall.AF_INET6:
host = "::"
default:
return Addr{}, fmt.Errorf("unknown family, %d", family)
}
}
lport, err := strconv.Atoi(port)
if err != nil {
return Addr{}, err
}
return Addr{IP: host, Port: uint32(lport)}, nil
}
laddr, err = parse(local)
if remote != "*.*" { // remote addr exists
raddr, err = parse(remote)
if err != nil {
return laddr, raddr, err
}
}
return laddr, raddr, err
}
// Return a list of network connections opened.
func Connections(kind string) ([]ConnectionStat, error) {
return ConnectionsWithContext(context.Background(), kind)
}
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
var ret []ConnectionStat
args := []string{"-na"}
switch strings.ToLower(kind) {
default:
fallthrough
case "":
fallthrough
case "all":
fallthrough
case "inet":
// nothing to add
case "inet4":
args = append(args, "-finet")
case "inet6":
args = append(args, "-finet6")
case "tcp":
args = append(args, "-ptcp")
case "tcp4":
args = append(args, "-ptcp", "-finet")
case "tcp6":
args = append(args, "-ptcp", "-finet6")
case "udp":
args = append(args, "-pudp")
case "udp4":
args = append(args, "-pudp", "-finet")
case "udp6":
args = append(args, "-pudp", "-finet6")
case "unix":
return ret, common.ErrNotImplementedError
}
netstat, err := exec.LookPath("netstat")
if err != nil {
return nil, err
}
out, err := invoke.CommandWithContext(ctx, netstat, args...)
if err != nil {
return nil, err
}
lines := strings.Split(string(out), "\n")
for _, line := range lines {
if !(strings.HasPrefix(line, "tcp") || strings.HasPrefix(line, "udp")) {
continue
}
n, err := parseNetstatLine(line)
if err != nil {
continue
}
ret = append(ret, n)
}
return ret, nil
}

96
vendor/github.com/shirou/gopsutil/net/net_unix.go generated vendored Normal file
View File

@@ -0,0 +1,96 @@
// +build freebsd darwin
package net
import (
"context"
"strings"
"github.com/shirou/gopsutil/internal/common"
)
// Return a list of network connections opened.
func Connections(kind string) ([]ConnectionStat, error) {
return ConnectionsWithContext(context.Background(), kind)
}
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
return ConnectionsPid(kind, 0)
}
// Return a list of network connections opened returning at most `max`
// connections for each running process.
func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
return ConnectionsMaxWithContext(context.Background(), kind, max)
}
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
return []ConnectionStat{}, common.ErrNotImplementedError
}
// Return a list of network connections opened by a process.
func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
return ConnectionsPidWithContext(context.Background(), kind, pid)
}
func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
var ret []ConnectionStat
args := []string{"-i"}
switch strings.ToLower(kind) {
default:
fallthrough
case "":
fallthrough
case "all":
fallthrough
case "inet":
args = append(args, "tcp", "-i", "udp")
case "inet4":
args = append(args, "4")
case "inet6":
args = append(args, "6")
case "tcp":
args = append(args, "tcp")
case "tcp4":
args = append(args, "4tcp")
case "tcp6":
args = append(args, "6tcp")
case "udp":
args = append(args, "udp")
case "udp4":
args = append(args, "6udp")
case "udp6":
args = append(args, "6udp")
case "unix":
args = []string{"-U"}
}
r, err := common.CallLsofWithContext(ctx, invoke, pid, args...)
if err != nil {
return nil, err
}
for _, rr := range r {
if strings.HasPrefix(rr, "COMMAND") {
continue
}
n, err := parseNetLine(rr)
if err != nil {
continue
}
ret = append(ret, n)
}
return ret, nil
}
// Return up to `max` network connections opened by a process.
func ConnectionsPidMax(kind string, pid int32, max int) ([]ConnectionStat, error) {
return ConnectionsPidMaxWithContext(context.Background(), kind, pid, max)
}
func ConnectionsPidMaxWithContext(ctx context.Context, kind string, pid int32, max int) ([]ConnectionStat, error) {
return []ConnectionStat{}, common.ErrNotImplementedError
}

645
vendor/github.com/shirou/gopsutil/net/net_windows.go generated vendored Normal file
View File

@@ -0,0 +1,645 @@
// +build windows
package net
import (
"context"
"errors"
"fmt"
"net"
"os"
"syscall"
"unsafe"
"github.com/shirou/gopsutil/internal/common"
"golang.org/x/sys/windows"
)
var (
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
procGetExtendedTCPTable = modiphlpapi.NewProc("GetExtendedTcpTable")
procGetExtendedUDPTable = modiphlpapi.NewProc("GetExtendedUdpTable")
)
const (
TCPTableBasicListener = iota
TCPTableBasicConnections
TCPTableBasicAll
TCPTableOwnerPIDListener
TCPTableOwnerPIDConnections
TCPTableOwnerPIDAll
TCPTableOwnerModuleListener
TCPTableOwnerModuleConnections
TCPTableOwnerModuleAll
)
type netConnectionKindType struct {
family uint32
sockType uint32
filename string
}
var kindTCP4 = netConnectionKindType{
family: syscall.AF_INET,
sockType: syscall.SOCK_STREAM,
filename: "tcp",
}
var kindTCP6 = netConnectionKindType{
family: syscall.AF_INET6,
sockType: syscall.SOCK_STREAM,
filename: "tcp6",
}
var kindUDP4 = netConnectionKindType{
family: syscall.AF_INET,
sockType: syscall.SOCK_DGRAM,
filename: "udp",
}
var kindUDP6 = netConnectionKindType{
family: syscall.AF_INET6,
sockType: syscall.SOCK_DGRAM,
filename: "udp6",
}
var netConnectionKindMap = map[string][]netConnectionKindType{
"all": {kindTCP4, kindTCP6, kindUDP4, kindUDP6},
"tcp": {kindTCP4, kindTCP6},
"tcp4": {kindTCP4},
"tcp6": {kindTCP6},
"udp": {kindUDP4, kindUDP6},
"udp4": {kindUDP4},
"udp6": {kindUDP6},
"inet": {kindTCP4, kindTCP6, kindUDP4, kindUDP6},
"inet4": {kindTCP4, kindUDP4},
"inet6": {kindTCP6, kindUDP6},
}
func IOCounters(pernic bool) ([]IOCountersStat, error) {
return IOCountersWithContext(context.Background(), pernic)
}
func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) {
ifs, err := net.Interfaces()
if err != nil {
return nil, err
}
var ret []IOCountersStat
for _, ifi := range ifs {
c := IOCountersStat{
Name: ifi.Name,
}
row := windows.MibIfRow{Index: uint32(ifi.Index)}
e := windows.GetIfEntry(&row)
if e != nil {
return nil, os.NewSyscallError("GetIfEntry", e)
}
c.BytesSent = uint64(row.OutOctets)
c.BytesRecv = uint64(row.InOctets)
c.PacketsSent = uint64(row.OutUcastPkts)
c.PacketsRecv = uint64(row.InUcastPkts)
c.Errin = uint64(row.InErrors)
c.Errout = uint64(row.OutErrors)
c.Dropin = uint64(row.InDiscards)
c.Dropout = uint64(row.OutDiscards)
ret = append(ret, c)
}
if pernic == false {
return getIOCountersAll(ret)
}
return ret, nil
}
// NetIOCountersByFile is an method which is added just a compatibility for linux.
func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) {
return IOCountersByFileWithContext(context.Background(), pernic, filename)
}
func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) {
return IOCounters(pernic)
}
// Return a list of network connections
// Available kind:
// reference to netConnectionKindMap
func Connections(kind string) ([]ConnectionStat, error) {
return ConnectionsWithContext(context.Background(), kind)
}
func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) {
return ConnectionsPidWithContext(ctx, kind, 0)
}
// ConnectionsPid Return a list of network connections opened by a process
func ConnectionsPid(kind string, pid int32) ([]ConnectionStat, error) {
return ConnectionsPidWithContext(context.Background(), kind, pid)
}
func ConnectionsPidWithContext(ctx context.Context, kind string, pid int32) ([]ConnectionStat, error) {
tmap, ok := netConnectionKindMap[kind]
if !ok {
return nil, fmt.Errorf("invalid kind, %s", kind)
}
return getProcInet(tmap, pid)
}
func getProcInet(kinds []netConnectionKindType, pid int32) ([]ConnectionStat, error) {
stats := make([]ConnectionStat, 0)
for _, kind := range kinds {
s, err := getNetStatWithKind(kind)
if err != nil {
continue
}
if pid == 0 {
stats = append(stats, s...)
} else {
for _, ns := range s {
if ns.Pid != pid {
continue
}
stats = append(stats, ns)
}
}
}
return stats, nil
}
func getNetStatWithKind(kindType netConnectionKindType) ([]ConnectionStat, error) {
if kindType.filename == "" {
return nil, fmt.Errorf("kind filename must be required")
}
switch kindType.filename {
case kindTCP4.filename:
return getTCPConnections(kindTCP4.family)
case kindTCP6.filename:
return getTCPConnections(kindTCP6.family)
case kindUDP4.filename:
return getUDPConnections(kindUDP4.family)
case kindUDP6.filename:
return getUDPConnections(kindUDP6.family)
}
return nil, fmt.Errorf("invalid kind filename, %s", kindType.filename)
}
// Return a list of network connections opened returning at most `max`
// connections for each running process.
func ConnectionsMax(kind string, max int) ([]ConnectionStat, error) {
return ConnectionsMaxWithContext(context.Background(), kind, max)
}
func ConnectionsMaxWithContext(ctx context.Context, kind string, max int) ([]ConnectionStat, error) {
return []ConnectionStat{}, common.ErrNotImplementedError
}
func FilterCounters() ([]FilterStat, error) {
return FilterCountersWithContext(context.Background())
}
func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) {
return nil, errors.New("NetFilterCounters not implemented for windows")
}
// NetProtoCounters returns network statistics for the entire system
// If protocols is empty then all protocols are returned, otherwise
// just the protocols in the list are returned.
// Not Implemented for Windows
func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) {
return ProtoCountersWithContext(context.Background(), protocols)
}
func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) {
return nil, errors.New("NetProtoCounters not implemented for windows")
}
func getTableUintptr(family uint32, buf []byte) uintptr {
var (
pmibTCPTable pmibTCPTableOwnerPidAll
pmibTCP6Table pmibTCP6TableOwnerPidAll
p uintptr
)
switch family {
case kindTCP4.family:
if len(buf) > 0 {
pmibTCPTable = (*mibTCPTableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibTCPTable))
} else {
p = uintptr(unsafe.Pointer(pmibTCPTable))
}
case kindTCP6.family:
if len(buf) > 0 {
pmibTCP6Table = (*mibTCP6TableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibTCP6Table))
} else {
p = uintptr(unsafe.Pointer(pmibTCP6Table))
}
}
return p
}
func getTableInfo(filename string, table interface{}) (index, step, length int) {
switch filename {
case kindTCP4.filename:
index = int(unsafe.Sizeof(table.(pmibTCPTableOwnerPidAll).DwNumEntries))
step = int(unsafe.Sizeof(table.(pmibTCPTableOwnerPidAll).Table))
length = int(table.(pmibTCPTableOwnerPidAll).DwNumEntries)
case kindTCP6.filename:
index = int(unsafe.Sizeof(table.(pmibTCP6TableOwnerPidAll).DwNumEntries))
step = int(unsafe.Sizeof(table.(pmibTCP6TableOwnerPidAll).Table))
length = int(table.(pmibTCP6TableOwnerPidAll).DwNumEntries)
case kindUDP4.filename:
index = int(unsafe.Sizeof(table.(pmibUDPTableOwnerPid).DwNumEntries))
step = int(unsafe.Sizeof(table.(pmibUDPTableOwnerPid).Table))
length = int(table.(pmibUDPTableOwnerPid).DwNumEntries)
case kindUDP6.filename:
index = int(unsafe.Sizeof(table.(pmibUDP6TableOwnerPid).DwNumEntries))
step = int(unsafe.Sizeof(table.(pmibUDP6TableOwnerPid).Table))
length = int(table.(pmibUDP6TableOwnerPid).DwNumEntries)
}
return
}
func getTCPConnections(family uint32) ([]ConnectionStat, error) {
var (
p uintptr
buf []byte
size uint32
pmibTCPTable pmibTCPTableOwnerPidAll
pmibTCP6Table pmibTCP6TableOwnerPidAll
)
if family == 0 {
return nil, fmt.Errorf("faimly must be required")
}
for {
switch family {
case kindTCP4.family:
if len(buf) > 0 {
pmibTCPTable = (*mibTCPTableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibTCPTable))
} else {
p = uintptr(unsafe.Pointer(pmibTCPTable))
}
case kindTCP6.family:
if len(buf) > 0 {
pmibTCP6Table = (*mibTCP6TableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibTCP6Table))
} else {
p = uintptr(unsafe.Pointer(pmibTCP6Table))
}
}
err := getExtendedTcpTable(p,
&size,
true,
family,
tcpTableOwnerPidAll,
0)
if err == nil {
break
}
if err != windows.ERROR_INSUFFICIENT_BUFFER {
return nil, err
}
buf = make([]byte, size)
}
var (
index, step int
length int
)
stats := make([]ConnectionStat, 0)
switch family {
case kindTCP4.family:
index, step, length = getTableInfo(kindTCP4.filename, pmibTCPTable)
case kindTCP6.family:
index, step, length = getTableInfo(kindTCP6.filename, pmibTCP6Table)
}
if length == 0 {
return nil, nil
}
for i := 0; i < length; i++ {
switch family {
case kindTCP4.family:
mibs := (*mibTCPRowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat()
stats = append(stats, ns)
case kindTCP6.family:
mibs := (*mibTCP6RowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat()
stats = append(stats, ns)
}
index += step
}
return stats, nil
}
func getUDPConnections(family uint32) ([]ConnectionStat, error) {
var (
p uintptr
buf []byte
size uint32
pmibUDPTable pmibUDPTableOwnerPid
pmibUDP6Table pmibUDP6TableOwnerPid
)
if family == 0 {
return nil, fmt.Errorf("faimly must be required")
}
for {
switch family {
case kindUDP4.family:
if len(buf) > 0 {
pmibUDPTable = (*mibUDPTableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibUDPTable))
} else {
p = uintptr(unsafe.Pointer(pmibUDPTable))
}
case kindUDP6.family:
if len(buf) > 0 {
pmibUDP6Table = (*mibUDP6TableOwnerPid)(unsafe.Pointer(&buf[0]))
p = uintptr(unsafe.Pointer(pmibUDP6Table))
} else {
p = uintptr(unsafe.Pointer(pmibUDP6Table))
}
}
err := getExtendedUdpTable(
p,
&size,
true,
family,
udpTableOwnerPid,
0,
)
if err == nil {
break
}
if err != windows.ERROR_INSUFFICIENT_BUFFER {
return nil, err
}
buf = make([]byte, size)
}
var (
index, step, length int
)
stats := make([]ConnectionStat, 0)
switch family {
case kindUDP4.family:
index, step, length = getTableInfo(kindUDP4.filename, pmibUDPTable)
case kindUDP6.family:
index, step, length = getTableInfo(kindUDP6.filename, pmibUDP6Table)
}
if length == 0 {
return nil, nil
}
for i := 0; i < length; i++ {
switch family {
case kindUDP4.family:
mibs := (*mibUDPRowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat()
stats = append(stats, ns)
case kindUDP4.family:
mibs := (*mibUDP6RowOwnerPid)(unsafe.Pointer(&buf[index]))
ns := mibs.convertToConnectionStat()
stats = append(stats, ns)
}
index += step
}
return stats, nil
}
// tcpStatuses https://msdn.microsoft.com/en-us/library/windows/desktop/bb485761(v=vs.85).aspx
var tcpStatuses = map[mibTCPState]string{
1: "CLOSED",
2: "LISTEN",
3: "SYN_SENT",
4: "SYN_RECEIVED",
5: "ESTABLISHED",
6: "FIN_WAIT_1",
7: "FIN_WAIT_2",
8: "CLOSE_WAIT",
9: "CLOSING",
10: "LAST_ACK",
11: "TIME_WAIT",
12: "DELETE",
}
func getExtendedTcpTable(pTcpTable uintptr, pdwSize *uint32, bOrder bool, ulAf uint32, tableClass tcpTableClass, reserved uint32) (errcode error) {
r1, _, _ := syscall.Syscall6(procGetExtendedTCPTable.Addr(), 6, pTcpTable, uintptr(unsafe.Pointer(pdwSize)), getUintptrFromBool(bOrder), uintptr(ulAf), uintptr(tableClass), uintptr(reserved))
if r1 != 0 {
errcode = syscall.Errno(r1)
}
return
}
func getExtendedUdpTable(pUdpTable uintptr, pdwSize *uint32, bOrder bool, ulAf uint32, tableClass udpTableClass, reserved uint32) (errcode error) {
r1, _, _ := syscall.Syscall6(procGetExtendedUDPTable.Addr(), 6, pUdpTable, uintptr(unsafe.Pointer(pdwSize)), getUintptrFromBool(bOrder), uintptr(ulAf), uintptr(tableClass), uintptr(reserved))
if r1 != 0 {
errcode = syscall.Errno(r1)
}
return
}
func getUintptrFromBool(b bool) uintptr {
if b {
return 1
}
return 0
}
const anySize = 1
// type MIB_TCP_STATE int32
type mibTCPState int32
type tcpTableClass int32
const (
tcpTableBasicListener tcpTableClass = iota
tcpTableBasicConnections
tcpTableBasicAll
tcpTableOwnerPidListener
tcpTableOwnerPidConnections
tcpTableOwnerPidAll
tcpTableOwnerModuleListener
tcpTableOwnerModuleConnections
tcpTableOwnerModuleAll
)
type udpTableClass int32
const (
udpTableBasic udpTableClass = iota
udpTableOwnerPid
udpTableOwnerModule
)
// TCP
type mibTCPRowOwnerPid struct {
DwState uint32
DwLocalAddr uint32
DwLocalPort uint32
DwRemoteAddr uint32
DwRemotePort uint32
DwOwningPid uint32
}
func (m *mibTCPRowOwnerPid) convertToConnectionStat() ConnectionStat {
ns := ConnectionStat{
Family: kindTCP4.family,
Type: kindTCP4.sockType,
Laddr: Addr{
IP: parseIPv4HexString(m.DwLocalAddr),
Port: uint32(decodePort(m.DwLocalPort)),
},
Raddr: Addr{
IP: parseIPv4HexString(m.DwRemoteAddr),
Port: uint32(decodePort(m.DwRemotePort)),
},
Pid: int32(m.DwOwningPid),
Status: tcpStatuses[mibTCPState(m.DwState)],
}
return ns
}
type mibTCPTableOwnerPid struct {
DwNumEntries uint32
Table [anySize]mibTCPRowOwnerPid
}
type mibTCP6RowOwnerPid struct {
UcLocalAddr [16]byte
DwLocalScopeId uint32
DwLocalPort uint32
UcRemoteAddr [16]byte
DwRemoteScopeId uint32
DwRemotePort uint32
DwState uint32
DwOwningPid uint32
}
func (m *mibTCP6RowOwnerPid) convertToConnectionStat() ConnectionStat {
ns := ConnectionStat{
Family: kindTCP6.family,
Type: kindTCP6.sockType,
Laddr: Addr{
IP: parseIPv6HexString(m.UcLocalAddr),
Port: uint32(decodePort(m.DwLocalPort)),
},
Raddr: Addr{
IP: parseIPv6HexString(m.UcRemoteAddr),
Port: uint32(decodePort(m.DwRemotePort)),
},
Pid: int32(m.DwOwningPid),
Status: tcpStatuses[mibTCPState(m.DwState)],
}
return ns
}
type mibTCP6TableOwnerPid struct {
DwNumEntries uint32
Table [anySize]mibTCP6RowOwnerPid
}
type pmibTCPTableOwnerPidAll *mibTCPTableOwnerPid
type pmibTCP6TableOwnerPidAll *mibTCP6TableOwnerPid
// UDP
type mibUDPRowOwnerPid struct {
DwLocalAddr uint32
DwLocalPort uint32
DwOwningPid uint32
}
func (m *mibUDPRowOwnerPid) convertToConnectionStat() ConnectionStat {
ns := ConnectionStat{
Family: kindUDP4.family,
Type: kindUDP4.sockType,
Laddr: Addr{
IP: parseIPv4HexString(m.DwLocalAddr),
Port: uint32(decodePort(m.DwLocalPort)),
},
Pid: int32(m.DwOwningPid),
}
return ns
}
type mibUDPTableOwnerPid struct {
DwNumEntries uint32
Table [anySize]mibUDPRowOwnerPid
}
type mibUDP6RowOwnerPid struct {
UcLocalAddr [16]byte
DwLocalScopeId uint32
DwLocalPort uint32
DwOwningPid uint32
}
func (m *mibUDP6RowOwnerPid) convertToConnectionStat() ConnectionStat {
ns := ConnectionStat{
Family: kindUDP6.family,
Type: kindUDP6.sockType,
Laddr: Addr{
IP: parseIPv6HexString(m.UcLocalAddr),
Port: uint32(decodePort(m.DwLocalPort)),
},
Pid: int32(m.DwOwningPid),
}
return ns
}
type mibUDP6TableOwnerPid struct {
DwNumEntries uint32
Table [anySize]mibUDP6RowOwnerPid
}
type pmibUDPTableOwnerPid *mibUDPTableOwnerPid
type pmibUDP6TableOwnerPid *mibUDP6TableOwnerPid
func decodePort(port uint32) uint16 {
return syscall.Ntohs(uint16(port))
}
func parseIPv4HexString(addr uint32) string {
return fmt.Sprintf("%d.%d.%d.%d", addr&255, addr>>8&255, addr>>16&255, addr>>24&255)
}
func parseIPv6HexString(addr [16]byte) string {
var ret [16]byte
for i := 0; i < 16; i++ {
ret[i] = uint8(addr[i])
}
// convert []byte to net.IP
ip := net.IP(ret[:])
return ip.String()
}

254
vendor/github.com/shirou/gopsutil/process/process.go generated vendored Normal file
View File

@@ -0,0 +1,254 @@
package process
import (
"context"
"encoding/json"
"errors"
"runtime"
"time"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/mem"
)
var (
invoke common.Invoker = common.Invoke{}
ErrorNoChildren = errors.New("process does not have children")
)
type Process struct {
Pid int32 `json:"pid"`
name string
status string
parent int32
numCtxSwitches *NumCtxSwitchesStat
uids []int32
gids []int32
numThreads int32
memInfo *MemoryInfoStat
sigInfo *SignalInfoStat
lastCPUTimes *cpu.TimesStat
lastCPUTime time.Time
tgid int32
}
type OpenFilesStat struct {
Path string `json:"path"`
Fd uint64 `json:"fd"`
}
type MemoryInfoStat struct {
RSS uint64 `json:"rss"` // bytes
VMS uint64 `json:"vms"` // bytes
Data uint64 `json:"data"` // bytes
Stack uint64 `json:"stack"` // bytes
Locked uint64 `json:"locked"` // bytes
Swap uint64 `json:"swap"` // bytes
}
type SignalInfoStat struct {
PendingProcess uint64 `json:"pending_process"`
PendingThread uint64 `json:"pending_thread"`
Blocked uint64 `json:"blocked"`
Ignored uint64 `json:"ignored"`
Caught uint64 `json:"caught"`
}
type RlimitStat struct {
Resource int32 `json:"resource"`
Soft int32 `json:"soft"` //TODO too small. needs to be uint64
Hard int32 `json:"hard"` //TODO too small. needs to be uint64
Used uint64 `json:"used"`
}
type IOCountersStat struct {
ReadCount uint64 `json:"readCount"`
WriteCount uint64 `json:"writeCount"`
ReadBytes uint64 `json:"readBytes"`
WriteBytes uint64 `json:"writeBytes"`
}
type NumCtxSwitchesStat struct {
Voluntary int64 `json:"voluntary"`
Involuntary int64 `json:"involuntary"`
}
// Resource limit constants are from /usr/include/x86_64-linux-gnu/bits/resource.h
// from libc6-dev package in Ubuntu 16.10
const (
RLIMIT_CPU int32 = 0
RLIMIT_FSIZE int32 = 1
RLIMIT_DATA int32 = 2
RLIMIT_STACK int32 = 3
RLIMIT_CORE int32 = 4
RLIMIT_RSS int32 = 5
RLIMIT_NPROC int32 = 6
RLIMIT_NOFILE int32 = 7
RLIMIT_MEMLOCK int32 = 8
RLIMIT_AS int32 = 9
RLIMIT_LOCKS int32 = 10
RLIMIT_SIGPENDING int32 = 11
RLIMIT_MSGQUEUE int32 = 12
RLIMIT_NICE int32 = 13
RLIMIT_RTPRIO int32 = 14
RLIMIT_RTTIME int32 = 15
)
func (p Process) String() string {
s, _ := json.Marshal(p)
return string(s)
}
func (o OpenFilesStat) String() string {
s, _ := json.Marshal(o)
return string(s)
}
func (m MemoryInfoStat) String() string {
s, _ := json.Marshal(m)
return string(s)
}
func (r RlimitStat) String() string {
s, _ := json.Marshal(r)
return string(s)
}
func (i IOCountersStat) String() string {
s, _ := json.Marshal(i)
return string(s)
}
func (p NumCtxSwitchesStat) String() string {
s, _ := json.Marshal(p)
return string(s)
}
func PidExists(pid int32) (bool, error) {
return PidExistsWithContext(context.Background(), pid)
}
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
pids, err := Pids()
if err != nil {
return false, err
}
for _, i := range pids {
if i == pid {
return true, err
}
}
return false, err
}
// Background returns true if the process is in background, false otherwise.
func (p *Process) Background() (bool, error) {
return p.BackgroundWithContext(context.Background())
}
func (p *Process) BackgroundWithContext(ctx context.Context) (bool, error) {
fg, err := p.ForegroundWithContext(ctx)
if err != nil {
return false, err
}
return !fg, err
}
// If interval is 0, return difference from last call(non-blocking).
// If interval > 0, wait interval sec and return diffrence between start and end.
func (p *Process) Percent(interval time.Duration) (float64, error) {
return p.PercentWithContext(context.Background(), interval)
}
func (p *Process) PercentWithContext(ctx context.Context, interval time.Duration) (float64, error) {
cpuTimes, err := p.Times()
if err != nil {
return 0, err
}
now := time.Now()
if interval > 0 {
p.lastCPUTimes = cpuTimes
p.lastCPUTime = now
time.Sleep(interval)
cpuTimes, err = p.Times()
now = time.Now()
if err != nil {
return 0, err
}
} else {
if p.lastCPUTimes == nil {
// invoked first time
p.lastCPUTimes = cpuTimes
p.lastCPUTime = now
return 0, nil
}
}
numcpu := runtime.NumCPU()
delta := (now.Sub(p.lastCPUTime).Seconds()) * float64(numcpu)
ret := calculatePercent(p.lastCPUTimes, cpuTimes, delta, numcpu)
p.lastCPUTimes = cpuTimes
p.lastCPUTime = now
return ret, nil
}
func calculatePercent(t1, t2 *cpu.TimesStat, delta float64, numcpu int) float64 {
if delta == 0 {
return 0
}
delta_proc := t2.Total() - t1.Total()
overall_percent := ((delta_proc / delta) * 100) * float64(numcpu)
return overall_percent
}
// MemoryPercent returns how many percent of the total RAM this process uses
func (p *Process) MemoryPercent() (float32, error) {
return p.MemoryPercentWithContext(context.Background())
}
func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) {
machineMemory, err := mem.VirtualMemory()
if err != nil {
return 0, err
}
total := machineMemory.Total
processMemory, err := p.MemoryInfo()
if err != nil {
return 0, err
}
used := processMemory.RSS
return (100 * float32(used) / float32(total)), nil
}
// CPU_Percent returns how many percent of the CPU time this process uses
func (p *Process) CPUPercent() (float64, error) {
return p.CPUPercentWithContext(context.Background())
}
func (p *Process) CPUPercentWithContext(ctx context.Context) (float64, error) {
crt_time, err := p.CreateTime()
if err != nil {
return 0, err
}
cput, err := p.Times()
if err != nil {
return 0, err
}
created := time.Unix(0, crt_time*int64(time.Millisecond))
totalTime := time.Since(created).Seconds()
if totalTime <= 0 {
return 0, nil
}
return 100 * cput.Total() / totalTime, nil
}

View File

@@ -0,0 +1,654 @@
// +build darwin
package process
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"os/exec"
"strconv"
"strings"
"time"
"unsafe"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/net"
"golang.org/x/sys/unix"
)
// copied from sys/sysctl.h
const (
CTLKern = 1 // "high kernel": proc, limits
KernProc = 14 // struct: process entries
KernProcPID = 1 // by process id
KernProcProc = 8 // only return procs
KernProcAll = 0 // everything
KernProcPathname = 12 // path to executable
)
const (
ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK)
)
type _Ctype_struct___0 struct {
Pad uint64
}
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32
pids, err := callPsWithContext(ctx, "pid", 0, false)
if err != nil {
return ret, err
}
for _, pid := range pids {
v, err := strconv.Atoi(pid[0])
if err != nil {
return ret, err
}
ret = append(ret, int32(v))
}
return ret, nil
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "ppid", p.Pid, false)
if err != nil {
return 0, err
}
v, err := strconv.Atoi(r[0][0])
if err != nil {
return 0, err
}
return int32(v), err
}
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
return common.IntToString(k.Proc.P_comm[:]), nil
}
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
lsof_bin, err := exec.LookPath("lsof")
if err != nil {
return "", err
}
awk_bin, err := exec.LookPath("awk")
if err != nil {
return "", err
}
sed_bin, err := exec.LookPath("sed")
if err != nil {
return "", err
}
lsof := exec.CommandContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn")
awk := exec.CommandContext(ctx, awk_bin, "NR==5{print}")
sed := exec.CommandContext(ctx, sed_bin, "s/n\\//\\//")
output, _, err := common.Pipeline(lsof, awk, sed)
if err != nil {
return "", err
}
ret := strings.TrimSpace(string(output))
return ret, nil
}
// Cmdline returns the command line arguments of the process as a string with
// each argument separated by 0x20 ascii character.
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false)
if err != nil {
return "", err
}
return strings.Join(r[0], " "), err
}
// CmdlineSlice returns the command line arguments of the process as a slice with each
// element being an argument. Because of current deficiencies in the way that the command
// line arguments are found, single arguments that have spaces in the will actually be
// reported as two separate items. In order to do something better CGO would be needed
// to use the native darwin functions.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
r, err := callPsWithContext(ctx, "command", p.Pid, false)
if err != nil {
return nil, err
}
return r[0], err
}
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
r, err := callPsWithContext(ctx, "etime", p.Pid, false)
if err != nil {
return 0, err
}
elapsedSegments := strings.Split(strings.Replace(r[0][0], "-", ":", 1), ":")
var elapsedDurations []time.Duration
for i := len(elapsedSegments) - 1; i >= 0; i-- {
p, err := strconv.ParseInt(elapsedSegments[i], 10, 0)
if err != nil {
return 0, err
}
elapsedDurations = append(elapsedDurations, time.Duration(p))
}
var elapsed = time.Duration(elapsedDurations[0]) * time.Second
if len(elapsedDurations) > 1 {
elapsed += time.Duration(elapsedDurations[1]) * time.Minute
}
if len(elapsedDurations) > 2 {
elapsed += time.Duration(elapsedDurations[2]) * time.Hour
}
if len(elapsedDurations) > 3 {
elapsed += time.Duration(elapsedDurations[3]) * time.Hour * 24
}
start := time.Now().Add(-elapsed)
return start.Unix() * 1000, nil
}
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
rr, err := common.CallLsofWithContext(ctx, invoke, p.Pid, "-FR")
if err != nil {
return nil, err
}
for _, r := range rr {
if strings.HasPrefix(r, "p") { // skip if process
continue
}
l := string(r)
v, err := strconv.Atoi(strings.Replace(l, "R", "", 1))
if err != nil {
return nil, err
}
return NewProcess(int32(v))
}
return nil, fmt.Errorf("could not find parent line")
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
r, err := callPsWithContext(ctx, "state", p.Pid, false)
if err != nil {
return "", err
}
return r[0][0], err
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
// See: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/ucred.h.html
userEffectiveUID := int32(k.Eproc.Ucred.UID)
return []int32{userEffectiveUID}, nil
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
gids := make([]int32, 0, 3)
gids = append(gids, int32(k.Eproc.Pcred.P_rgid), int32(k.Eproc.Ucred.Ngroups), int32(k.Eproc.Pcred.P_svgid))
return gids, nil
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
/*
k, err := p.getKProc()
if err != nil {
return "", err
}
ttyNr := uint64(k.Eproc.Tdev)
termmap, err := getTerminalMap()
if err != nil {
return "", err
}
return termmap[ttyNr], nil
*/
}
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return int32(k.Proc.P_nice), nil
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, true)
if err != nil {
return 0, err
}
return int32(len(r)), nil
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func convertCPUTimes(s string) (ret float64, err error) {
var t int
var _tmp string
if strings.Contains(s, ":") {
_t := strings.Split(s, ":")
hour, err := strconv.Atoi(_t[0])
if err != nil {
return ret, err
}
t += hour * 60 * 100
_tmp = _t[1]
} else {
_tmp = s
}
_t := strings.Split(_tmp, ".")
if err != nil {
return ret, err
}
h, err := strconv.Atoi(_t[0])
t += h * 100
h, err = strconv.Atoi(_t[1])
t += h
return float64(t) / ClockTicks, nil
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
r, err := callPsWithContext(ctx, "utime,stime", p.Pid, false)
if err != nil {
return nil, err
}
utime, err := convertCPUTimes(r[0][0])
if err != nil {
return nil, err
}
stime, err := convertCPUTimes(r[0][1])
if err != nil {
return nil, err
}
ret := &cpu.TimesStat{
CPU: "cpu",
User: utime,
System: stime,
}
return ret, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
r, err := callPsWithContext(ctx, "rss,vsize,pagein", p.Pid, false)
if err != nil {
return nil, err
}
rss, err := strconv.Atoi(r[0][0])
if err != nil {
return nil, err
}
vms, err := strconv.Atoi(r[0][1])
if err != nil {
return nil, err
}
pagein, err := strconv.Atoi(r[0][2])
if err != nil {
return nil, err
}
ret := &MemoryInfoStat{
RSS: uint64(rss) * 1024,
VMS: uint64(vms) * 1024,
Swap: uint64(pagein),
}
return ret, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return net.ConnectionsPid("all", p.Pid)
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{}
pids, err := PidsWithContext(ctx)
if err != nil {
return out, err
}
for _, pid := range pids {
p, err := NewProcess(pid)
if err != nil {
continue
}
out = append(out, p)
}
return out, nil
}
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
if err != nil {
return k, err
}
return k, nil
}
// Returns a proc as defined here:
// http://unix.superglobalmegacorp.com/Net2/newsrc/sys/kinfo_proc.h.html
func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background())
}
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
procK := KinfoProc{}
length := uint64(unsafe.Sizeof(procK))
buf := make([]byte, length)
_, _, syserr := unix.Syscall6(
unix.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])),
uintptr(len(mib)),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&length)),
0,
0)
if syserr != 0 {
return nil, syserr
}
k, err := parseKinfoProc(buf)
if err != nil {
return nil, err
}
return &k, nil
}
func NewProcess(pid int32) (*Process, error) {
p := &Process{Pid: pid}
return p, nil
}
// call ps command.
// Return value deletes Header line(you must not input wrong arg).
// And splited by Space. Caller have responsibility to manage.
// If passed arg pid is 0, get information from all process.
func callPsWithContext(ctx context.Context, arg string, pid int32, threadOption bool) ([][]string, error) {
bin, err := exec.LookPath("ps")
if err != nil {
return [][]string{}, err
}
var cmd []string
if pid == 0 { // will get from all processes.
cmd = []string{"-ax", "-o", arg}
} else if threadOption {
cmd = []string{"-x", "-o", arg, "-M", "-p", strconv.Itoa(int(pid))}
} else {
cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
}
out, err := invoke.CommandWithContext(ctx, bin, cmd...)
if err != nil {
return [][]string{}, err
}
lines := strings.Split(string(out), "\n")
var ret [][]string
for _, l := range lines[1:] {
var lr []string
for _, r := range strings.Split(l, " ") {
if r == "" {
continue
}
lr = append(lr, strings.TrimSpace(r))
}
if len(lr) != 0 {
ret = append(ret, lr)
}
}
return ret, nil
}

View File

@@ -0,0 +1,234 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_darwin.go
package process
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int32
Pad_cgo_0 [4]byte
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
type Rlimit struct {
Cur uint64
Max uint64
}
type UGid_t uint32
type KinfoProc struct {
Proc ExternProc
Eproc Eproc
}
type Eproc struct {
Paddr *uint64
Sess *Session
Pcred Upcred
Ucred Uucred
Pad_cgo_0 [4]byte
Vm Vmspace
Ppid int32
Pgid int32
Jobc int16
Pad_cgo_1 [2]byte
Tdev int32
Tpgid int32
Pad_cgo_2 [4]byte
Tsess *Session
Wmesg [8]int8
Xsize int32
Xrssize int16
Xccount int16
Xswrss int16
Pad_cgo_3 [2]byte
Flag int32
Login [12]int8
Spare [4]int32
Pad_cgo_4 [4]byte
}
type Proc struct{}
type Session struct{}
type ucred struct {
Link _Ctype_struct___0
Ref uint64
Posix Posix_cred
Label *Label
Audit Au_session
}
type Uucred struct {
Ref int32
UID uint32
Ngroups int16
Pad_cgo_0 [2]byte
Groups [16]uint32
}
type Upcred struct {
Pc_lock [72]int8
Pc_ucred *ucred
P_ruid uint32
P_svuid uint32
P_rgid uint32
P_svgid uint32
P_refcnt int32
Pad_cgo_0 [4]byte
}
type Vmspace struct {
Dummy int32
Pad_cgo_0 [4]byte
Dummy2 *int8
Dummy3 [5]int32
Pad_cgo_1 [4]byte
Dummy4 [3]*int8
}
type Sigacts struct{}
type ExternProc struct {
P_un [16]byte
P_vmspace uint64
P_sigacts uint64
Pad_cgo_0 [3]byte
P_flag int32
P_stat int8
P_pid int32
P_oppid int32
P_dupfd int32
Pad_cgo_1 [4]byte
User_stack uint64
Exit_thread uint64
P_debugger int32
Sigwait int32
P_estcpu uint32
P_cpticks int32
P_pctcpu uint32
Pad_cgo_2 [4]byte
P_wchan uint64
P_wmesg uint64
P_swtime uint32
P_slptime uint32
P_realtimer Itimerval
P_rtime Timeval
P_uticks uint64
P_sticks uint64
P_iticks uint64
P_traceflag int32
Pad_cgo_3 [4]byte
P_tracep uint64
P_siglist int32
Pad_cgo_4 [4]byte
P_textvp uint64
P_holdcnt int32
P_sigmask uint32
P_sigignore uint32
P_sigcatch uint32
P_priority uint8
P_usrpri uint8
P_nice int8
P_comm [17]int8
Pad_cgo_5 [4]byte
P_pgrp uint64
P_addr uint64
P_xstat uint16
P_acflag uint16
Pad_cgo_6 [4]byte
P_ru uint64
}
type Itimerval struct {
Interval Timeval
Value Timeval
}
type Vnode struct{}
type Pgrp struct{}
type UserStruct struct{}
type Au_session struct {
Aia_p *AuditinfoAddr
Mask AuMask
}
type Posix_cred struct {
UID uint32
Ruid uint32
Svuid uint32
Ngroups int16
Pad_cgo_0 [2]byte
Groups [16]uint32
Rgid uint32
Svgid uint32
Gmuid uint32
Flags int32
}
type Label struct{}
type AuditinfoAddr struct {
Auid uint32
Mask AuMask
Termid AuTidAddr
Asid int32
Flags uint64
}
type AuMask struct {
Success uint32
Failure uint32
}
type AuTidAddr struct {
Port int32
Type uint32
Addr [4]uint32
}
type UcredQueue struct {
Next *ucred
Prev **ucred
}

View File

@@ -0,0 +1,234 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_darwin.go
package process
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int32
Pad_cgo_0 [4]byte
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
type Rlimit struct {
Cur uint64
Max uint64
}
type UGid_t uint32
type KinfoProc struct {
Proc ExternProc
Eproc Eproc
}
type Eproc struct {
Paddr *uint64
Sess *Session
Pcred Upcred
Ucred Uucred
Pad_cgo_0 [4]byte
Vm Vmspace
Ppid int32
Pgid int32
Jobc int16
Pad_cgo_1 [2]byte
Tdev int32
Tpgid int32
Pad_cgo_2 [4]byte
Tsess *Session
Wmesg [8]int8
Xsize int32
Xrssize int16
Xccount int16
Xswrss int16
Pad_cgo_3 [2]byte
Flag int32
Login [12]int8
Spare [4]int32
Pad_cgo_4 [4]byte
}
type Proc struct{}
type Session struct{}
type ucred struct {
Link _Ctype_struct___0
Ref uint64
Posix Posix_cred
Label *Label
Audit Au_session
}
type Uucred struct {
Ref int32
UID uint32
Ngroups int16
Pad_cgo_0 [2]byte
Groups [16]uint32
}
type Upcred struct {
Pc_lock [72]int8
Pc_ucred *ucred
P_ruid uint32
P_svuid uint32
P_rgid uint32
P_svgid uint32
P_refcnt int32
Pad_cgo_0 [4]byte
}
type Vmspace struct {
Dummy int32
Pad_cgo_0 [4]byte
Dummy2 *int8
Dummy3 [5]int32
Pad_cgo_1 [4]byte
Dummy4 [3]*int8
}
type Sigacts struct{}
type ExternProc struct {
P_un [16]byte
P_vmspace uint64
P_sigacts uint64
Pad_cgo_0 [3]byte
P_flag int32
P_stat int8
P_pid int32
P_oppid int32
P_dupfd int32
Pad_cgo_1 [4]byte
User_stack uint64
Exit_thread uint64
P_debugger int32
Sigwait int32
P_estcpu uint32
P_cpticks int32
P_pctcpu uint32
Pad_cgo_2 [4]byte
P_wchan uint64
P_wmesg uint64
P_swtime uint32
P_slptime uint32
P_realtimer Itimerval
P_rtime Timeval
P_uticks uint64
P_sticks uint64
P_iticks uint64
P_traceflag int32
Pad_cgo_3 [4]byte
P_tracep uint64
P_siglist int32
Pad_cgo_4 [4]byte
P_textvp uint64
P_holdcnt int32
P_sigmask uint32
P_sigignore uint32
P_sigcatch uint32
P_priority uint8
P_usrpri uint8
P_nice int8
P_comm [17]int8
Pad_cgo_5 [4]byte
P_pgrp uint64
P_addr uint64
P_xstat uint16
P_acflag uint16
Pad_cgo_6 [4]byte
P_ru uint64
}
type Itimerval struct {
Interval Timeval
Value Timeval
}
type Vnode struct{}
type Pgrp struct{}
type UserStruct struct{}
type Au_session struct {
Aia_p *AuditinfoAddr
Mask AuMask
}
type Posix_cred struct {
UID uint32
Ruid uint32
Svuid uint32
Ngroups int16
Pad_cgo_0 [2]byte
Groups [16]uint32
Rgid uint32
Svgid uint32
Gmuid uint32
Flags int32
}
type Label struct{}
type AuditinfoAddr struct {
Auid uint32
Mask AuMask
Termid AuTidAddr
Asid int32
Flags uint64
}
type AuMask struct {
Success uint32
Failure uint32
}
type AuTidAddr struct {
Port int32
Type uint32
Addr [4]uint32
}
type UcredQueue struct {
Next *ucred
Prev **ucred
}

View File

@@ -0,0 +1,319 @@
// +build !darwin,!linux,!freebsd,!openbsd,!windows
package process
import (
"context"
"syscall"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
"github.com/shirou/gopsutil/net"
)
type MemoryMapsStat struct {
Path string `json:"path"`
Rss uint64 `json:"rss"`
Size uint64 `json:"size"`
Pss uint64 `json:"pss"`
SharedClean uint64 `json:"sharedClean"`
SharedDirty uint64 `json:"sharedDirty"`
PrivateClean uint64 `json:"privateClean"`
PrivateDirty uint64 `json:"privateDirty"`
Referenced uint64 `json:"referenced"`
Anonymous uint64 `json:"anonymous"`
Swap uint64 `json:"swap"`
}
type MemoryInfoExStat struct {
}
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return nil, common.ErrNotImplementedError
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return nil, common.ErrNotImplementedError
}
func NewProcess(pid int32) (*Process, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
return []string{}, common.ErrNotImplementedError
}
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
return []int32{}, common.ErrNotImplementedError
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return []OpenFilesStat{}, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return []net.ConnectionStat{}, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return []net.IOCountersStat{}, common.ErrNotImplementedError
}
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
return common.ErrNotImplementedError
}
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
func (p *Process) ResumeWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
func (p *Process) TerminateWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
func (p *Process) KillWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}

View File

@@ -0,0 +1,501 @@
// +build freebsd
package process
import (
"bytes"
"context"
"encoding/binary"
"os/exec"
"strconv"
"strings"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
net "github.com/shirou/gopsutil/net"
"golang.org/x/sys/unix"
)
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32
procs, err := Processes()
if err != nil {
return ret, nil
}
for _, p := range procs {
ret = append(ret, p.Pid)
}
return ret, nil
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return k.Ppid, nil
}
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
return common.IntToString(k.Comm[:]), nil
}
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return "", err
}
ret := strings.FieldsFunc(string(buf), func(r rune) bool {
if r == '\u0000' {
return true
}
return false
})
return strings.Join(ret, " "), nil
}
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
mib := []int32{CTLKern, KernProc, KernProcArgs, p.Pid}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return nil, err
}
if len(buf) == 0 {
return nil, nil
}
if buf[len(buf)-1] == 0 {
buf = buf[:len(buf)-1]
}
parts := bytes.Split(buf, []byte{0})
var strParts []string
for _, p := range parts {
strParts = append(strParts, string(p))
}
return strParts, nil
}
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return p, common.ErrNotImplementedError
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
var s string
switch k.Stat {
case SIDL:
s = "I"
case SRUN:
s = "R"
case SSLEEP:
s = "S"
case SSTOP:
s = "T"
case SZOMB:
s = "Z"
case SWAIT:
s = "W"
case SLOCK:
s = "L"
}
return s, nil
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
uids := make([]int32, 0, 3)
uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid))
return uids, nil
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
gids := make([]int32, 0, 3)
gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid))
return gids, nil
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
ttyNr := uint64(k.Tdev)
termmap, err := getTerminalMap()
if err != nil {
return "", err
}
return termmap[ttyNr], nil
}
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return int32(k.Nice), nil
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &IOCountersStat{
ReadCount: uint64(k.Rusage.Inblock),
WriteCount: uint64(k.Rusage.Oublock),
}, nil
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return k.Numthreads, nil
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &cpu.TimesStat{
CPU: "cpu",
User: float64(k.Rusage.Utime.Sec) + float64(k.Rusage.Utime.Usec)/1000000,
System: float64(k.Rusage.Stime.Sec) + float64(k.Rusage.Stime.Usec)/1000000,
}, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
v, err := unix.Sysctl("vm.stats.vm.v_page_size")
if err != nil {
return nil, err
}
pageSize := common.LittleEndian.Uint16([]byte(v))
return &MemoryInfoStat{
RSS: uint64(k.Rssize) * uint64(pageSize),
VMS: uint64(k.Size),
}, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
results := []*Process{}
mib := []int32{CTLKern, KernProc, KernProcProc, 0}
buf, length, err := common.CallSyscall(mib)
if err != nil {
return results, err
}
// get kinfo_proc size
count := int(length / uint64(sizeOfKinfoProc))
// parse buf to procs
for i := 0; i < count; i++ {
b := buf[i*sizeOfKinfoProc : (i+1)*sizeOfKinfoProc]
k, err := parseKinfoProc(b)
if err != nil {
continue
}
p, err := NewProcess(int32(k.Pid))
if err != nil {
continue
}
results = append(results, p)
}
return results, nil
}
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
return k, err
}
func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background())
}
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
mib := []int32{CTLKern, KernProc, KernProcPID, p.Pid}
buf, length, err := common.CallSyscall(mib)
if err != nil {
return nil, err
}
if length != sizeOfKinfoProc {
return nil, err
}
k, err := parseKinfoProc(buf)
if err != nil {
return nil, err
}
return &k, nil
}
func NewProcess(pid int32) (*Process, error) {
p := &Process{Pid: pid}
return p, nil
}

View File

@@ -0,0 +1,192 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package process
const (
CTLKern = 1
KernProc = 14
KernProcPID = 1
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 7
)
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
)
const (
sizeOfKinfoVmentry = 0x488
sizeOfKinfoProc = 0x300
)
const (
SIDL = 1
SRUN = 2
SSLEEP = 3
SSTOP = 4
SZOMB = 5
SWAIT = 6
SLOCK = 7
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type Timespec struct {
Sec int32
Nsec int32
}
type Timeval struct {
Sec int32
Usec int32
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int32
Ixrss int32
Idrss int32
Isrss int32
Minflt int32
Majflt int32
Nswap int32
Inblock int32
Oublock int32
Msgsnd int32
Msgrcv int32
Nsignals int32
Nvcsw int32
Nivcsw int32
}
type Rlimit struct {
Cur int64
Max int64
}
type KinfoProc struct {
Structsize int32
Layout int32
Args int32 /* pargs */
Paddr int32 /* proc */
Addr int32 /* user */
Tracep int32 /* vnode */
Textvp int32 /* vnode */
Fd int32 /* filedesc */
Vmspace int32 /* vmspace */
Wchan int32
Pid int32
Ppid int32
Pgid int32
Tpgid int32
Sid int32
Tsid int32
Jobc int16
Spare_short1 int16
Tdev uint32
Siglist [16]byte /* sigset */
Sigmask [16]byte /* sigset */
Sigignore [16]byte /* sigset */
Sigcatch [16]byte /* sigset */
Uid uint32
Ruid uint32
Svuid uint32
Rgid uint32
Svgid uint32
Ngroups int16
Spare_short2 int16
Groups [16]uint32
Size uint32
Rssize int32
Swrss int32
Tsize int32
Dsize int32
Ssize int32
Xstat uint16
Acflag uint16
Pctcpu uint32
Estcpu uint32
Slptime uint32
Swtime uint32
Cow uint32
Runtime uint64
Start Timeval
Childtime Timeval
Flag int32
Kiflag int32
Traceflag int32
Stat int8
Nice int8
Lock int8
Rqindex int8
Oncpu uint8
Lastcpu uint8
Tdname [17]int8
Wmesg [9]int8
Login [18]int8
Lockname [9]int8
Comm [20]int8
Emul [17]int8
Loginclass [18]int8
Sparestrings [50]int8
Spareints [7]int32
Flag2 int32
Fibnum int32
Cr_flags uint32
Jid int32
Numthreads int32
Tid int32
Pri Priority
Rusage Rusage
Rusage_ch Rusage
Pcb int32 /* pcb */
Kstack int32
Udata int32
Tdaddr int32 /* thread */
Spareptrs [6]int32
Sparelongs [12]int32
Sflag int32
Tdflags int32
}
type Priority struct {
Class uint8
Level uint8
Native uint8
User uint8
}
type KinfoVmentry struct {
Structsize int32
Type int32
Start uint64
End uint64
Offset uint64
Vn_fileid uint64
Vn_fsid uint32
Flags int32
Resident int32
Private_resident int32
Protection int32
Ref_count int32
Shadow_count int32
Vn_type int32
Vn_size uint64
Vn_rdev uint32
Vn_mode uint16
Status uint16
X_kve_ispare [12]int32
Path [1024]int8
}

View File

@@ -0,0 +1,192 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package process
const (
CTLKern = 1
KernProc = 14
KernProcPID = 1
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 7
)
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
)
const (
sizeOfKinfoVmentry = 0x488
sizeOfKinfoProc = 0x440
)
const (
SIDL = 1
SRUN = 2
SSLEEP = 3
SSTOP = 4
SZOMB = 5
SWAIT = 6
SLOCK = 7
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int64
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
type Rlimit struct {
Cur int64
Max int64
}
type KinfoProc struct {
Structsize int32
Layout int32
Args int64 /* pargs */
Paddr int64 /* proc */
Addr int64 /* user */
Tracep int64 /* vnode */
Textvp int64 /* vnode */
Fd int64 /* filedesc */
Vmspace int64 /* vmspace */
Wchan int64
Pid int32
Ppid int32
Pgid int32
Tpgid int32
Sid int32
Tsid int32
Jobc int16
Spare_short1 int16
Tdev uint32
Siglist [16]byte /* sigset */
Sigmask [16]byte /* sigset */
Sigignore [16]byte /* sigset */
Sigcatch [16]byte /* sigset */
Uid uint32
Ruid uint32
Svuid uint32
Rgid uint32
Svgid uint32
Ngroups int16
Spare_short2 int16
Groups [16]uint32
Size uint64
Rssize int64
Swrss int64
Tsize int64
Dsize int64
Ssize int64
Xstat uint16
Acflag uint16
Pctcpu uint32
Estcpu uint32
Slptime uint32
Swtime uint32
Cow uint32
Runtime uint64
Start Timeval
Childtime Timeval
Flag int64
Kiflag int64
Traceflag int32
Stat int8
Nice int8
Lock int8
Rqindex int8
Oncpu uint8
Lastcpu uint8
Tdname [17]int8
Wmesg [9]int8
Login [18]int8
Lockname [9]int8
Comm [20]int8
Emul [17]int8
Loginclass [18]int8
Sparestrings [50]int8
Spareints [7]int32
Flag2 int32
Fibnum int32
Cr_flags uint32
Jid int32
Numthreads int32
Tid int32
Pri Priority
Rusage Rusage
Rusage_ch Rusage
Pcb int64 /* pcb */
Kstack int64
Udata int64
Tdaddr int64 /* thread */
Spareptrs [6]int64
Sparelongs [12]int64
Sflag int64
Tdflags int64
}
type Priority struct {
Class uint8
Level uint8
Native uint8
User uint8
}
type KinfoVmentry struct {
Structsize int32
Type int32
Start uint64
End uint64
Offset uint64
Vn_fileid uint64
Vn_fsid uint32
Flags int32
Resident int32
Private_resident int32
Protection int32
Ref_count int32
Shadow_count int32
Vn_type int32
Vn_size uint64
Vn_rdev uint32
Vn_mode uint16
Status uint16
X_kve_ispare [12]int32
Path [1024]int8
}

View File

@@ -0,0 +1,192 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_freebsd.go
package process
const (
CTLKern = 1
KernProc = 14
KernProcPID = 1
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 7
)
const (
sizeofPtr = 0x4
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x4
sizeofLongLong = 0x8
)
const (
sizeOfKinfoVmentry = 0x488
sizeOfKinfoProc = 0x440
)
const (
SIDL = 1
SRUN = 2
SSLEEP = 3
SSTOP = 4
SZOMB = 5
SWAIT = 6
SLOCK = 7
)
type (
_C_short int16
_C_int int32
_C_long int32
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int64
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int32
Ixrss int32
Idrss int32
Isrss int32
Minflt int32
Majflt int32
Nswap int32
Inblock int32
Oublock int32
Msgsnd int32
Msgrcv int32
Nsignals int32
Nvcsw int32
Nivcsw int32
}
type Rlimit struct {
Cur int32
Max int32
}
type KinfoProc struct {
Structsize int32
Layout int32
Args int32 /* pargs */
Paddr int32 /* proc */
Addr int32 /* user */
Tracep int32 /* vnode */
Textvp int32 /* vnode */
Fd int32 /* filedesc */
Vmspace int32 /* vmspace */
Wchan int32
Pid int32
Ppid int32
Pgid int32
Tpgid int32
Sid int32
Tsid int32
Jobc int16
Spare_short1 int16
Tdev uint32
Siglist [16]byte /* sigset */
Sigmask [16]byte /* sigset */
Sigignore [16]byte /* sigset */
Sigcatch [16]byte /* sigset */
Uid uint32
Ruid uint32
Svuid uint32
Rgid uint32
Svgid uint32
Ngroups int16
Spare_short2 int16
Groups [16]uint32
Size uint32
Rssize int32
Swrss int32
Tsize int32
Dsize int32
Ssize int32
Xstat uint16
Acflag uint16
Pctcpu uint32
Estcpu uint32
Slptime uint32
Swtime uint32
Cow uint32
Runtime uint64
Start Timeval
Childtime Timeval
Flag int32
Kiflag int32
Traceflag int32
Stat int8
Nice int8
Lock int8
Rqindex int8
Oncpu uint8
Lastcpu uint8
Tdname [17]int8
Wmesg [9]int8
Login [18]int8
Lockname [9]int8
Comm [20]int8
Emul [17]int8
Loginclass [18]int8
Sparestrings [50]int8
Spareints [4]int32
Flag2 int32
Fibnum int32
Cr_flags uint32
Jid int32
Numthreads int32
Tid int32
Pri Priority
Rusage Rusage
Rusage_ch Rusage
Pcb int32 /* pcb */
Kstack int32
Udata int32
Tdaddr int32 /* thread */
Spareptrs [6]int64
Sparelongs [12]int64
Sflag int64
Tdflags int64
}
type Priority struct {
Class uint8
Level uint8
Native uint8
User uint8
}
type KinfoVmentry struct {
Structsize int32
Type int32
Start uint64
End uint64
Offset uint64
Vn_fileid uint64
Vn_fsid uint32
Flags int32
Resident int32
Private_resident int32
Protection int32
Ref_count int32
Shadow_count int32
Vn_type int32
Vn_size uint64
Vn_rdev uint32
Vn_mode uint16
Status uint16
X_kve_ispare [12]int32
Path [1024]int8
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,527 @@
// +build openbsd
package process
import (
"C"
"bytes"
"context"
"encoding/binary"
"strings"
"unsafe"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
mem "github.com/shirou/gopsutil/mem"
net "github.com/shirou/gopsutil/net"
"golang.org/x/sys/unix"
)
// MemoryInfoExStat is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
var ret []int32
procs, err := Processes()
if err != nil {
return ret, nil
}
for _, p := range procs {
ret = append(ret, p.Pid)
}
return ret, nil
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return k.Ppid, nil
}
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
return common.IntToString(k.Comm[:]), nil
}
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
mib := []int32{CTLKern, KernProcArgs, p.Pid, KernProcArgv}
buf, _, err := common.CallSyscall(mib)
if err != nil {
return nil, err
}
argc := 0
argvp := unsafe.Pointer(&buf[0])
argv := *(**C.char)(unsafe.Pointer(argvp))
size := unsafe.Sizeof(argv)
var strParts []string
for argv != nil {
strParts = append(strParts, C.GoString(argv))
argc++
argv = *(**C.char)(unsafe.Pointer(uintptr(argvp) + uintptr(argc)*size))
}
return strParts, nil
}
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
argv, err := p.CmdlineSlice()
if err != nil {
return "", err
}
return strings.Join(argv, " "), nil
}
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
return p, common.ErrNotImplementedError
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
var s string
switch k.Stat {
case SIDL:
case SRUN:
case SONPROC:
s = "R"
case SSLEEP:
s = "S"
case SSTOP:
s = "T"
case SDEAD:
s = "Z"
}
return s, nil
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
pid := p.Pid
ps, err := exec.LookPath("ps")
if err != nil {
return false, err
}
out, err := invoke.CommandWithContext(ctx, ps, "-o", "stat=", "-p", strconv.Itoa(int(pid)))
if err != nil {
return false, err
}
return strings.IndexByte(string(out), '+') != -1, nil
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
uids := make([]int32, 0, 3)
uids = append(uids, int32(k.Ruid), int32(k.Uid), int32(k.Svuid))
return uids, nil
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
gids := make([]int32, 0, 3)
gids = append(gids, int32(k.Rgid), int32(k.Ngroups), int32(k.Svgid))
return gids, nil
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
k, err := p.getKProc()
if err != nil {
return "", err
}
ttyNr := uint64(k.Tdev)
termmap, err := getTerminalMap()
if err != nil {
return "", err
}
return termmap[ttyNr], nil
}
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
k, err := p.getKProc()
if err != nil {
return 0, err
}
return int32(k.Nice), nil
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &IOCountersStat{
ReadCount: uint64(k.Uru_inblock),
WriteCount: uint64(k.Uru_oublock),
}, nil
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
/* not supported, just return 1 */
return 1, nil
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
return &cpu.TimesStat{
CPU: "cpu",
User: float64(k.Uutime_sec) + float64(k.Uutime_usec)/1000000,
System: float64(k.Ustime_sec) + float64(k.Ustime_usec)/1000000,
}, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
k, err := p.getKProc()
if err != nil {
return nil, err
}
pageSize, err := mem.GetPageSize()
if err != nil {
return nil, err
}
return &MemoryInfoStat{
RSS: uint64(k.Vm_rssize) * pageSize,
VMS: uint64(k.Vm_tsize) + uint64(k.Vm_dsize) +
uint64(k.Vm_ssize),
}, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
pids, err := common.CallPgrepWithContext(ctx, invoke, p.Pid)
if err != nil {
return nil, err
}
ret := make([]*Process, 0, len(pids))
for _, pid := range pids {
np, err := NewProcess(pid)
if err != nil {
return nil, err
}
ret = append(ret, np)
}
return ret, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
results := []*Process{}
buf, length, err := CallKernProcSyscall(KernProcAll, 0)
if err != nil {
return results, err
}
// get kinfo_proc size
count := int(length / uint64(sizeOfKinfoProc))
// parse buf to procs
for i := 0; i < count; i++ {
b := buf[i*sizeOfKinfoProc : (i+1)*sizeOfKinfoProc]
k, err := parseKinfoProc(b)
if err != nil {
continue
}
p, err := NewProcess(int32(k.Pid))
if err != nil {
continue
}
results = append(results, p)
}
return results, nil
}
func parseKinfoProc(buf []byte) (KinfoProc, error) {
var k KinfoProc
br := bytes.NewReader(buf)
err := common.Read(br, binary.LittleEndian, &k)
return k, err
}
func (p *Process) getKProc() (*KinfoProc, error) {
return p.getKProcWithContext(context.Background())
}
func (p *Process) getKProcWithContext(ctx context.Context) (*KinfoProc, error) {
buf, length, err := CallKernProcSyscall(KernProcPID, p.Pid)
if err != nil {
return nil, err
}
if length != sizeOfKinfoProc {
return nil, err
}
k, err := parseKinfoProc(buf)
if err != nil {
return nil, err
}
return &k, nil
}
func NewProcess(pid int32) (*Process, error) {
p := &Process{Pid: pid}
return p, nil
}
func CallKernProcSyscall(op int32, arg int32) ([]byte, uint64, error) {
return CallKernProcSyscallWithContext(context.Background(), op, arg)
}
func CallKernProcSyscallWithContext(ctx context.Context, op int32, arg int32) ([]byte, uint64, error) {
mib := []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, 0}
mibptr := unsafe.Pointer(&mib[0])
miblen := uint64(len(mib))
length := uint64(0)
_, _, err := unix.Syscall6(
unix.SYS___SYSCTL,
uintptr(mibptr),
uintptr(miblen),
0,
uintptr(unsafe.Pointer(&length)),
0,
0)
if err != 0 {
return nil, length, err
}
count := int32(length / uint64(sizeOfKinfoProc))
mib = []int32{CTLKern, KernProc, op, arg, sizeOfKinfoProc, count}
mibptr = unsafe.Pointer(&mib[0])
miblen = uint64(len(mib))
// get proc info itself
buf := make([]byte, length)
_, _, err = unix.Syscall6(
unix.SYS___SYSCTL,
uintptr(mibptr),
uintptr(miblen),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&length)),
0,
0)
if err != 0 {
return buf, length, err
}
return buf, length, nil
}

View File

@@ -0,0 +1,200 @@
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_openbsd.go
package process
const (
CTLKern = 1
KernProc = 66
KernProcAll = 0
KernProcPID = 1
KernProcProc = 8
KernProcPathname = 12
KernProcArgs = 55
KernProcArgv = 1
KernProcEnv = 3
)
const (
ArgMax = 256 * 1024
)
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
)
const (
sizeOfKinfoVmentry = 0x50
sizeOfKinfoProc = 0x268
)
const (
SIDL = 1
SRUN = 2
SSLEEP = 3
SSTOP = 4
SZOMB = 5
SDEAD = 6
SONPROC = 7
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int64
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
type Rlimit struct {
Cur uint64
Max uint64
}
type KinfoProc struct {
Forw uint64
Back uint64
Paddr uint64
Addr uint64
Fd uint64
Stats uint64
Limit uint64
Vmspace uint64
Sigacts uint64
Sess uint64
Tsess uint64
Ru uint64
Eflag int32
Exitsig int32
Flag int32
Pid int32
Ppid int32
Sid int32
X_pgid int32
Tpgid int32
Uid uint32
Ruid uint32
Gid uint32
Rgid uint32
Groups [16]uint32
Ngroups int16
Jobc int16
Tdev uint32
Estcpu uint32
Rtime_sec uint32
Rtime_usec uint32
Cpticks int32
Pctcpu uint32
Swtime uint32
Slptime uint32
Schedflags int32
Uticks uint64
Sticks uint64
Iticks uint64
Tracep uint64
Traceflag int32
Holdcnt int32
Siglist int32
Sigmask uint32
Sigignore uint32
Sigcatch uint32
Stat int8
Priority uint8
Usrpri uint8
Nice uint8
Xstat uint16
Acflag uint16
Comm [24]int8
Wmesg [8]int8
Wchan uint64
Login [32]int8
Vm_rssize int32
Vm_tsize int32
Vm_dsize int32
Vm_ssize int32
Uvalid int64
Ustart_sec uint64
Ustart_usec uint32
Uutime_sec uint32
Uutime_usec uint32
Ustime_sec uint32
Ustime_usec uint32
Pad_cgo_0 [4]byte
Uru_maxrss uint64
Uru_ixrss uint64
Uru_idrss uint64
Uru_isrss uint64
Uru_minflt uint64
Uru_majflt uint64
Uru_nswap uint64
Uru_inblock uint64
Uru_oublock uint64
Uru_msgsnd uint64
Uru_msgrcv uint64
Uru_nsignals uint64
Uru_nvcsw uint64
Uru_nivcsw uint64
Uctime_sec uint32
Uctime_usec uint32
Psflags int32
Spare int32
Svuid uint32
Svgid uint32
Emul [8]int8
Rlim_rss_cur uint64
Cpuid uint64
Vm_map_size uint64
Tid int32
Rtableid uint32
}
type Priority struct{}
type KinfoVmentry struct {
Start uint64
End uint64
Guard uint64
Fspace uint64
Fspace_augment uint64
Offset uint64
Wired_count int32
Etype int32
Protection int32
Max_protection int32
Advice int32
Inheritance int32
Flags uint8
Pad_cgo_0 [7]byte
}

View File

@@ -0,0 +1,146 @@
// +build linux freebsd openbsd darwin
package process
import (
"context"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"syscall"
"golang.org/x/sys/unix"
)
// POSIX
func getTerminalMap() (map[uint64]string, error) {
ret := make(map[uint64]string)
var termfiles []string
d, err := os.Open("/dev")
if err != nil {
return nil, err
}
defer d.Close()
devnames, err := d.Readdirnames(-1)
if err != nil {
return nil, err
}
for _, devname := range devnames {
if strings.HasPrefix(devname, "/dev/tty") {
termfiles = append(termfiles, "/dev/tty/"+devname)
}
}
var ptsnames []string
ptsd, err := os.Open("/dev/pts")
if err != nil {
ptsnames, _ = filepath.Glob("/dev/ttyp*")
if ptsnames == nil {
return nil, err
}
}
defer ptsd.Close()
if ptsnames == nil {
defer ptsd.Close()
ptsnames, err = ptsd.Readdirnames(-1)
if err != nil {
return nil, err
}
for _, ptsname := range ptsnames {
termfiles = append(termfiles, "/dev/pts/"+ptsname)
}
} else {
termfiles = ptsnames
}
for _, name := range termfiles {
stat := unix.Stat_t{}
if err = unix.Stat(name, &stat); err != nil {
return nil, err
}
rdev := uint64(stat.Rdev)
ret[rdev] = strings.Replace(name, "/dev", "", -1)
}
return ret, nil
}
// SendSignal sends a unix.Signal to the process.
// Currently, SIGSTOP, SIGCONT, SIGTERM and SIGKILL are supported.
func (p *Process) SendSignal(sig syscall.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig syscall.Signal) error {
process, err := os.FindProcess(int(p.Pid))
if err != nil {
return err
}
err = process.Signal(sig)
if err != nil {
return err
}
return nil
}
// Suspend sends SIGSTOP to the process.
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGSTOP)
}
// Resume sends SIGCONT to the process.
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
func (p *Process) ResumeWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGCONT)
}
// Terminate sends SIGTERM to the process.
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
func (p *Process) TerminateWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGTERM)
}
// Kill sends SIGKILL to the process.
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
func (p *Process) KillWithContext(ctx context.Context) error {
return p.SendSignal(unix.SIGKILL)
}
// Username returns a username of the process.
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
uids, err := p.Uids()
if err != nil {
return "", err
}
if len(uids) > 0 {
u, err := user.LookupId(strconv.Itoa(int(uids[0])))
if err != nil {
return "", err
}
return u.Username, nil
}
return "", nil
}

View File

@@ -0,0 +1,801 @@
// +build windows
package process
import (
"context"
"fmt"
"os"
"strings"
"syscall"
"time"
"unsafe"
"github.com/StackExchange/wmi"
cpu "github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/internal/common"
net "github.com/shirou/gopsutil/net"
"github.com/shirou/w32"
"golang.org/x/sys/windows"
)
const (
NoMoreFiles = 0x12
MaxPathLength = 260
)
var (
modpsapi = windows.NewLazySystemDLL("psapi.dll")
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
advapi32 = windows.NewLazySystemDLL("advapi32.dll")
procLookupPrivilegeValue = advapi32.NewProc("LookupPrivilegeValueW")
procAdjustTokenPrivileges = advapi32.NewProc("AdjustTokenPrivileges")
)
type SystemProcessInformation struct {
NextEntryOffset uint64
NumberOfThreads uint64
Reserved1 [48]byte
Reserved2 [3]byte
UniqueProcessID uintptr
Reserved3 uintptr
HandleCount uint64
Reserved4 [4]byte
Reserved5 [11]byte
PeakPagefileUsage uint64
PrivatePageCount uint64
Reserved6 [6]uint64
}
// Memory_info_ex is different between OSes
type MemoryInfoExStat struct {
}
type MemoryMapsStat struct {
}
type Win32_Process struct {
Name string
ExecutablePath *string
CommandLine *string
Priority uint32
CreationDate *time.Time
ProcessID uint32
ThreadCount uint32
Status *string
ReadOperationCount uint64
ReadTransferCount uint64
WriteOperationCount uint64
WriteTransferCount uint64
CSCreationClassName string
CSName string
Caption *string
CreationClassName string
Description *string
ExecutionState *uint16
HandleCount uint32
KernelModeTime uint64
MaximumWorkingSetSize *uint32
MinimumWorkingSetSize *uint32
OSCreationClassName string
OSName string
OtherOperationCount uint64
OtherTransferCount uint64
PageFaults uint32
PageFileUsage uint32
ParentProcessID uint32
PeakPageFileUsage uint32
PeakVirtualSize uint64
PeakWorkingSetSize uint32
PrivatePageCount uint64
TerminationDate *time.Time
UserModeTime uint64
WorkingSetSize uint64
}
type winLUID struct {
LowPart winDWord
HighPart winLong
}
// LUID_AND_ATTRIBUTES
type winLUIDAndAttributes struct {
Luid winLUID
Attributes winDWord
}
// TOKEN_PRIVILEGES
type winTokenPriviledges struct {
PrivilegeCount winDWord
Privileges [1]winLUIDAndAttributes
}
type winLong int32
type winDWord uint32
func init() {
wmi.DefaultClient.AllowMissingFields = true
// enable SeDebugPrivilege https://github.com/midstar/proci/blob/6ec79f57b90ba3d9efa2a7b16ef9c9369d4be875/proci_windows.go#L80-L119
handle, err := syscall.GetCurrentProcess()
if err != nil {
return
}
var token syscall.Token
err = syscall.OpenProcessToken(handle, 0x0028, &token)
if err != nil {
return
}
defer token.Close()
tokenPriviledges := winTokenPriviledges{PrivilegeCount: 1}
lpName := syscall.StringToUTF16("SeDebugPrivilege")
ret, _, _ := procLookupPrivilegeValue.Call(
0,
uintptr(unsafe.Pointer(&lpName[0])),
uintptr(unsafe.Pointer(&tokenPriviledges.Privileges[0].Luid)))
if ret == 0 {
return
}
tokenPriviledges.Privileges[0].Attributes = 0x00000002 // SE_PRIVILEGE_ENABLED
procAdjustTokenPrivileges.Call(
uintptr(token),
0,
uintptr(unsafe.Pointer(&tokenPriviledges)),
uintptr(unsafe.Sizeof(tokenPriviledges)),
0,
0)
}
func Pids() ([]int32, error) {
return PidsWithContext(context.Background())
}
func PidsWithContext(ctx context.Context) ([]int32, error) {
// inspired by https://gist.github.com/henkman/3083408
// and https://github.com/giampaolo/psutil/blob/1c3a15f637521ba5c0031283da39c733fda53e4c/psutil/arch/windows/process_info.c#L315-L329
var ret []int32
var read uint32 = 0
var psSize uint32 = 1024
const dwordSize uint32 = 4
for {
ps := make([]uint32, psSize)
if !w32.EnumProcesses(ps, uint32(len(ps)), &read) {
return nil, fmt.Errorf("could not get w32.EnumProcesses")
}
if uint32(len(ps)) == read { // ps buffer was too small to host every results, retry with a bigger one
psSize += 1024
continue
}
for _, pid := range ps[:read/dwordSize] {
ret = append(ret, int32(pid))
}
return ret, nil
}
}
func (p *Process) Ppid() (int32, error) {
return p.PpidWithContext(context.Background())
}
func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
ppid, _, _, err := getFromSnapProcess(p.Pid)
if err != nil {
return 0, err
}
return ppid, nil
}
func GetWin32Proc(pid int32) ([]Win32_Process, error) {
return GetWin32ProcWithContext(context.Background(), pid)
}
func GetWin32ProcWithContext(ctx context.Context, pid int32) ([]Win32_Process, error) {
var dst []Win32_Process
query := fmt.Sprintf("WHERE ProcessId = %d", pid)
q := wmi.CreateQuery(&dst, query)
err := common.WMIQueryWithContext(ctx, q, &dst)
if err != nil {
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: %s", err)
}
if len(dst) == 0 {
return []Win32_Process{}, fmt.Errorf("could not get win32Proc: empty")
}
return dst, nil
}
func (p *Process) Name() (string, error) {
return p.NameWithContext(context.Background())
}
func (p *Process) NameWithContext(ctx context.Context) (string, error) {
_, _, name, err := getFromSnapProcess(p.Pid)
if err != nil {
return "", fmt.Errorf("could not get Name: %s", err)
}
return name, nil
}
func (p *Process) Tgid() (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Exe() (string, error) {
return p.ExeWithContext(context.Background())
}
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
if p.Pid != 0 { // 0 or null is the current process for CreateToolhelp32Snapshot
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPMODULE|w32.TH32CS_SNAPMODULE32, uint32(p.Pid))
if snap != 0 { // don't report errors here, fallback to WMI instead
defer w32.CloseHandle(snap)
var me32 w32.MODULEENTRY32
me32.Size = uint32(unsafe.Sizeof(me32))
if w32.Module32First(snap, &me32) {
szexepath := windows.UTF16ToString(me32.SzExePath[:])
return szexepath, nil
}
}
}
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
if err != nil {
return "", fmt.Errorf("could not get ExecutablePath: %s", err)
}
return *dst[0].ExecutablePath, nil
}
func (p *Process) Cmdline() (string, error) {
return p.CmdlineWithContext(context.Background())
}
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
if err != nil {
return "", fmt.Errorf("could not get CommandLine: %s", err)
}
return *dst[0].CommandLine, nil
}
// CmdlineSlice returns the command line arguments of the process as a slice with each
// element being an argument. This merely returns the CommandLine informations passed
// to the process split on the 0x20 ASCII character.
func (p *Process) CmdlineSlice() ([]string, error) {
return p.CmdlineSliceWithContext(context.Background())
}
func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
cmdline, err := p.CmdlineWithContext(ctx)
if err != nil {
return nil, err
}
return strings.Split(cmdline, " "), nil
}
func (p *Process) CreateTime() (int64, error) {
return p.CreateTimeWithContext(context.Background())
}
func (p *Process) CreateTimeWithContext(ctx context.Context) (int64, error) {
ru, err := getRusage(p.Pid)
if err != nil {
return 0, fmt.Errorf("could not get CreationDate: %s", err)
}
return ru.CreationTime.Nanoseconds() / 1000000, nil
}
func (p *Process) Cwd() (string, error) {
return p.CwdWithContext(context.Background())
}
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Parent() (*Process, error) {
return p.ParentWithContext(context.Background())
}
func (p *Process) ParentWithContext(ctx context.Context) (*Process, error) {
ppid, err := p.PpidWithContext(ctx)
if err != nil {
return nil, fmt.Errorf("could not get ParentProcessID: %s", err)
}
return NewProcess(ppid)
}
func (p *Process) Status() (string, error) {
return p.StatusWithContext(context.Background())
}
func (p *Process) StatusWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
func (p *Process) Foreground() (bool, error) {
return p.ForegroundWithContext(context.Background())
}
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
return false, common.ErrNotImplementedError
}
func (p *Process) Username() (string, error) {
return p.UsernameWithContext(context.Background())
}
func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
pid := p.Pid
// 0x1000 is PROCESS_QUERY_LIMITED_INFORMATION
c, err := syscall.OpenProcess(0x1000, false, uint32(pid))
if err != nil {
return "", err
}
defer syscall.CloseHandle(c)
var token syscall.Token
err = syscall.OpenProcessToken(c, syscall.TOKEN_QUERY, &token)
if err != nil {
return "", err
}
defer token.Close()
tokenUser, err := token.GetTokenUser()
if err != nil {
return "", err
}
user, domain, _, err := tokenUser.User.Sid.LookupAccount("")
return domain + "\\" + user, err
}
func (p *Process) Uids() ([]int32, error) {
return p.UidsWithContext(context.Background())
}
func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
var uids []int32
return uids, common.ErrNotImplementedError
}
func (p *Process) Gids() ([]int32, error) {
return p.GidsWithContext(context.Background())
}
func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
var gids []int32
return gids, common.ErrNotImplementedError
}
func (p *Process) Terminal() (string, error) {
return p.TerminalWithContext(context.Background())
}
func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
// Nice returns priority in Windows
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
if err != nil {
return 0, fmt.Errorf("could not get Priority: %s", err)
}
return int32(dst[0].Priority), nil
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())
}
func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) Rlimit() ([]RlimitStat, error) {
return p.RlimitWithContext(context.Background())
}
func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) RlimitUsage(gatherUsed bool) ([]RlimitStat, error) {
return p.RlimitUsageWithContext(context.Background(), gatherUsed)
}
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
var rlimit []RlimitStat
return rlimit, common.ErrNotImplementedError
}
func (p *Process) IOCounters() (*IOCountersStat, error) {
return p.IOCountersWithContext(context.Background())
}
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
if err != nil || len(dst) == 0 {
return nil, fmt.Errorf("could not get Win32Proc: %s", err)
}
ret := &IOCountersStat{
ReadCount: uint64(dst[0].ReadOperationCount),
ReadBytes: uint64(dst[0].ReadTransferCount),
WriteCount: uint64(dst[0].WriteOperationCount),
WriteBytes: uint64(dst[0].WriteTransferCount),
}
return ret, nil
}
func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) {
return p.NumCtxSwitchesWithContext(context.Background())
}
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NumFDs() (int32, error) {
return p.NumFDsWithContext(context.Background())
}
func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
return 0, common.ErrNotImplementedError
}
func (p *Process) NumThreads() (int32, error) {
return p.NumThreadsWithContext(context.Background())
}
func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
if err != nil {
return 0, fmt.Errorf("could not get ThreadCount: %s", err)
}
return int32(dst[0].ThreadCount), nil
}
func (p *Process) Threads() (map[int32]*cpu.TimesStat, error) {
return p.ThreadsWithContext(context.Background())
}
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
ret := make(map[int32]*cpu.TimesStat)
return ret, common.ErrNotImplementedError
}
func (p *Process) Times() (*cpu.TimesStat, error) {
return p.TimesWithContext(context.Background())
}
func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
sysTimes, err := getProcessCPUTimes(p.Pid)
if err != nil {
return nil, err
}
// User and kernel times are represented as a FILETIME structure
// which contains a 64-bit value representing the number of
// 100-nanosecond intervals since January 1, 1601 (UTC):
// http://msdn.microsoft.com/en-us/library/ms724284(VS.85).aspx
// To convert it into a float representing the seconds that the
// process has executed in user/kernel mode I borrowed the code
// below from psutil's _psutil_windows.c, and in turn from Python's
// Modules/posixmodule.c
user := float64(sysTimes.UserTime.HighDateTime)*429.4967296 + float64(sysTimes.UserTime.LowDateTime)*1e-7
kernel := float64(sysTimes.KernelTime.HighDateTime)*429.4967296 + float64(sysTimes.KernelTime.LowDateTime)*1e-7
return &cpu.TimesStat{
User: user,
System: kernel,
}, nil
}
func (p *Process) CPUAffinity() ([]int32, error) {
return p.CPUAffinityWithContext(context.Background())
}
func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) MemoryInfo() (*MemoryInfoStat, error) {
return p.MemoryInfoWithContext(context.Background())
}
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
mem, err := getMemoryInfo(p.Pid)
if err != nil {
return nil, err
}
ret := &MemoryInfoStat{
RSS: uint64(mem.WorkingSetSize),
VMS: uint64(mem.PagefileUsage),
}
return ret, nil
}
func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) {
return p.MemoryInfoExWithContext(context.Background())
}
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Children() ([]*Process, error) {
return p.ChildrenWithContext(context.Background())
}
func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{}
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(0))
if snap == 0 {
return out, windows.GetLastError()
}
defer w32.CloseHandle(snap)
var pe32 w32.PROCESSENTRY32
pe32.DwSize = uint32(unsafe.Sizeof(pe32))
if w32.Process32First(snap, &pe32) == false {
return out, windows.GetLastError()
}
if pe32.Th32ParentProcessID == uint32(p.Pid) {
p, err := NewProcess(int32(pe32.Th32ProcessID))
if err == nil {
out = append(out, p)
}
}
for w32.Process32Next(snap, &pe32) {
if pe32.Th32ParentProcessID == uint32(p.Pid) {
p, err := NewProcess(int32(pe32.Th32ProcessID))
if err == nil {
out = append(out, p)
}
}
}
return out, nil
}
func (p *Process) OpenFiles() ([]OpenFilesStat, error) {
return p.OpenFilesWithContext(context.Background())
}
func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) Connections() ([]net.ConnectionStat, error) {
return p.ConnectionsWithContext(context.Background())
}
func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) NetIOCounters(pernic bool) ([]net.IOCountersStat, error) {
return p.NetIOCountersWithContext(context.Background(), pernic)
}
func (p *Process) NetIOCountersWithContext(ctx context.Context, pernic bool) ([]net.IOCountersStat, error) {
return nil, common.ErrNotImplementedError
}
func (p *Process) IsRunning() (bool, error) {
return p.IsRunningWithContext(context.Background())
}
func (p *Process) IsRunningWithContext(ctx context.Context) (bool, error) {
return true, common.ErrNotImplementedError
}
func (p *Process) MemoryMaps(grouped bool) (*[]MemoryMapsStat, error) {
return p.MemoryMapsWithContext(context.Background(), grouped)
}
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
var ret []MemoryMapsStat
return &ret, common.ErrNotImplementedError
}
func NewProcess(pid int32) (*Process, error) {
p := &Process{Pid: pid}
return p, nil
}
func (p *Process) SendSignal(sig windows.Signal) error {
return p.SendSignalWithContext(context.Background(), sig)
}
func (p *Process) SendSignalWithContext(ctx context.Context, sig windows.Signal) error {
return common.ErrNotImplementedError
}
func (p *Process) Suspend() error {
return p.SuspendWithContext(context.Background())
}
func (p *Process) SuspendWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Resume() error {
return p.ResumeWithContext(context.Background())
}
func (p *Process) ResumeWithContext(ctx context.Context) error {
return common.ErrNotImplementedError
}
func (p *Process) Terminate() error {
return p.TerminateWithContext(context.Background())
}
func (p *Process) TerminateWithContext(ctx context.Context) error {
// PROCESS_TERMINATE = 0x0001
proc := w32.OpenProcess(0x0001, false, uint32(p.Pid))
ret := w32.TerminateProcess(proc, 0)
w32.CloseHandle(proc)
if ret == false {
return windows.GetLastError()
} else {
return nil
}
}
func (p *Process) Kill() error {
return p.KillWithContext(context.Background())
}
func (p *Process) KillWithContext(ctx context.Context) error {
process := os.Process{Pid: int(p.Pid)}
return process.Kill()
}
func getFromSnapProcess(pid int32) (int32, int32, string, error) {
snap := w32.CreateToolhelp32Snapshot(w32.TH32CS_SNAPPROCESS, uint32(pid))
if snap == 0 {
return 0, 0, "", windows.GetLastError()
}
defer w32.CloseHandle(snap)
var pe32 w32.PROCESSENTRY32
pe32.DwSize = uint32(unsafe.Sizeof(pe32))
if w32.Process32First(snap, &pe32) == false {
return 0, 0, "", windows.GetLastError()
}
if pe32.Th32ProcessID == uint32(pid) {
szexe := windows.UTF16ToString(pe32.SzExeFile[:])
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
}
for w32.Process32Next(snap, &pe32) {
if pe32.Th32ProcessID == uint32(pid) {
szexe := windows.UTF16ToString(pe32.SzExeFile[:])
return int32(pe32.Th32ParentProcessID), int32(pe32.CntThreads), szexe, nil
}
}
return 0, 0, "", fmt.Errorf("Couldn't find pid: %d", pid)
}
// Get processes
func Processes() ([]*Process, error) {
return ProcessesWithContext(context.Background())
}
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
out := []*Process{}
pids, err := PidsWithContext(ctx)
if err != nil {
return out, fmt.Errorf("could not get Processes %s", err)
}
for _, pid := range pids {
p, err := NewProcess(pid)
if err != nil {
continue
}
out = append(out, p)
}
return out, nil
}
func getProcInfo(pid int32) (*SystemProcessInformation, error) {
initialBufferSize := uint64(0x4000)
bufferSize := initialBufferSize
buffer := make([]byte, bufferSize)
var sysProcInfo SystemProcessInformation
ret, _, _ := common.ProcNtQuerySystemInformation.Call(
uintptr(unsafe.Pointer(&sysProcInfo)),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(unsafe.Pointer(&bufferSize)),
uintptr(unsafe.Pointer(&bufferSize)))
if ret != 0 {
return nil, windows.GetLastError()
}
return &sysProcInfo, nil
}
func getRusage(pid int32) (*windows.Rusage, error) {
var CPU windows.Rusage
c, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, uint32(pid))
if err != nil {
return nil, err
}
defer windows.CloseHandle(c)
if err := windows.GetProcessTimes(c, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil {
return nil, err
}
return &CPU, nil
}
func getMemoryInfo(pid int32) (PROCESS_MEMORY_COUNTERS, error) {
var mem PROCESS_MEMORY_COUNTERS
// PROCESS_QUERY_LIMITED_INFORMATION is 0x1000
c, err := windows.OpenProcess(0x1000, false, uint32(pid))
if err != nil {
return mem, err
}
defer windows.CloseHandle(c)
if err := getProcessMemoryInfo(c, &mem); err != nil {
return mem, err
}
return mem, err
}
func getProcessMemoryInfo(h windows.Handle, mem *PROCESS_MEMORY_COUNTERS) (err error) {
r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(h), uintptr(unsafe.Pointer(mem)), uintptr(unsafe.Sizeof(*mem)))
if r1 == 0 {
if e1 != 0 {
err = error(e1)
} else {
err = syscall.EINVAL
}
}
return
}
type SYSTEM_TIMES struct {
CreateTime syscall.Filetime
ExitTime syscall.Filetime
KernelTime syscall.Filetime
UserTime syscall.Filetime
}
func getProcessCPUTimes(pid int32) (SYSTEM_TIMES, error) {
var times SYSTEM_TIMES
// PROCESS_QUERY_LIMITED_INFORMATION is 0x1000
h, err := windows.OpenProcess(0x1000, false, uint32(pid))
if err != nil {
return times, err
}
defer windows.CloseHandle(h)
err = syscall.GetProcessTimes(
syscall.Handle(h),
&times.CreateTime,
&times.ExitTime,
&times.KernelTime,
&times.UserTime,
)
return times, err
}

View File

@@ -0,0 +1,16 @@
// +build windows
package process
type PROCESS_MEMORY_COUNTERS struct {
CB uint32
PageFaultCount uint32
PeakWorkingSetSize uint32
WorkingSetSize uint32
QuotaPeakPagedPoolUsage uint32
QuotaPagedPoolUsage uint32
QuotaPeakNonPagedPoolUsage uint32
QuotaNonPagedPoolUsage uint32
PagefileUsage uint32
PeakPagefileUsage uint32
}

View File

@@ -0,0 +1,16 @@
// +build windows
package process
type PROCESS_MEMORY_COUNTERS struct {
CB uint32
PageFaultCount uint32
PeakWorkingSetSize uint64
WorkingSetSize uint64
QuotaPeakPagedPoolUsage uint64
QuotaPagedPoolUsage uint64
QuotaPeakNonPagedPoolUsage uint64
QuotaNonPagedPoolUsage uint64
PagefileUsage uint64
PeakPagefileUsage uint64
}

View File

@@ -0,0 +1,160 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Hand Writing
// - all pointer in ExternProc to uint64
// +build ignore
/*
Input to cgo -godefs.
*/
// +godefs map struct_in_addr [4]byte /* in_addr */
// +godefs map struct_in6_addr [16]byte /* in6_addr */
// +godefs map struct_ [16]byte /* in6_addr */
package process
/*
#define __DARWIN_UNIX03 0
#define KERNEL
#define _DARWIN_USE_64_BIT_INODE
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <unistd.h>
#include <mach/mach.h>
#include <mach/message.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <net/bpf.h>
#include <net/if_dl.h>
#include <net/if_var.h>
#include <net/route.h>
#include <netinet/in.h>
#include <sys/sysctl.h>
#include <sys/ucred.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/_types/_timeval.h>
#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
#include <sys/param.h>
#include <bsm/audit.h>
#include <sys/queue.h>
enum {
sizeofPtr = sizeof(void*),
};
union sockaddr_all {
struct sockaddr s1; // this one gets used for fields
struct sockaddr_in s2; // these pad it out
struct sockaddr_in6 s3;
struct sockaddr_un s4;
struct sockaddr_dl s5;
};
struct sockaddr_any {
struct sockaddr addr;
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
};
struct ucred_queue {
struct ucred *tqe_next;
struct ucred **tqe_prev;
TRACEBUF
};
*/
import "C"
// Machine characteristics; for internal use.
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
// Time
type Timespec C.struct_timespec
type Timeval C.struct_timeval
// Processes
type Rusage C.struct_rusage
type Rlimit C.struct_rlimit
type UGid_t C.gid_t
type KinfoProc C.struct_kinfo_proc
type Eproc C.struct_eproc
type Proc C.struct_proc
type Session C.struct_session
type ucred C.struct_ucred
type Uucred C.struct__ucred
type Upcred C.struct__pcred
type Vmspace C.struct_vmspace
type Sigacts C.struct_sigacts
type ExternProc C.struct_extern_proc
type Itimerval C.struct_itimerval
type Vnode C.struct_vnode
type Pgrp C.struct_pgrp
type UserStruct C.struct_user
type Au_session C.struct_au_session
type Posix_cred C.struct_posix_cred
type Label C.struct_label
type AuditinfoAddr C.struct_auditinfo_addr
type AuMask C.struct_au_mask
type AuTidAddr C.struct_au_tid_addr
// TAILQ(ucred)
type UcredQueue C.struct_ucred_queue

View File

@@ -0,0 +1,95 @@
// +build ignore
// We still need editing by hands.
// go tool cgo -godefs types_freebsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_freebsd_amd64.go
/*
Input to cgo -godefs.
*/
// +godefs map struct_pargs int64 /* pargs */
// +godefs map struct_proc int64 /* proc */
// +godefs map struct_user int64 /* user */
// +godefs map struct_vnode int64 /* vnode */
// +godefs map struct_vnode int64 /* vnode */
// +godefs map struct_filedesc int64 /* filedesc */
// +godefs map struct_vmspace int64 /* vmspace */
// +godefs map struct_pcb int64 /* pcb */
// +godefs map struct_thread int64 /* thread */
// +godefs map struct___sigset [16]byte /* sigset */
package process
/*
#include <sys/types.h>
#include <sys/user.h>
enum {
sizeofPtr = sizeof(void*),
};
*/
import "C"
// Machine characteristics; for internal use.
const (
CTLKern = 1 // "high kernel": proc, limits
KernProc = 14 // struct: process entries
KernProcPID = 1 // by process id
KernProcProc = 8 // only return procs
KernProcPathname = 12 // path to executable
KernProcArgs = 7 // get/set arguments/proctitle
)
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
)
const (
sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry
sizeOfKinfoProc = C.sizeof_struct_kinfo_proc
)
// from sys/proc.h
const (
SIDL = 1 /* Process being created by fork. */
SRUN = 2 /* Currently runnable. */
SSLEEP = 3 /* Sleeping on an address. */
SSTOP = 4 /* Process debugging or suspension. */
SZOMB = 5 /* Awaiting collection by parent. */
SWAIT = 6 /* Waiting for interrupt. */
SLOCK = 7 /* Blocked on a lock. */
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
// Time
type Timespec C.struct_timespec
type Timeval C.struct_timeval
// Processes
type Rusage C.struct_rusage
type Rlimit C.struct_rlimit
type KinfoProc C.struct_kinfo_proc
type Priority C.struct_priority
type KinfoVmentry C.struct_kinfo_vmentry

View File

@@ -0,0 +1,103 @@
// +build ignore
// We still need editing by hands.
// go tool cgo -godefs types_openbsd.go | sed 's/\*int64/int64/' | sed 's/\*byte/int64/' > process_openbsd_amd64.go
/*
Input to cgo -godefs.
*/
// +godefs map struct_pargs int64 /* pargs */
// +godefs map struct_proc int64 /* proc */
// +godefs map struct_user int64 /* user */
// +godefs map struct_vnode int64 /* vnode */
// +godefs map struct_vnode int64 /* vnode */
// +godefs map struct_filedesc int64 /* filedesc */
// +godefs map struct_vmspace int64 /* vmspace */
// +godefs map struct_pcb int64 /* pcb */
// +godefs map struct_thread int64 /* thread */
// +godefs map struct___sigset [16]byte /* sigset */
package process
/*
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/user.h>
enum {
sizeofPtr = sizeof(void*),
};
*/
import "C"
// Machine characteristics; for internal use.
const (
CTLKern = 1 // "high kernel": proc, limits
KernProc = 66 // struct: process entries
KernProcAll = 0
KernProcPID = 1 // by process id
KernProcProc = 8 // only return procs
KernProcPathname = 12 // path to executable
KernProcArgs = 55 // get/set arguments/proctitle
KernProcArgv = 1
KernProcEnv = 3
)
const (
ArgMax = 256 * 1024 // sys/syslimits.h:#define ARG_MAX
)
const (
sizeofPtr = C.sizeofPtr
sizeofShort = C.sizeof_short
sizeofInt = C.sizeof_int
sizeofLong = C.sizeof_long
sizeofLongLong = C.sizeof_longlong
)
const (
sizeOfKinfoVmentry = C.sizeof_struct_kinfo_vmentry
sizeOfKinfoProc = C.sizeof_struct_kinfo_proc
)
// from sys/proc.h
const (
SIDL = 1 /* Process being created by fork. */
SRUN = 2 /* Currently runnable. */
SSLEEP = 3 /* Sleeping on an address. */
SSTOP = 4 /* Process debugging or suspension. */
SZOMB = 5 /* Awaiting collection by parent. */
SDEAD = 6 /* Thread is almost gone */
SONPROC = 7 /* Thread is currently on a CPU. */
)
// Basic types
type (
_C_short C.short
_C_int C.int
_C_long C.long
_C_long_long C.longlong
)
// Time
type Timespec C.struct_timespec
type Timeval C.struct_timeval
// Processes
type Rusage C.struct_rusage
type Rlimit C.struct_rlimit
type KinfoProc C.struct_kinfo_proc
type Priority C.struct_priority
type KinfoVmentry C.struct_kinfo_vmentry

16
vendor/github.com/shirou/w32/AUTHORS generated vendored Normal file
View File

@@ -0,0 +1,16 @@
# This is the official list of 'w32' authors for copyright purposes.
# Names should be added to this file as
# Name or Organization <email address>
# The email address is not required for organizations.
# Please keep the list sorted.
# Contributors
# ============
Allen Dang <allengnr@gmail.com>
Benny Siegert <bsiegert@gmail.com>
Bruno Bigras <bigras.bruno@gmail.com>
Gerald Rosenberg <gerald.rosenberg@gmail.com>
Michael Henke

23
vendor/github.com/shirou/w32/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
Copyright (c) 2010-2012 The w32 Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

33
vendor/github.com/shirou/w32/README.md generated vendored Normal file
View File

@@ -0,0 +1,33 @@
About w32
==========
w32 is a wrapper of windows apis for the Go Programming Language.
It wraps win32 apis to "Go style" to make them easier to use.
Setup
=====
1. Make sure you have a working Go installation and build environment,
see this go-nuts post for details:
http://groups.google.com/group/golang-nuts/msg/5c87630a84f4fd0c
Updated versions of the Windows Go build are available here:
http://code.google.com/p/gomingw/downloads/list
2. Create a "gopath" directory if you do not have one yet and set the
GOPATH variable accordingly. For example:
mkdir -p go-externals/src
export GOPATH=${PWD}/go-externals
3. go get github.com/AllenDang/w32
4. go install github.com/AllenDang/w32...
Contribute
==========
Contributions in form of design, code, documentation, bug reporting or other
ways you see fit are very welcome.
Thank You!

301
vendor/github.com/shirou/w32/advapi32.go generated vendored Normal file
View File

@@ -0,0 +1,301 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
var (
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
procRegCreateKeyEx = modadvapi32.NewProc("RegCreateKeyExW")
procRegOpenKeyEx = modadvapi32.NewProc("RegOpenKeyExW")
procRegCloseKey = modadvapi32.NewProc("RegCloseKey")
procRegGetValue = modadvapi32.NewProc("RegGetValueW")
procRegEnumKeyEx = modadvapi32.NewProc("RegEnumKeyExW")
// procRegSetKeyValue = modadvapi32.NewProc("RegSetKeyValueW")
procRegSetValueEx = modadvapi32.NewProc("RegSetValueExW")
procOpenEventLog = modadvapi32.NewProc("OpenEventLogW")
procReadEventLog = modadvapi32.NewProc("ReadEventLogW")
procCloseEventLog = modadvapi32.NewProc("CloseEventLog")
procOpenSCManager = modadvapi32.NewProc("OpenSCManagerW")
procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle")
procOpenService = modadvapi32.NewProc("OpenServiceW")
procStartService = modadvapi32.NewProc("StartServiceW")
procControlService = modadvapi32.NewProc("ControlService")
)
func RegCreateKey(hKey HKEY, subKey string) HKEY {
var result HKEY
ret, _, _ := procRegCreateKeyEx.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(0),
uintptr(0),
uintptr(0),
uintptr(KEY_ALL_ACCESS),
uintptr(0),
uintptr(unsafe.Pointer(&result)),
uintptr(0))
_ = ret
return result
}
func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY {
var result HKEY
ret, _, _ := procRegOpenKeyEx.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(0),
uintptr(samDesired),
uintptr(unsafe.Pointer(&result)))
if ret != ERROR_SUCCESS {
panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired))
}
return result
}
func RegCloseKey(hKey HKEY) error {
var err error
ret, _, _ := procRegCloseKey.Call(
uintptr(hKey))
if ret != ERROR_SUCCESS {
err = errors.New("RegCloseKey failed")
}
return err
}
func RegGetRaw(hKey HKEY, subKey string, value string) []byte {
var bufLen uint32
var valptr unsafe.Pointer
if len(value) > 0 {
valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value))
}
procRegGetValue.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(valptr),
uintptr(RRF_RT_ANY),
0,
0,
uintptr(unsafe.Pointer(&bufLen)))
if bufLen == 0 {
return nil
}
buf := make([]byte, bufLen)
ret, _, _ := procRegGetValue.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(valptr),
uintptr(RRF_RT_ANY),
0,
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&bufLen)))
if ret != ERROR_SUCCESS {
return nil
}
return buf
}
func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) {
var lptr, vptr unsafe.Pointer
if len(subKey) > 0 {
lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))
}
if len(value) > 0 {
vptr = unsafe.Pointer(&value[0])
}
ret, _, _ := procRegSetValueEx.Call(
uintptr(hKey),
uintptr(lptr),
uintptr(0),
uintptr(REG_BINARY),
uintptr(vptr),
uintptr(len(value)))
return int(ret)
}
func RegGetString(hKey HKEY, subKey string, value string) string {
var bufLen uint32
procRegGetValue.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
uintptr(RRF_RT_REG_SZ),
0,
0,
uintptr(unsafe.Pointer(&bufLen)))
if bufLen == 0 {
return ""
}
buf := make([]uint16, bufLen)
ret, _, _ := procRegGetValue.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
uintptr(RRF_RT_REG_SZ),
0,
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&bufLen)))
if ret != ERROR_SUCCESS {
return ""
}
return syscall.UTF16ToString(buf)
}
/*
func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) {
ret, _, _ := procRegSetKeyValue.Call(
uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))),
uintptr(dwType),
data,
uintptr(cbData))
return int(ret)
}
*/
func RegEnumKeyEx(hKey HKEY, index uint32) string {
var bufLen uint32 = 255
buf := make([]uint16, bufLen)
procRegEnumKeyEx.Call(
uintptr(hKey),
uintptr(index),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(&bufLen)),
0,
0,
0,
0)
return syscall.UTF16ToString(buf)
}
func OpenEventLog(servername string, sourcename string) HANDLE {
ret, _, _ := procOpenEventLog.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename))))
return HANDLE(ret)
}
func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool {
ret, _, _ := procReadEventLog.Call(
uintptr(eventlog),
uintptr(readflags),
uintptr(recordoffset),
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(numberofbytestoread),
uintptr(unsafe.Pointer(bytesread)),
uintptr(unsafe.Pointer(minnumberofbytesneeded)))
return ret != 0
}
func CloseEventLog(eventlog HANDLE) bool {
ret, _, _ := procCloseEventLog.Call(
uintptr(eventlog))
return ret != 0
}
func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) {
var p1, p2 uintptr
if len(lpMachineName) > 0 {
p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName)))
}
if len(lpDatabaseName) > 0 {
p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName)))
}
ret, _, _ := procOpenSCManager.Call(
p1,
p2,
uintptr(dwDesiredAccess))
if ret == 0 {
return 0, syscall.GetLastError()
}
return HANDLE(ret), nil
}
func CloseServiceHandle(hSCObject HANDLE) error {
ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject))
if ret == 0 {
return syscall.GetLastError()
}
return nil
}
func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) {
ret, _, _ := procOpenService.Call(
uintptr(hSCManager),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))),
uintptr(dwDesiredAccess))
if ret == 0 {
return 0, syscall.GetLastError()
}
return HANDLE(ret), nil
}
func StartService(hService HANDLE, lpServiceArgVectors []string) error {
l := len(lpServiceArgVectors)
var ret uintptr
if l == 0 {
ret, _, _ = procStartService.Call(
uintptr(hService),
0,
0)
} else {
lpArgs := make([]uintptr, l)
for i := 0; i < l; i++ {
lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i])))
}
ret, _, _ = procStartService.Call(
uintptr(hService),
uintptr(l),
uintptr(unsafe.Pointer(&lpArgs[0])))
}
if ret == 0 {
return syscall.GetLastError()
}
return nil
}
func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool {
if lpServiceStatus == nil {
panic("ControlService:lpServiceStatus cannot be nil")
}
ret, _, _ := procControlService.Call(
uintptr(hService),
uintptr(dwControl),
uintptr(unsafe.Pointer(lpServiceStatus)))
return ret != 0
}

111
vendor/github.com/shirou/w32/comctl32.go generated vendored Normal file
View File

@@ -0,0 +1,111 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modcomctl32 = syscall.NewLazyDLL("comctl32.dll")
procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx")
procImageList_Create = modcomctl32.NewProc("ImageList_Create")
procImageList_Destroy = modcomctl32.NewProc("ImageList_Destroy")
procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount")
procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount")
procImageList_Add = modcomctl32.NewProc("ImageList_Add")
procImageList_ReplaceIcon = modcomctl32.NewProc("ImageList_ReplaceIcon")
procImageList_Remove = modcomctl32.NewProc("ImageList_Remove")
procTrackMouseEvent = modcomctl32.NewProc("_TrackMouseEvent")
)
func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool {
ret, _, _ := procInitCommonControlsEx.Call(
uintptr(unsafe.Pointer(lpInitCtrls)))
return ret != 0
}
func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST {
ret, _, _ := procImageList_Create.Call(
uintptr(cx),
uintptr(cy),
uintptr(flags),
uintptr(cInitial),
uintptr(cGrow))
if ret == 0 {
panic("Create image list failed")
}
return HIMAGELIST(ret)
}
func ImageList_Destroy(himl HIMAGELIST) bool {
ret, _, _ := procImageList_Destroy.Call(
uintptr(himl))
return ret != 0
}
func ImageList_GetImageCount(himl HIMAGELIST) int {
ret, _, _ := procImageList_GetImageCount.Call(
uintptr(himl))
return int(ret)
}
func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool {
ret, _, _ := procImageList_SetImageCount.Call(
uintptr(himl),
uintptr(uNewCount))
return ret != 0
}
func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int {
ret, _, _ := procImageList_Add.Call(
uintptr(himl),
uintptr(hbmImage),
uintptr(hbmMask))
return int(ret)
}
func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int {
ret, _, _ := procImageList_ReplaceIcon.Call(
uintptr(himl),
uintptr(i),
uintptr(hicon))
return int(ret)
}
func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int {
return ImageList_ReplaceIcon(himl, -1, hicon)
}
func ImageList_Remove(himl HIMAGELIST, i int) bool {
ret, _, _ := procImageList_Remove.Call(
uintptr(himl),
uintptr(i))
return ret != 0
}
func ImageList_RemoveAll(himl HIMAGELIST) bool {
return ImageList_Remove(himl, -1)
}
func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool {
ret, _, _ := procTrackMouseEvent.Call(
uintptr(unsafe.Pointer(tme)))
return ret != 0
}

40
vendor/github.com/shirou/w32/comdlg32.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll")
procGetSaveFileName = modcomdlg32.NewProc("GetSaveFileNameW")
procGetOpenFileName = modcomdlg32.NewProc("GetOpenFileNameW")
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
)
func GetOpenFileName(ofn *OPENFILENAME) bool {
ret, _, _ := procGetOpenFileName.Call(
uintptr(unsafe.Pointer(ofn)))
return ret != 0
}
func GetSaveFileName(ofn *OPENFILENAME) bool {
ret, _, _ := procGetSaveFileName.Call(
uintptr(unsafe.Pointer(ofn)))
return ret != 0
}
func CommDlgExtendedError() uint {
ret, _, _ := procCommDlgExtendedError.Call()
return uint(ret)
}

2661
vendor/github.com/shirou/w32/constants.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

256
vendor/github.com/shirou/w32/dwmapi.go generated vendored Normal file
View File

@@ -0,0 +1,256 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"fmt"
"syscall"
"unsafe"
)
// DEFINED IN THE DWM API BUT NOT IMPLEMENTED BY MS:
// DwmAttachMilContent
// DwmDetachMilContent
// DwmEnableComposition
// DwmGetGraphicsStreamClient
// DwmGetGraphicsStreamTransformHint
var (
moddwmapi = syscall.NewLazyDLL("dwmapi.dll")
procDwmDefWindowProc = moddwmapi.NewProc("DwmDefWindowProc")
procDwmEnableBlurBehindWindow = moddwmapi.NewProc("DwmEnableBlurBehindWindow")
procDwmEnableMMCSS = moddwmapi.NewProc("DwmEnableMMCSS")
procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea")
procDwmFlush = moddwmapi.NewProc("DwmFlush")
procDwmGetColorizationColor = moddwmapi.NewProc("DwmGetColorizationColor")
procDwmGetCompositionTimingInfo = moddwmapi.NewProc("DwmGetCompositionTimingInfo")
procDwmGetTransportAttributes = moddwmapi.NewProc("DwmGetTransportAttributes")
procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute")
procDwmInvalidateIconicBitmaps = moddwmapi.NewProc("DwmInvalidateIconicBitmaps")
procDwmIsCompositionEnabled = moddwmapi.NewProc("DwmIsCompositionEnabled")
procDwmModifyPreviousDxFrameDuration = moddwmapi.NewProc("DwmModifyPreviousDxFrameDuration")
procDwmQueryThumbnailSourceSize = moddwmapi.NewProc("DwmQueryThumbnailSourceSize")
procDwmRegisterThumbnail = moddwmapi.NewProc("DwmRegisterThumbnail")
procDwmRenderGesture = moddwmapi.NewProc("DwmRenderGesture")
procDwmSetDxFrameDuration = moddwmapi.NewProc("DwmSetDxFrameDuration")
procDwmSetIconicLivePreviewBitmap = moddwmapi.NewProc("DwmSetIconicLivePreviewBitmap")
procDwmSetIconicThumbnail = moddwmapi.NewProc("DwmSetIconicThumbnail")
procDwmSetPresentParameters = moddwmapi.NewProc("DwmSetPresentParameters")
procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute")
procDwmShowContact = moddwmapi.NewProc("DwmShowContact")
procDwmTetherContact = moddwmapi.NewProc("DwmTetherContact")
procDwmTransitionOwnedWindow = moddwmapi.NewProc("DwmTransitionOwnedWindow")
procDwmUnregisterThumbnail = moddwmapi.NewProc("DwmUnregisterThumbnail")
procDwmUpdateThumbnailProperties = moddwmapi.NewProc("DwmUpdateThumbnailProperties")
)
func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) {
var result uint
ret, _, _ := procDwmDefWindowProc.Call(
uintptr(hWnd),
uintptr(msg),
wParam,
lParam,
uintptr(unsafe.Pointer(&result)))
return ret != 0, result
}
func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT {
ret, _, _ := procDwmEnableBlurBehindWindow.Call(
uintptr(hWnd),
uintptr(unsafe.Pointer(pBlurBehind)))
return HRESULT(ret)
}
func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT {
ret, _, _ := procDwmEnableMMCSS.Call(
uintptr(BoolToBOOL(fEnableMMCSS)))
return HRESULT(ret)
}
func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT {
ret, _, _ := procDwmExtendFrameIntoClientArea.Call(
uintptr(hWnd),
uintptr(unsafe.Pointer(pMarInset)))
return HRESULT(ret)
}
func DwmFlush() HRESULT {
ret, _, _ := procDwmFlush.Call()
return HRESULT(ret)
}
func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT {
ret, _, _ := procDwmGetColorizationColor.Call(
uintptr(unsafe.Pointer(pcrColorization)),
uintptr(unsafe.Pointer(pfOpaqueBlend)))
return HRESULT(ret)
}
func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT {
ret, _, _ := procDwmGetCompositionTimingInfo.Call(
uintptr(hWnd),
uintptr(unsafe.Pointer(pTimingInfo)))
return HRESULT(ret)
}
func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT {
ret, _, _ := procDwmGetTransportAttributes.Call(
uintptr(unsafe.Pointer(pfIsRemoting)),
uintptr(unsafe.Pointer(pfIsConnected)),
uintptr(unsafe.Pointer(pDwGeneration)))
return HRESULT(ret)
}
// TODO: verify handling of variable arguments
func DwmGetWindowAttribute(hWnd HWND, dwAttribute uint32) (pAttribute interface{}, result HRESULT) {
var pvAttribute, pvAttrSize uintptr
switch dwAttribute {
case DWMWA_NCRENDERING_ENABLED:
v := new(BOOL)
pAttribute = v
pvAttribute = uintptr(unsafe.Pointer(v))
pvAttrSize = unsafe.Sizeof(*v)
case DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_EXTENDED_FRAME_BOUNDS:
v := new(RECT)
pAttribute = v
pvAttribute = uintptr(unsafe.Pointer(v))
pvAttrSize = unsafe.Sizeof(*v)
case DWMWA_CLOAKED:
panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not currently supported.", dwAttribute))
default:
panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not valid.", dwAttribute))
}
ret, _, _ := procDwmGetWindowAttribute.Call(
uintptr(hWnd),
uintptr(dwAttribute),
pvAttribute,
pvAttrSize)
result = HRESULT(ret)
return
}
func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT {
ret, _, _ := procDwmInvalidateIconicBitmaps.Call(
uintptr(hWnd))
return HRESULT(ret)
}
func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT {
ret, _, _ := procDwmIsCompositionEnabled.Call(
uintptr(unsafe.Pointer(pfEnabled)))
return HRESULT(ret)
}
func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT {
ret, _, _ := procDwmModifyPreviousDxFrameDuration.Call(
uintptr(hWnd),
uintptr(cRefreshes),
uintptr(BoolToBOOL(fRelative)))
return HRESULT(ret)
}
func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT {
ret, _, _ := procDwmQueryThumbnailSourceSize.Call(
uintptr(hThumbnail),
uintptr(unsafe.Pointer(pSize)))
return HRESULT(ret)
}
func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT {
ret, _, _ := procDwmRegisterThumbnail.Call(
uintptr(hWndDestination),
uintptr(hWndSource),
uintptr(unsafe.Pointer(phThumbnailId)))
return HRESULT(ret)
}
func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) {
procDwmRenderGesture.Call(
uintptr(gt),
uintptr(cContacts),
uintptr(unsafe.Pointer(pdwPointerID)),
uintptr(unsafe.Pointer(pPoints)))
return
}
func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT {
ret, _, _ := procDwmSetDxFrameDuration.Call(
uintptr(hWnd),
uintptr(cRefreshes))
return HRESULT(ret)
}
func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT {
ret, _, _ := procDwmSetIconicLivePreviewBitmap.Call(
uintptr(hWnd),
uintptr(hbmp),
uintptr(unsafe.Pointer(pptClient)),
uintptr(dwSITFlags))
return HRESULT(ret)
}
func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT {
ret, _, _ := procDwmSetIconicThumbnail.Call(
uintptr(hWnd),
uintptr(hbmp),
uintptr(dwSITFlags))
return HRESULT(ret)
}
func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT {
ret, _, _ := procDwmSetPresentParameters.Call(
uintptr(hWnd),
uintptr(unsafe.Pointer(pPresentParams)))
return HRESULT(ret)
}
func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT {
ret, _, _ := procDwmSetWindowAttribute.Call(
uintptr(hWnd),
uintptr(dwAttribute),
uintptr(pvAttribute),
uintptr(cbAttribute))
return HRESULT(ret)
}
func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) {
procDwmShowContact.Call(
uintptr(dwPointerID),
uintptr(eShowContact))
return
}
func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) {
procDwmTetherContact.Call(
uintptr(dwPointerID),
uintptr(BoolToBOOL(fEnable)),
uintptr(unsafe.Pointer(&ptTether)))
return
}
func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) {
procDwmTransitionOwnedWindow.Call(
uintptr(hWnd),
uintptr(target))
return
}
func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT {
ret, _, _ := procDwmUnregisterThumbnail.Call(
uintptr(hThumbnailId))
return HRESULT(ret)
}
func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT {
ret, _, _ := procDwmUpdateThumbnailProperties.Call(
uintptr(hThumbnailId),
uintptr(unsafe.Pointer(ptnProperties)))
return HRESULT(ret)
}

511
vendor/github.com/shirou/w32/gdi32.go generated vendored Normal file
View File

@@ -0,0 +1,511 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modgdi32 = syscall.NewLazyDLL("gdi32.dll")
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
procDeleteObject = modgdi32.NewProc("DeleteObject")
procCreateFontIndirect = modgdi32.NewProc("CreateFontIndirectW")
procAbortDoc = modgdi32.NewProc("AbortDoc")
procBitBlt = modgdi32.NewProc("BitBlt")
procCloseEnhMetaFile = modgdi32.NewProc("CloseEnhMetaFile")
procCopyEnhMetaFile = modgdi32.NewProc("CopyEnhMetaFileW")
procCreateBrushIndirect = modgdi32.NewProc("CreateBrushIndirect")
procCreateCompatibleDC = modgdi32.NewProc("CreateCompatibleDC")
procCreateDC = modgdi32.NewProc("CreateDCW")
procCreateDIBSection = modgdi32.NewProc("CreateDIBSection")
procCreateEnhMetaFile = modgdi32.NewProc("CreateEnhMetaFileW")
procCreateIC = modgdi32.NewProc("CreateICW")
procDeleteDC = modgdi32.NewProc("DeleteDC")
procDeleteEnhMetaFile = modgdi32.NewProc("DeleteEnhMetaFile")
procEllipse = modgdi32.NewProc("Ellipse")
procEndDoc = modgdi32.NewProc("EndDoc")
procEndPage = modgdi32.NewProc("EndPage")
procExtCreatePen = modgdi32.NewProc("ExtCreatePen")
procGetEnhMetaFile = modgdi32.NewProc("GetEnhMetaFileW")
procGetEnhMetaFileHeader = modgdi32.NewProc("GetEnhMetaFileHeader")
procGetObject = modgdi32.NewProc("GetObjectW")
procGetStockObject = modgdi32.NewProc("GetStockObject")
procGetTextExtentExPoint = modgdi32.NewProc("GetTextExtentExPointW")
procGetTextExtentPoint32 = modgdi32.NewProc("GetTextExtentPoint32W")
procGetTextMetrics = modgdi32.NewProc("GetTextMetricsW")
procLineTo = modgdi32.NewProc("LineTo")
procMoveToEx = modgdi32.NewProc("MoveToEx")
procPlayEnhMetaFile = modgdi32.NewProc("PlayEnhMetaFile")
procRectangle = modgdi32.NewProc("Rectangle")
procResetDC = modgdi32.NewProc("ResetDCW")
procSelectObject = modgdi32.NewProc("SelectObject")
procSetBkMode = modgdi32.NewProc("SetBkMode")
procSetBrushOrgEx = modgdi32.NewProc("SetBrushOrgEx")
procSetStretchBltMode = modgdi32.NewProc("SetStretchBltMode")
procSetTextColor = modgdi32.NewProc("SetTextColor")
procSetBkColor = modgdi32.NewProc("SetBkColor")
procStartDoc = modgdi32.NewProc("StartDocW")
procStartPage = modgdi32.NewProc("StartPage")
procStretchBlt = modgdi32.NewProc("StretchBlt")
procSetDIBitsToDevice = modgdi32.NewProc("SetDIBitsToDevice")
procChoosePixelFormat = modgdi32.NewProc("ChoosePixelFormat")
procDescribePixelFormat = modgdi32.NewProc("DescribePixelFormat")
procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat")
procGetPixelFormat = modgdi32.NewProc("GetPixelFormat")
procSetPixelFormat = modgdi32.NewProc("SetPixelFormat")
procSwapBuffers = modgdi32.NewProc("SwapBuffers")
)
func GetDeviceCaps(hdc HDC, index int) int {
ret, _, _ := procGetDeviceCaps.Call(
uintptr(hdc),
uintptr(index))
return int(ret)
}
func DeleteObject(hObject HGDIOBJ) bool {
ret, _, _ := procDeleteObject.Call(
uintptr(hObject))
return ret != 0
}
func CreateFontIndirect(logFont *LOGFONT) HFONT {
ret, _, _ := procCreateFontIndirect.Call(
uintptr(unsafe.Pointer(logFont)))
return HFONT(ret)
}
func AbortDoc(hdc HDC) int {
ret, _, _ := procAbortDoc.Call(
uintptr(hdc))
return int(ret)
}
func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) {
ret, _, _ := procBitBlt.Call(
uintptr(hdcDest),
uintptr(nXDest),
uintptr(nYDest),
uintptr(nWidth),
uintptr(nHeight),
uintptr(hdcSrc),
uintptr(nXSrc),
uintptr(nYSrc),
uintptr(dwRop))
if ret == 0 {
panic("BitBlt failed")
}
}
func CloseEnhMetaFile(hdc HDC) HENHMETAFILE {
ret, _, _ := procCloseEnhMetaFile.Call(
uintptr(hdc))
return HENHMETAFILE(ret)
}
func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE {
ret, _, _ := procCopyEnhMetaFile.Call(
uintptr(hemfSrc),
uintptr(unsafe.Pointer(lpszFile)))
return HENHMETAFILE(ret)
}
func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH {
ret, _, _ := procCreateBrushIndirect.Call(
uintptr(unsafe.Pointer(lplb)))
return HBRUSH(ret)
}
func CreateCompatibleDC(hdc HDC) HDC {
ret, _, _ := procCreateCompatibleDC.Call(
uintptr(hdc))
if ret == 0 {
panic("Create compatible DC failed")
}
return HDC(ret)
}
func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC {
ret, _, _ := procCreateDC.Call(
uintptr(unsafe.Pointer(lpszDriver)),
uintptr(unsafe.Pointer(lpszDevice)),
uintptr(unsafe.Pointer(lpszOutput)),
uintptr(unsafe.Pointer(lpInitData)))
return HDC(ret)
}
func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP {
ret, _, _ := procCreateDIBSection.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(pbmi)),
uintptr(iUsage),
uintptr(unsafe.Pointer(ppvBits)),
uintptr(hSection),
uintptr(dwOffset))
return HBITMAP(ret)
}
func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC {
ret, _, _ := procCreateEnhMetaFile.Call(
uintptr(hdcRef),
uintptr(unsafe.Pointer(lpFilename)),
uintptr(unsafe.Pointer(lpRect)),
uintptr(unsafe.Pointer(lpDescription)))
return HDC(ret)
}
func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC {
ret, _, _ := procCreateIC.Call(
uintptr(unsafe.Pointer(lpszDriver)),
uintptr(unsafe.Pointer(lpszDevice)),
uintptr(unsafe.Pointer(lpszOutput)),
uintptr(unsafe.Pointer(lpdvmInit)))
return HDC(ret)
}
func DeleteDC(hdc HDC) bool {
ret, _, _ := procDeleteDC.Call(
uintptr(hdc))
return ret != 0
}
func DeleteEnhMetaFile(hemf HENHMETAFILE) bool {
ret, _, _ := procDeleteEnhMetaFile.Call(
uintptr(hemf))
return ret != 0
}
func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
ret, _, _ := procEllipse.Call(
uintptr(hdc),
uintptr(nLeftRect),
uintptr(nTopRect),
uintptr(nRightRect),
uintptr(nBottomRect))
return ret != 0
}
func EndDoc(hdc HDC) int {
ret, _, _ := procEndDoc.Call(
uintptr(hdc))
return int(ret)
}
func EndPage(hdc HDC) int {
ret, _, _ := procEndPage.Call(
uintptr(hdc))
return int(ret)
}
func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN {
ret, _, _ := procExtCreatePen.Call(
uintptr(dwPenStyle),
uintptr(dwWidth),
uintptr(unsafe.Pointer(lplb)),
uintptr(dwStyleCount),
uintptr(unsafe.Pointer(lpStyle)))
return HPEN(ret)
}
func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE {
ret, _, _ := procGetEnhMetaFile.Call(
uintptr(unsafe.Pointer(lpszMetaFile)))
return HENHMETAFILE(ret)
}
func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint {
ret, _, _ := procGetEnhMetaFileHeader.Call(
uintptr(hemf),
uintptr(cbBuffer),
uintptr(unsafe.Pointer(lpemh)))
return uint(ret)
}
func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int {
ret, _, _ := procGetObject.Call(
uintptr(hgdiobj),
uintptr(cbBuffer),
uintptr(lpvObject))
return int(ret)
}
func GetStockObject(fnObject int) HGDIOBJ {
ret, _, _ := procGetDeviceCaps.Call(
uintptr(fnObject))
return HGDIOBJ(ret)
}
func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool {
ret, _, _ := procGetTextExtentExPoint.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(lpszStr)),
uintptr(cchString),
uintptr(nMaxExtent),
uintptr(unsafe.Pointer(lpnFit)),
uintptr(unsafe.Pointer(alpDx)),
uintptr(unsafe.Pointer(lpSize)))
return ret != 0
}
func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool {
ret, _, _ := procGetTextExtentPoint32.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(lpString)),
uintptr(c),
uintptr(unsafe.Pointer(lpSize)))
return ret != 0
}
func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool {
ret, _, _ := procGetTextMetrics.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(lptm)))
return ret != 0
}
func LineTo(hdc HDC, nXEnd, nYEnd int) bool {
ret, _, _ := procLineTo.Call(
uintptr(hdc),
uintptr(nXEnd),
uintptr(nYEnd))
return ret != 0
}
func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool {
ret, _, _ := procMoveToEx.Call(
uintptr(hdc),
uintptr(x),
uintptr(y),
uintptr(unsafe.Pointer(lpPoint)))
return ret != 0
}
func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool {
ret, _, _ := procPlayEnhMetaFile.Call(
uintptr(hdc),
uintptr(hemf),
uintptr(unsafe.Pointer(lpRect)))
return ret != 0
}
func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
ret, _, _ := procRectangle.Call(
uintptr(hdc),
uintptr(nLeftRect),
uintptr(nTopRect),
uintptr(nRightRect),
uintptr(nBottomRect))
return ret != 0
}
func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC {
ret, _, _ := procResetDC.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(lpInitData)))
return HDC(ret)
}
func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ {
ret, _, _ := procSelectObject.Call(
uintptr(hdc),
uintptr(hgdiobj))
if ret == 0 {
panic("SelectObject failed")
}
return HGDIOBJ(ret)
}
func SetBkMode(hdc HDC, iBkMode int) int {
ret, _, _ := procSetBkMode.Call(
uintptr(hdc),
uintptr(iBkMode))
if ret == 0 {
panic("SetBkMode failed")
}
return int(ret)
}
func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool {
ret, _, _ := procSetBrushOrgEx.Call(
uintptr(hdc),
uintptr(nXOrg),
uintptr(nYOrg),
uintptr(unsafe.Pointer(lppt)))
return ret != 0
}
func SetStretchBltMode(hdc HDC, iStretchMode int) int {
ret, _, _ := procSetStretchBltMode.Call(
uintptr(hdc),
uintptr(iStretchMode))
return int(ret)
}
func SetTextColor(hdc HDC, crColor COLORREF) COLORREF {
ret, _, _ := procSetTextColor.Call(
uintptr(hdc),
uintptr(crColor))
if ret == CLR_INVALID {
panic("SetTextColor failed")
}
return COLORREF(ret)
}
func SetBkColor(hdc HDC, crColor COLORREF) COLORREF {
ret, _, _ := procSetBkColor.Call(
uintptr(hdc),
uintptr(crColor))
if ret == CLR_INVALID {
panic("SetBkColor failed")
}
return COLORREF(ret)
}
func StartDoc(hdc HDC, lpdi *DOCINFO) int {
ret, _, _ := procStartDoc.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(lpdi)))
return int(ret)
}
func StartPage(hdc HDC) int {
ret, _, _ := procStartPage.Call(
uintptr(hdc))
return int(ret)
}
func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) {
ret, _, _ := procStretchBlt.Call(
uintptr(hdcDest),
uintptr(nXOriginDest),
uintptr(nYOriginDest),
uintptr(nWidthDest),
uintptr(nHeightDest),
uintptr(hdcSrc),
uintptr(nXOriginSrc),
uintptr(nYOriginSrc),
uintptr(nWidthSrc),
uintptr(nHeightSrc),
uintptr(dwRop))
if ret == 0 {
panic("StretchBlt failed")
}
}
func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int {
ret, _, _ := procSetDIBitsToDevice.Call(
uintptr(hdc),
uintptr(xDest),
uintptr(yDest),
uintptr(dwWidth),
uintptr(dwHeight),
uintptr(xSrc),
uintptr(ySrc),
uintptr(uStartScan),
uintptr(cScanLines),
uintptr(unsafe.Pointer(&lpvBits[0])),
uintptr(unsafe.Pointer(lpbmi)),
uintptr(fuColorUse))
return int(ret)
}
func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int {
ret, _, _ := procChoosePixelFormat.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(pfd)),
)
return int(ret)
}
func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int {
ret, _, _ := procDescribePixelFormat.Call(
uintptr(hdc),
uintptr(iPixelFormat),
uintptr(nBytes),
uintptr(unsafe.Pointer(pfd)),
)
return int(ret)
}
func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint {
ret, _, _ := procGetEnhMetaFilePixelFormat.Call(
uintptr(hemf),
uintptr(cbBuffer),
uintptr(unsafe.Pointer(pfd)),
)
return uint(ret)
}
func GetPixelFormat(hdc HDC) int {
ret, _, _ := procGetPixelFormat.Call(
uintptr(hdc),
)
return int(ret)
}
func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool {
ret, _, _ := procSetPixelFormat.Call(
uintptr(hdc),
uintptr(iPixelFormat),
uintptr(unsafe.Pointer(pfd)),
)
return ret == TRUE
}
func SwapBuffers(hdc HDC) bool {
ret, _, _ := procSwapBuffers.Call(uintptr(hdc))
return ret == TRUE
}

177
vendor/github.com/shirou/w32/gdiplus.go generated vendored Normal file
View File

@@ -0,0 +1,177 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
const (
Ok = 0
GenericError = 1
InvalidParameter = 2
OutOfMemory = 3
ObjectBusy = 4
InsufficientBuffer = 5
NotImplemented = 6
Win32Error = 7
WrongState = 8
Aborted = 9
FileNotFound = 10
ValueOverflow = 11
AccessDenied = 12
UnknownImageFormat = 13
FontFamilyNotFound = 14
FontStyleNotFound = 15
NotTrueTypeFont = 16
UnsupportedGdiplusVersion = 17
GdiplusNotInitialized = 18
PropertyNotFound = 19
PropertyNotSupported = 20
ProfileNotFound = 21
)
func GetGpStatus(s int32) string {
switch s {
case Ok:
return "Ok"
case GenericError:
return "GenericError"
case InvalidParameter:
return "InvalidParameter"
case OutOfMemory:
return "OutOfMemory"
case ObjectBusy:
return "ObjectBusy"
case InsufficientBuffer:
return "InsufficientBuffer"
case NotImplemented:
return "NotImplemented"
case Win32Error:
return "Win32Error"
case WrongState:
return "WrongState"
case Aborted:
return "Aborted"
case FileNotFound:
return "FileNotFound"
case ValueOverflow:
return "ValueOverflow"
case AccessDenied:
return "AccessDenied"
case UnknownImageFormat:
return "UnknownImageFormat"
case FontFamilyNotFound:
return "FontFamilyNotFound"
case FontStyleNotFound:
return "FontStyleNotFound"
case NotTrueTypeFont:
return "NotTrueTypeFont"
case UnsupportedGdiplusVersion:
return "UnsupportedGdiplusVersion"
case GdiplusNotInitialized:
return "GdiplusNotInitialized"
case PropertyNotFound:
return "PropertyNotFound"
case PropertyNotSupported:
return "PropertyNotSupported"
case ProfileNotFound:
return "ProfileNotFound"
}
return "Unknown Status Value"
}
var (
token uintptr
modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile")
procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream")
procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage")
procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown")
procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup")
)
func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromFile.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
}
return bitmap, nil
}
func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromResource.Call(
uintptr(instance),
uintptr(unsafe.Pointer(resId)),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
}
return bitmap, nil
}
func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
var bitmap *uintptr
ret, _, _ := procGdipCreateBitmapFromStream.Call(
uintptr(unsafe.Pointer(stream)),
uintptr(unsafe.Pointer(&bitmap)))
if ret != Ok {
return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
}
return bitmap, nil
}
func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
var hbitmap HBITMAP
ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
uintptr(unsafe.Pointer(bitmap)),
uintptr(unsafe.Pointer(&hbitmap)),
uintptr(background))
if ret != Ok {
return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
}
return hbitmap, nil
}
func GdipDisposeImage(image *uintptr) {
procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
}
func GdiplusShutdown() {
procGdiplusShutdown.Call(token)
}
func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
ret, _, _ := procGdiplusStartup.Call(
uintptr(unsafe.Pointer(&token)),
uintptr(unsafe.Pointer(input)),
uintptr(unsafe.Pointer(output)))
if ret != Ok {
panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
}
}

45
vendor/github.com/shirou/w32/idispatch.go generated vendored Normal file
View File

@@ -0,0 +1,45 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"unsafe"
)
type pIDispatchVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
pGetTypeInfoCount uintptr
pGetTypeInfo uintptr
pGetIDsOfNames uintptr
pInvoke uintptr
}
type IDispatch struct {
lpVtbl *pIDispatchVtbl
}
func (this *IDispatch) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
}
func (this *IDispatch) AddRef() int32 {
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IDispatch) Release() int32 {
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IDispatch) GetIDsOfName(names []string) []int32 {
return ComGetIDsOfName(this, names)
}
func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT {
return ComInvoke(this, dispid, dispatch, params...)
}

33
vendor/github.com/shirou/w32/istream.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"unsafe"
)
type pIStreamVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
}
type IStream struct {
lpVtbl *pIStreamVtbl
}
func (this *IStream) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
}
func (this *IStream) AddRef() int32 {
return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
}
func (this *IStream) Release() int32 {
return ComRelease((*IUnknown)(unsafe.Pointer(this)))
}

29
vendor/github.com/shirou/w32/iunknown.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
type pIUnknownVtbl struct {
pQueryInterface uintptr
pAddRef uintptr
pRelease uintptr
}
type IUnknown struct {
lpVtbl *pIUnknownVtbl
}
func (this *IUnknown) QueryInterface(id *GUID) *IDispatch {
return ComQueryInterface(this, id)
}
func (this *IUnknown) AddRef() int32 {
return ComAddRef(this)
}
func (this *IUnknown) Release() int32 {
return ComRelease(this)
}

316
vendor/github.com/shirou/w32/kernel32.go generated vendored Normal file
View File

@@ -0,0 +1,316 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetModuleHandle = modkernel32.NewProc("GetModuleHandleW")
procMulDiv = modkernel32.NewProc("MulDiv")
procGetConsoleWindow = modkernel32.NewProc("GetConsoleWindow")
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives")
procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID")
procLstrlen = modkernel32.NewProc("lstrlenW")
procLstrcpy = modkernel32.NewProc("lstrcpyW")
procGlobalAlloc = modkernel32.NewProc("GlobalAlloc")
procGlobalFree = modkernel32.NewProc("GlobalFree")
procGlobalLock = modkernel32.NewProc("GlobalLock")
procGlobalUnlock = modkernel32.NewProc("GlobalUnlock")
procMoveMemory = modkernel32.NewProc("RtlMoveMemory")
procFindResource = modkernel32.NewProc("FindResourceW")
procSizeofResource = modkernel32.NewProc("SizeofResource")
procLockResource = modkernel32.NewProc("LockResource")
procLoadResource = modkernel32.NewProc("LoadResource")
procGetLastError = modkernel32.NewProc("GetLastError")
procOpenProcess = modkernel32.NewProc("OpenProcess")
procTerminateProcess = modkernel32.NewProc("TerminateProcess")
procCloseHandle = modkernel32.NewProc("CloseHandle")
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
procModule32First = modkernel32.NewProc("Module32FirstW")
procModule32Next = modkernel32.NewProc("Module32NextW")
procProcess32First = modkernel32.NewProc("Process32FirstW")
procProcess32Next = modkernel32.NewProc("Process32NextW")
procGetSystemTimes = modkernel32.NewProc("GetSystemTimes")
procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
procSetConsoleTextAttribute = modkernel32.NewProc("SetConsoleTextAttribute")
procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW")
procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
)
func GetModuleHandle(modulename string) HINSTANCE {
var mn uintptr
if modulename == "" {
mn = 0
} else {
mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
}
ret, _, _ := procGetModuleHandle.Call(mn)
return HINSTANCE(ret)
}
func MulDiv(number, numerator, denominator int) int {
ret, _, _ := procMulDiv.Call(
uintptr(number),
uintptr(numerator),
uintptr(denominator))
return int(ret)
}
func GetConsoleWindow() HWND {
ret, _, _ := procGetConsoleWindow.Call()
return HWND(ret)
}
func GetCurrentThread() HANDLE {
ret, _, _ := procGetCurrentThread.Call()
return HANDLE(ret)
}
func GetLogicalDrives() uint32 {
ret, _, _ := procGetLogicalDrives.Call()
return uint32(ret)
}
func GetUserDefaultLCID() uint32 {
ret, _, _ := procGetUserDefaultLCID.Call()
return uint32(ret)
}
func Lstrlen(lpString *uint16) int {
ret, _, _ := procLstrlen.Call(uintptr(unsafe.Pointer(lpString)))
return int(ret)
}
func Lstrcpy(buf []uint16, lpString *uint16) {
procLstrcpy.Call(
uintptr(unsafe.Pointer(&buf[0])),
uintptr(unsafe.Pointer(lpString)))
}
func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL {
ret, _, _ := procGlobalAlloc.Call(
uintptr(uFlags),
uintptr(dwBytes))
if ret == 0 {
panic("GlobalAlloc failed")
}
return HGLOBAL(ret)
}
func GlobalFree(hMem HGLOBAL) {
ret, _, _ := procGlobalFree.Call(uintptr(hMem))
if ret != 0 {
panic("GlobalFree failed")
}
}
func GlobalLock(hMem HGLOBAL) unsafe.Pointer {
ret, _, _ := procGlobalLock.Call(uintptr(hMem))
if ret == 0 {
panic("GlobalLock failed")
}
return unsafe.Pointer(ret)
}
func GlobalUnlock(hMem HGLOBAL) bool {
ret, _, _ := procGlobalUnlock.Call(uintptr(hMem))
return ret != 0
}
func MoveMemory(destination, source unsafe.Pointer, length uint32) {
procMoveMemory.Call(
uintptr(unsafe.Pointer(destination)),
uintptr(source),
uintptr(length))
}
func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) {
ret, _, _ := procFindResource.Call(
uintptr(hModule),
uintptr(unsafe.Pointer(lpName)),
uintptr(unsafe.Pointer(lpType)))
if ret == 0 {
return 0, syscall.GetLastError()
}
return HRSRC(ret), nil
}
func SizeofResource(hModule HMODULE, hResInfo HRSRC) uint32 {
ret, _, _ := procSizeofResource.Call(
uintptr(hModule),
uintptr(hResInfo))
if ret == 0 {
panic("SizeofResource failed")
}
return uint32(ret)
}
func LockResource(hResData HGLOBAL) unsafe.Pointer {
ret, _, _ := procLockResource.Call(uintptr(hResData))
if ret == 0 {
panic("LockResource failed")
}
return unsafe.Pointer(ret)
}
func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL {
ret, _, _ := procLoadResource.Call(
uintptr(hModule),
uintptr(hResInfo))
if ret == 0 {
panic("LoadResource failed")
}
return HGLOBAL(ret)
}
func GetLastError() uint32 {
ret, _, _ := procGetLastError.Call()
return uint32(ret)
}
func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE {
inherit := 0
if inheritHandle {
inherit = 1
}
ret, _, _ := procOpenProcess.Call(
uintptr(desiredAccess),
uintptr(inherit),
uintptr(processId))
return HANDLE(ret)
}
func TerminateProcess(hProcess HANDLE, uExitCode uint) bool {
ret, _, _ := procTerminateProcess.Call(
uintptr(hProcess),
uintptr(uExitCode))
return ret != 0
}
func CloseHandle(object HANDLE) bool {
ret, _, _ := procCloseHandle.Call(
uintptr(object))
return ret != 0
}
func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE {
ret, _, _ := procCreateToolhelp32Snapshot.Call(
uintptr(flags),
uintptr(processId))
if ret <= 0 {
return HANDLE(0)
}
return HANDLE(ret)
}
func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool {
ret, _, _ := procModule32First.Call(
uintptr(snapshot),
uintptr(unsafe.Pointer(me)))
return ret != 0
}
func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool {
ret, _, _ := procModule32Next.Call(
uintptr(snapshot),
uintptr(unsafe.Pointer(me)))
return ret != 0
}
func Process32First(snapshot HANDLE, pe *PROCESSENTRY32) bool {
ret, _, _ := procProcess32First.Call(
uintptr(snapshot),
uintptr(unsafe.Pointer(pe)))
return ret != 0
}
func Process32Next(snapshot HANDLE, pe *PROCESSENTRY32) bool {
ret, _, _ := procProcess32Next.Call(
uintptr(snapshot),
uintptr(unsafe.Pointer(pe)))
return ret != 0
}
func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool {
ret, _, _ := procGetSystemTimes.Call(
uintptr(unsafe.Pointer(lpIdleTime)),
uintptr(unsafe.Pointer(lpKernelTime)),
uintptr(unsafe.Pointer(lpUserTime)))
return ret != 0
}
func GetProcessTimes(hProcess HANDLE, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime *FILETIME) bool {
ret, _, _ := procGetProcessTimes.Call(
uintptr(hProcess),
uintptr(unsafe.Pointer(lpCreationTime)),
uintptr(unsafe.Pointer(lpExitTime)),
uintptr(unsafe.Pointer(lpKernelTime)),
uintptr(unsafe.Pointer(lpUserTime)))
return ret != 0
}
func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO {
var csbi CONSOLE_SCREEN_BUFFER_INFO
ret, _, _ := procGetConsoleScreenBufferInfo.Call(
uintptr(hConsoleOutput),
uintptr(unsafe.Pointer(&csbi)))
if ret == 0 {
return nil
}
return &csbi
}
func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool {
ret, _, _ := procSetConsoleTextAttribute.Call(
uintptr(hConsoleOutput),
uintptr(wAttributes))
return ret != 0
}
func GetDiskFreeSpaceEx(dirName string) (r bool,
freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) {
ret, _, _ := procGetDiskFreeSpaceEx.Call(
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(dirName))),
uintptr(unsafe.Pointer(&freeBytesAvailable)),
uintptr(unsafe.Pointer(&totalNumberOfBytes)),
uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)))
return ret != 0,
freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes
}

65
vendor/github.com/shirou/w32/ole32.go generated vendored Normal file
View File

@@ -0,0 +1,65 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modole32 = syscall.NewLazyDLL("ole32.dll")
procCoInitializeEx = modole32.NewProc("CoInitializeEx")
procCoInitialize = modole32.NewProc("CoInitialize")
procCoUninitialize = modole32.NewProc("CoUninitialize")
procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal")
)
func CoInitializeEx(coInit uintptr) HRESULT {
ret, _, _ := procCoInitializeEx.Call(
0,
coInit)
switch uint32(ret) {
case E_INVALIDARG:
panic("CoInitializeEx failed with E_INVALIDARG")
case E_OUTOFMEMORY:
panic("CoInitializeEx failed with E_OUTOFMEMORY")
case E_UNEXPECTED:
panic("CoInitializeEx failed with E_UNEXPECTED")
}
return HRESULT(ret)
}
func CoInitialize() {
procCoInitialize.Call(0)
}
func CoUninitialize() {
procCoUninitialize.Call()
}
func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream {
stream := new(IStream)
ret, _, _ := procCreateStreamOnHGlobal.Call(
uintptr(hGlobal),
uintptr(BoolToBOOL(fDeleteOnRelease)),
uintptr(unsafe.Pointer(&stream)))
switch uint32(ret) {
case E_INVALIDARG:
panic("CreateStreamOnHGlobal failed with E_INVALIDARG")
case E_OUTOFMEMORY:
panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY")
case E_UNEXPECTED:
panic("CreateStreamOnHGlobal failed with E_UNEXPECTED")
}
return stream
}

50
vendor/github.com/shirou/w32/oleaut32.go generated vendored Normal file
View File

@@ -0,0 +1,50 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modoleaut32 = syscall.NewLazyDLL("oleaut32")
procVariantInit = modoleaut32.NewProc("VariantInit")
procSysAllocString = modoleaut32.NewProc("SysAllocString")
procSysFreeString = modoleaut32.NewProc("SysFreeString")
procSysStringLen = modoleaut32.NewProc("SysStringLen")
procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo")
procCreateStdDispatch = modoleaut32.NewProc("CreateStdDispatch")
)
func VariantInit(v *VARIANT) {
hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
if hr != 0 {
panic("Invoke VariantInit error.")
}
return
}
func SysAllocString(v string) (ss *int16) {
pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
ss = (*int16)(unsafe.Pointer(pss))
return
}
func SysFreeString(v *int16) {
hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v)))
if hr != 0 {
panic("Invoke SysFreeString error.")
}
return
}
func SysStringLen(v *int16) uint {
l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v)))
return uint(l)
}

74
vendor/github.com/shirou/w32/opengl32.go generated vendored Normal file
View File

@@ -0,0 +1,74 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modopengl32 = syscall.NewLazyDLL("opengl32.dll")
procwglCreateContext = modopengl32.NewProc("wglCreateContext")
procwglCreateLayerContext = modopengl32.NewProc("wglCreateLayerContext")
procwglDeleteContext = modopengl32.NewProc("wglDeleteContext")
procwglGetProcAddress = modopengl32.NewProc("wglGetProcAddress")
procwglMakeCurrent = modopengl32.NewProc("wglMakeCurrent")
procwglShareLists = modopengl32.NewProc("wglShareLists")
)
func WglCreateContext(hdc HDC) HGLRC {
ret, _, _ := procwglCreateContext.Call(
uintptr(hdc),
)
return HGLRC(ret)
}
func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC {
ret, _, _ := procwglCreateLayerContext.Call(
uintptr(hdc),
uintptr(iLayerPlane),
)
return HGLRC(ret)
}
func WglDeleteContext(hglrc HGLRC) bool {
ret, _, _ := procwglDeleteContext.Call(
uintptr(hglrc),
)
return ret == TRUE
}
func WglGetProcAddress(szProc string) uintptr {
ret, _, _ := procwglGetProcAddress.Call(
uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))),
)
return ret
}
func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool {
ret, _, _ := procwglMakeCurrent.Call(
uintptr(hdc),
uintptr(hglrc),
)
return ret == TRUE
}
func WglShareLists(hglrc1, hglrc2 HGLRC) bool {
ret, _, _ := procwglShareLists.Call(
uintptr(hglrc1),
uintptr(hglrc2),
)
return ret == TRUE
}

27
vendor/github.com/shirou/w32/psapi.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"syscall"
"unsafe"
)
var (
modpsapi = syscall.NewLazyDLL("psapi.dll")
procEnumProcesses = modpsapi.NewProc("EnumProcesses")
)
func EnumProcesses(processIds []uint32, cb uint32, bytesReturned *uint32) bool {
ret, _, _ := procEnumProcesses.Call(
uintptr(unsafe.Pointer(&processIds[0])),
uintptr(cb),
uintptr(unsafe.Pointer(bytesReturned)))
return ret != 0
}

155
vendor/github.com/shirou/w32/shell32.go generated vendored Normal file
View File

@@ -0,0 +1,155 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
var (
modshell32 = syscall.NewLazyDLL("shell32.dll")
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolderW")
procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW")
procDragAcceptFiles = modshell32.NewProc("DragAcceptFiles")
procDragQueryFile = modshell32.NewProc("DragQueryFileW")
procDragQueryPoint = modshell32.NewProc("DragQueryPoint")
procDragFinish = modshell32.NewProc("DragFinish")
procShellExecute = modshell32.NewProc("ShellExecuteW")
procExtractIcon = modshell32.NewProc("ExtractIconW")
)
func SHBrowseForFolder(bi *BROWSEINFO) uintptr {
ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi)))
return ret
}
func SHGetPathFromIDList(idl uintptr) string {
buf := make([]uint16, 1024)
procSHGetPathFromIDList.Call(
idl,
uintptr(unsafe.Pointer(&buf[0])))
return syscall.UTF16ToString(buf)
}
func DragAcceptFiles(hwnd HWND, accept bool) {
procDragAcceptFiles.Call(
uintptr(hwnd),
uintptr(BoolToBOOL(accept)))
}
func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) {
ret, _, _ := procDragQueryFile.Call(
uintptr(hDrop),
uintptr(iFile),
0,
0)
fileCount = uint(ret)
if iFile != 0xFFFFFFFF {
buf := make([]uint16, fileCount+1)
ret, _, _ := procDragQueryFile.Call(
uintptr(hDrop),
uintptr(iFile),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(fileCount+1))
if ret == 0 {
panic("Invoke DragQueryFile error.")
}
fileName = syscall.UTF16ToString(buf)
}
return
}
func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) {
var pt POINT
ret, _, _ := procDragQueryPoint.Call(
uintptr(hDrop),
uintptr(unsafe.Pointer(&pt)))
return int(pt.X), int(pt.Y), (ret == 1)
}
func DragFinish(hDrop HDROP) {
procDragFinish.Call(uintptr(hDrop))
}
func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
var op, param, directory uintptr
if len(lpOperation) != 0 {
op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
}
if len(lpParameters) != 0 {
param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
}
if len(lpDirectory) != 0 {
directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
}
ret, _, _ := procShellExecute.Call(
uintptr(hwnd),
op,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
param,
directory,
uintptr(nShowCmd))
errorMsg := ""
if ret != 0 && ret <= 32 {
switch int(ret) {
case ERROR_FILE_NOT_FOUND:
errorMsg = "The specified file was not found."
case ERROR_PATH_NOT_FOUND:
errorMsg = "The specified path was not found."
case ERROR_BAD_FORMAT:
errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."
case SE_ERR_ACCESSDENIED:
errorMsg = "The operating system denied access to the specified file."
case SE_ERR_ASSOCINCOMPLETE:
errorMsg = "The file name association is incomplete or invalid."
case SE_ERR_DDEBUSY:
errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed."
case SE_ERR_DDEFAIL:
errorMsg = "The DDE transaction failed."
case SE_ERR_DDETIMEOUT:
errorMsg = "The DDE transaction could not be completed because the request timed out."
case SE_ERR_DLLNOTFOUND:
errorMsg = "The specified DLL was not found."
case SE_ERR_NOASSOC:
errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."
case SE_ERR_OOM:
errorMsg = "There was not enough memory to complete the operation."
case SE_ERR_SHARE:
errorMsg = "A sharing violation occurred."
default:
errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret)
}
} else {
return nil
}
return errors.New(errorMsg)
}
func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON {
ret, _, _ := procExtractIcon.Call(
0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))),
uintptr(nIconIndex))
return HICON(ret)
}

901
vendor/github.com/shirou/w32/typedef.go generated vendored Normal file
View File

@@ -0,0 +1,901 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package w32
import (
"unsafe"
)
// From MSDN: Windows Data Types
// http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx
// ATOM WORD
// BOOL int32
// BOOLEAN byte
// BYTE byte
// CCHAR int8
// CHAR int8
// COLORREF DWORD
// DWORD uint32
// DWORDLONG ULONGLONG
// DWORD_PTR ULONG_PTR
// DWORD32 uint32
// DWORD64 uint64
// FLOAT float32
// HACCEL HANDLE
// HALF_PTR struct{} // ???
// HANDLE PVOID
// HBITMAP HANDLE
// HBRUSH HANDLE
// HCOLORSPACE HANDLE
// HCONV HANDLE
// HCONVLIST HANDLE
// HCURSOR HANDLE
// HDC HANDLE
// HDDEDATA HANDLE
// HDESK HANDLE
// HDROP HANDLE
// HDWP HANDLE
// HENHMETAFILE HANDLE
// HFILE HANDLE
// HFONT HANDLE
// HGDIOBJ HANDLE
// HGLOBAL HANDLE
// HHOOK HANDLE
// HICON HANDLE
// HINSTANCE HANDLE
// HKEY HANDLE
// HKL HANDLE
// HLOCAL HANDLE
// HMENU HANDLE
// HMETAFILE HANDLE
// HMODULE HANDLE
// HPALETTE HANDLE
// HPEN HANDLE
// HRESULT int32
// HRGN HANDLE
// HSZ HANDLE
// HWINSTA HANDLE
// HWND HANDLE
// INT int32
// INT_PTR uintptr
// INT8 int8
// INT16 int16
// INT32 int32
// INT64 int64
// LANGID WORD
// LCID DWORD
// LCTYPE DWORD
// LGRPID DWORD
// LONG int32
// LONGLONG int64
// LONG_PTR uintptr
// LONG32 int32
// LONG64 int64
// LPARAM LONG_PTR
// LPBOOL *BOOL
// LPBYTE *BYTE
// LPCOLORREF *COLORREF
// LPCSTR *int8
// LPCTSTR LPCWSTR
// LPCVOID unsafe.Pointer
// LPCWSTR *WCHAR
// LPDWORD *DWORD
// LPHANDLE *HANDLE
// LPINT *INT
// LPLONG *LONG
// LPSTR *CHAR
// LPTSTR LPWSTR
// LPVOID unsafe.Pointer
// LPWORD *WORD
// LPWSTR *WCHAR
// LRESULT LONG_PTR
// PBOOL *BOOL
// PBOOLEAN *BOOLEAN
// PBYTE *BYTE
// PCHAR *CHAR
// PCSTR *CHAR
// PCTSTR PCWSTR
// PCWSTR *WCHAR
// PDWORD *DWORD
// PDWORDLONG *DWORDLONG
// PDWORD_PTR *DWORD_PTR
// PDWORD32 *DWORD32
// PDWORD64 *DWORD64
// PFLOAT *FLOAT
// PHALF_PTR *HALF_PTR
// PHANDLE *HANDLE
// PHKEY *HKEY
// PINT_PTR *INT_PTR
// PINT8 *INT8
// PINT16 *INT16
// PINT32 *INT32
// PINT64 *INT64
// PLCID *LCID
// PLONG *LONG
// PLONGLONG *LONGLONG
// PLONG_PTR *LONG_PTR
// PLONG32 *LONG32
// PLONG64 *LONG64
// POINTER_32 struct{} // ???
// POINTER_64 struct{} // ???
// POINTER_SIGNED uintptr
// POINTER_UNSIGNED uintptr
// PSHORT *SHORT
// PSIZE_T *SIZE_T
// PSSIZE_T *SSIZE_T
// PSTR *CHAR
// PTBYTE *TBYTE
// PTCHAR *TCHAR
// PTSTR PWSTR
// PUCHAR *UCHAR
// PUHALF_PTR *UHALF_PTR
// PUINT *UINT
// PUINT_PTR *UINT_PTR
// PUINT8 *UINT8
// PUINT16 *UINT16
// PUINT32 *UINT32
// PUINT64 *UINT64
// PULONG *ULONG
// PULONGLONG *ULONGLONG
// PULONG_PTR *ULONG_PTR
// PULONG32 *ULONG32
// PULONG64 *ULONG64
// PUSHORT *USHORT
// PVOID unsafe.Pointer
// PWCHAR *WCHAR
// PWORD *WORD
// PWSTR *WCHAR
// QWORD uint64
// SC_HANDLE HANDLE
// SC_LOCK LPVOID
// SERVICE_STATUS_HANDLE HANDLE
// SHORT int16
// SIZE_T ULONG_PTR
// SSIZE_T LONG_PTR
// TBYTE WCHAR
// TCHAR WCHAR
// UCHAR uint8
// UHALF_PTR struct{} // ???
// UINT uint32
// UINT_PTR uintptr
// UINT8 uint8
// UINT16 uint16
// UINT32 uint32
// UINT64 uint64
// ULONG uint32
// ULONGLONG uint64
// ULONG_PTR uintptr
// ULONG32 uint32
// ULONG64 uint64
// USHORT uint16
// USN LONGLONG
// WCHAR uint16
// WORD uint16
// WPARAM UINT_PTR
type (
ATOM uint16
BOOL int32
COLORREF uint32
DWM_FRAME_COUNT uint64
HACCEL HANDLE
HANDLE uintptr
HBITMAP HANDLE
HBRUSH HANDLE
HCURSOR HANDLE
HDC HANDLE
HDROP HANDLE
HDWP HANDLE
HENHMETAFILE HANDLE
HFONT HANDLE
HGDIOBJ HANDLE
HGLOBAL HANDLE
HGLRC HANDLE
HICON HANDLE
HIMAGELIST HANDLE
HINSTANCE HANDLE
HKEY HANDLE
HKL HANDLE
HMENU HANDLE
HMODULE HANDLE
HMONITOR HANDLE
HPEN HANDLE
HRESULT int32
HRGN HANDLE
HRSRC HANDLE
HTHUMBNAIL HANDLE
HWND HANDLE
LPCVOID unsafe.Pointer
PVOID unsafe.Pointer
QPC_TIME uint64
)
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx
type POINT struct {
X, Y int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx
type RECT struct {
Left, Top, Right, Bottom int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577.aspx
type WNDCLASSEX struct {
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance HINSTANCE
Icon HICON
Cursor HCURSOR
Background HBRUSH
MenuName *uint16
ClassName *uint16
IconSm HICON
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx
type MSG struct {
Hwnd HWND
Message uint32
WParam uintptr
LParam uintptr
Time uint32
Pt POINT
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx
type LOGFONT struct {
Height int32
Width int32
Escapement int32
Orientation int32
Weight int32
Italic byte
Underline byte
StrikeOut byte
CharSet byte
OutPrecision byte
ClipPrecision byte
Quality byte
PitchAndFamily byte
FaceName [LF_FACESIZE]uint16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx
type OPENFILENAME struct {
StructSize uint32
Owner HWND
Instance HINSTANCE
Filter *uint16
CustomFilter *uint16
MaxCustomFilter uint32
FilterIndex uint32
File *uint16
MaxFile uint32
FileTitle *uint16
MaxFileTitle uint32
InitialDir *uint16
Title *uint16
Flags uint32
FileOffset uint16
FileExtension uint16
DefExt *uint16
CustData uintptr
FnHook uintptr
TemplateName *uint16
PvReserved unsafe.Pointer
DwReserved uint32
FlagsEx uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205.aspx
type BROWSEINFO struct {
Owner HWND
Root *uint16
DisplayName *uint16
Title *uint16
Flags uint32
CallbackFunc uintptr
LParam uintptr
Image int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx
type GUID struct {
Data1 uint32
Data2 uint16
Data3 uint16
Data4 [8]byte
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627.aspx
type VARIANT struct {
VT uint16 // 2
WReserved1 uint16 // 4
WReserved2 uint16 // 6
WReserved3 uint16 // 8
Val int64 // 16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221416.aspx
type DISPPARAMS struct {
Rgvarg uintptr
RgdispidNamedArgs uintptr
CArgs uint32
CNamedArgs uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221133.aspx
type EXCEPINFO struct {
WCode uint16
WReserved uint16
BstrSource *uint16
BstrDescription *uint16
BstrHelpFile *uint16
DwHelpContext uint32
PvReserved uintptr
PfnDeferredFillIn uintptr
Scode int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035.aspx
type LOGBRUSH struct {
LbStyle uint32
LbColor COLORREF
LbHatch uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565.aspx
type DEVMODE struct {
DmDeviceName [CCHDEVICENAME]uint16
DmSpecVersion uint16
DmDriverVersion uint16
DmSize uint16
DmDriverExtra uint16
DmFields uint32
DmOrientation int16
DmPaperSize int16
DmPaperLength int16
DmPaperWidth int16
DmScale int16
DmCopies int16
DmDefaultSource int16
DmPrintQuality int16
DmColor int16
DmDuplex int16
DmYResolution int16
DmTTOption int16
DmCollate int16
DmFormName [CCHFORMNAME]uint16
DmLogPixels uint16
DmBitsPerPel uint32
DmPelsWidth uint32
DmPelsHeight uint32
DmDisplayFlags uint32
DmDisplayFrequency uint32
DmICMMethod uint32
DmICMIntent uint32
DmMediaType uint32
DmDitherType uint32
DmReserved1 uint32
DmReserved2 uint32
DmPanningWidth uint32
DmPanningHeight uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx
type BITMAPINFOHEADER struct {
BiSize uint32
BiWidth int32
BiHeight int32
BiPlanes uint16
BiBitCount uint16
BiCompression uint32
BiSizeImage uint32
BiXPelsPerMeter int32
BiYPelsPerMeter int32
BiClrUsed uint32
BiClrImportant uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx
type RGBQUAD struct {
RgbBlue byte
RgbGreen byte
RgbRed byte
RgbReserved byte
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375.aspx
type BITMAPINFO struct {
BmiHeader BITMAPINFOHEADER
BmiColors *RGBQUAD
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183371.aspx
type BITMAP struct {
BmType int32
BmWidth int32
BmHeight int32
BmWidthBytes int32
BmPlanes uint16
BmBitsPixel uint16
BmBits unsafe.Pointer
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx
type DIBSECTION struct {
DsBm BITMAP
DsBmih BITMAPINFOHEADER
DsBitfields [3]uint32
DshSection HANDLE
DsOffset uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162607.aspx
type ENHMETAHEADER struct {
IType uint32
NSize uint32
RclBounds RECT
RclFrame RECT
DSignature uint32
NVersion uint32
NBytes uint32
NRecords uint32
NHandles uint16
SReserved uint16
NDescription uint32
OffDescription uint32
NPalEntries uint32
SzlDevice SIZE
SzlMillimeters SIZE
CbPixelFormat uint32
OffPixelFormat uint32
BOpenGL uint32
SzlMicrometers SIZE
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145106.aspx
type SIZE struct {
CX, CY int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145132.aspx
type TEXTMETRIC struct {
TmHeight int32
TmAscent int32
TmDescent int32
TmInternalLeading int32
TmExternalLeading int32
TmAveCharWidth int32
TmMaxCharWidth int32
TmWeight int32
TmOverhang int32
TmDigitizedAspectX int32
TmDigitizedAspectY int32
TmFirstChar uint16
TmLastChar uint16
TmDefaultChar uint16
TmBreakChar uint16
TmItalic byte
TmUnderlined byte
TmStruckOut byte
TmPitchAndFamily byte
TmCharSet byte
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183574.aspx
type DOCINFO struct {
CbSize int32
LpszDocName *uint16
LpszOutput *uint16
LpszDatatype *uint16
FwType uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775514.aspx
type NMHDR struct {
HwndFrom HWND
IdFrom uintptr
Code uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx
type LVCOLUMN struct {
Mask uint32
Fmt int32
Cx int32
PszText *uint16
CchTextMax int32
ISubItem int32
IImage int32
IOrder int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx
type LVITEM struct {
Mask uint32
IItem int32
ISubItem int32
State uint32
StateMask uint32
PszText *uint16
CchTextMax int32
IImage int32
LParam uintptr
IIndent int32
IGroupId int32
CColumns uint32
PuColumns uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx
type LVHITTESTINFO struct {
Pt POINT
Flags uint32
IItem int32
ISubItem int32
IGroup int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774771.aspx
type NMITEMACTIVATE struct {
Hdr NMHDR
IItem int32
ISubItem int32
UNewState uint32
UOldState uint32
UChanged uint32
PtAction POINT
LParam uintptr
UKeyFlags uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774773.aspx
type NMLISTVIEW struct {
Hdr NMHDR
IItem int32
ISubItem int32
UNewState uint32
UOldState uint32
UChanged uint32
PtAction POINT
LParam uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780.aspx
type NMLVDISPINFO struct {
Hdr NMHDR
Item LVITEM
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx
type INITCOMMONCONTROLSEX struct {
DwSize uint32
DwICC uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx
type TOOLINFO struct {
CbSize uint32
UFlags uint32
Hwnd HWND
UId uintptr
Rect RECT
Hinst HINSTANCE
LpszText *uint16
LParam uintptr
LpReserved unsafe.Pointer
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604.aspx
type TRACKMOUSEEVENT struct {
CbSize uint32
DwFlags uint32
HwndTrack HWND
DwHoverTime uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534067.aspx
type GdiplusStartupInput struct {
GdiplusVersion uint32
DebugEventCallback uintptr
SuppressBackgroundThread BOOL
SuppressExternalCodecs BOOL
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534068.aspx
type GdiplusStartupOutput struct {
NotificationHook uintptr
NotificationUnhook uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768.aspx
type PAINTSTRUCT struct {
Hdc HDC
FErase BOOL
RcPaint RECT
FRestore BOOL
FIncUpdate BOOL
RgbReserved [32]byte
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363646.aspx
type EVENTLOGRECORD struct {
Length uint32
Reserved uint32
RecordNumber uint32
TimeGenerated uint32
TimeWritten uint32
EventID uint32
EventType uint16
NumStrings uint16
EventCategory uint16
ReservedFlags uint16
ClosingRecordNumber uint32
StringOffset uint32
UserSidLength uint32
UserSidOffset uint32
DataLength uint32
DataOffset uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996.aspx
type SERVICE_STATUS struct {
DwServiceType uint32
DwCurrentState uint32
DwControlsAccepted uint32
DwWin32ExitCode uint32
DwServiceSpecificExitCode uint32
DwCheckPoint uint32
DwWaitHint uint32
}
type PROCESSENTRY32 struct {
DwSize uint32
CntUsage uint32
Th32ProcessID uint32
Th32DefaultHeapID uintptr
Th32ModuleID uint32
CntThreads uint32
Th32ParentProcessID uint32
PcPriClassBase int32
DwFlags uint32
SzExeFile [MAX_PATH]uint16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225.aspx
type MODULEENTRY32 struct {
Size uint32
ModuleID uint32
ProcessID uint32
GlblcntUsage uint32
ProccntUsage uint32
ModBaseAddr *uint8
ModBaseSize uint32
HModule HMODULE
SzModule [MAX_MODULE_NAME32 + 1]uint16
SzExePath [MAX_PATH]uint16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
type FILETIME struct {
DwLowDateTime uint32
DwHighDateTime uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx
type COORD struct {
X, Y int16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311.aspx
type SMALL_RECT struct {
Left, Top, Right, Bottom int16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093.aspx
type CONSOLE_SCREEN_BUFFER_INFO struct {
DwSize COORD
DwCursorPosition COORD
WAttributes uint16
SrWindow SMALL_RECT
DwMaximumWindowSize COORD
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx
type MARGINS struct {
CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969500.aspx
type DWM_BLURBEHIND struct {
DwFlags uint32
fEnable BOOL
hRgnBlur HRGN
fTransitionOnMaximized BOOL
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969501.aspx
type DWM_PRESENT_PARAMETERS struct {
cbSize uint32
fQueue BOOL
cRefreshStart DWM_FRAME_COUNT
cBuffer uint32
fUseSourceRate BOOL
rateSource UNSIGNED_RATIO
cRefreshesPerFrame uint32
eSampling DWM_SOURCE_FRAME_SAMPLING
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969502.aspx
type DWM_THUMBNAIL_PROPERTIES struct {
dwFlags uint32
rcDestination RECT
rcSource RECT
opacity byte
fVisible BOOL
fSourceClientAreaOnly BOOL
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969503.aspx
type DWM_TIMING_INFO struct {
cbSize uint32
rateRefresh UNSIGNED_RATIO
qpcRefreshPeriod QPC_TIME
rateCompose UNSIGNED_RATIO
qpcVBlank QPC_TIME
cRefresh DWM_FRAME_COUNT
cDXRefresh uint32
qpcCompose QPC_TIME
cFrame DWM_FRAME_COUNT
cDXPresent uint32
cRefreshFrame DWM_FRAME_COUNT
cFrameSubmitted DWM_FRAME_COUNT
cDXPresentSubmitted uint32
cFrameConfirmed DWM_FRAME_COUNT
cDXPresentConfirmed uint32
cRefreshConfirmed DWM_FRAME_COUNT
cDXRefreshConfirmed uint32
cFramesLate DWM_FRAME_COUNT
cFramesOutstanding uint32
cFrameDisplayed DWM_FRAME_COUNT
qpcFrameDisplayed QPC_TIME
cRefreshFrameDisplayed DWM_FRAME_COUNT
cFrameComplete DWM_FRAME_COUNT
qpcFrameComplete QPC_TIME
cFramePending DWM_FRAME_COUNT
qpcFramePending QPC_TIME
cFramesDisplayed DWM_FRAME_COUNT
cFramesComplete DWM_FRAME_COUNT
cFramesPending DWM_FRAME_COUNT
cFramesAvailable DWM_FRAME_COUNT
cFramesDropped DWM_FRAME_COUNT
cFramesMissed DWM_FRAME_COUNT
cRefreshNextDisplayed DWM_FRAME_COUNT
cRefreshNextPresented DWM_FRAME_COUNT
cRefreshesDisplayed DWM_FRAME_COUNT
cRefreshesPresented DWM_FRAME_COUNT
cRefreshStarted DWM_FRAME_COUNT
cPixelsReceived uint64
cPixelsDrawn uint64
cBuffersEmpty DWM_FRAME_COUNT
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd389402.aspx
type MilMatrix3x2D struct {
S_11, S_12, S_21, S_22 float64
DX, DY float64
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969505.aspx
type UNSIGNED_RATIO struct {
uiNumerator uint32
uiDenominator uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603.aspx
type CREATESTRUCT struct {
CreateParams uintptr
Instance HINSTANCE
Menu HMENU
Parent HWND
Cy, Cx int32
Y, X int32
Style int32
Name *uint16
Class *uint16
dwExStyle uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065.aspx
type MONITORINFO struct {
CbSize uint32
RcMonitor RECT
RcWork RECT
DwFlags uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066.aspx
type MONITORINFOEX struct {
MONITORINFO
SzDevice [CCHDEVICENAME]uint16
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826.aspx
type PIXELFORMATDESCRIPTOR struct {
Size uint16
Version uint16
DwFlags uint32
IPixelType byte
ColorBits byte
RedBits, RedShift byte
GreenBits, GreenShift byte
BlueBits, BlueShift byte
AlphaBits, AlphaShift byte
AccumBits byte
AccumRedBits byte
AccumGreenBits byte
AccumBlueBits byte
AccumAlphaBits byte
DepthBits, StencilBits byte
AuxBuffers byte
ILayerType byte
Reserved byte
DwLayerMask uint32
DwVisibleMask uint32
DwDamageMask uint32
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
type INPUT struct {
Type uint32
Mi MOUSEINPUT
Ki KEYBDINPUT
Hi HARDWAREINPUT
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx
type MOUSEINPUT struct {
Dx int32
Dy int32
MouseData uint32
DwFlags uint32
Time uint32
DwExtraInfo uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271(v=vs.85).aspx
type KEYBDINPUT struct {
WVk uint16
WScan uint16
DwFlags uint32
Time uint32
DwExtraInfo uintptr
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269(v=vs.85).aspx
type HARDWAREINPUT struct {
UMsg uint32
WParamL uint16
WParamH uint16
}
type KbdInput struct {
typ uint32
ki KEYBDINPUT
}
type MouseInput struct {
typ uint32
mi MOUSEINPUT
}
type HardwareInput struct {
typ uint32
hi HARDWAREINPUT
}

950
vendor/github.com/shirou/w32/user32.go generated vendored Normal file
View File

@@ -0,0 +1,950 @@
// Copyright 2010-2012 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package w32
import (
"fmt"
"syscall"
"unsafe"
)
var (
moduser32 = syscall.NewLazyDLL("user32.dll")
procRegisterClassEx = moduser32.NewProc("RegisterClassExW")
procLoadIcon = moduser32.NewProc("LoadIconW")
procLoadCursor = moduser32.NewProc("LoadCursorW")
procShowWindow = moduser32.NewProc("ShowWindow")
procUpdateWindow = moduser32.NewProc("UpdateWindow")
procCreateWindowEx = moduser32.NewProc("CreateWindowExW")
procAdjustWindowRect = moduser32.NewProc("AdjustWindowRect")
procAdjustWindowRectEx = moduser32.NewProc("AdjustWindowRectEx")
procDestroyWindow = moduser32.NewProc("DestroyWindow")
procDefWindowProc = moduser32.NewProc("DefWindowProcW")
procDefDlgProc = moduser32.NewProc("DefDlgProcW")
procPostQuitMessage = moduser32.NewProc("PostQuitMessage")
procGetMessage = moduser32.NewProc("GetMessageW")
procTranslateMessage = moduser32.NewProc("TranslateMessage")
procDispatchMessage = moduser32.NewProc("DispatchMessageW")
procSendMessage = moduser32.NewProc("SendMessageW")
procPostMessage = moduser32.NewProc("PostMessageW")
procWaitMessage = moduser32.NewProc("WaitMessage")
procSetWindowText = moduser32.NewProc("SetWindowTextW")
procGetWindowTextLength = moduser32.NewProc("GetWindowTextLengthW")
procGetWindowText = moduser32.NewProc("GetWindowTextW")
procGetWindowRect = moduser32.NewProc("GetWindowRect")
procMoveWindow = moduser32.NewProc("MoveWindow")
procScreenToClient = moduser32.NewProc("ScreenToClient")
procCallWindowProc = moduser32.NewProc("CallWindowProcW")
procSetWindowLong = moduser32.NewProc("SetWindowLongW")
procSetWindowLongPtr = moduser32.NewProc("SetWindowLongW")
procGetWindowLong = moduser32.NewProc("GetWindowLongW")
procGetWindowLongPtr = moduser32.NewProc("GetWindowLongW")
procEnableWindow = moduser32.NewProc("EnableWindow")
procIsWindowEnabled = moduser32.NewProc("IsWindowEnabled")
procIsWindowVisible = moduser32.NewProc("IsWindowVisible")
procSetFocus = moduser32.NewProc("SetFocus")
procInvalidateRect = moduser32.NewProc("InvalidateRect")
procGetClientRect = moduser32.NewProc("GetClientRect")
procGetDC = moduser32.NewProc("GetDC")
procReleaseDC = moduser32.NewProc("ReleaseDC")
procSetCapture = moduser32.NewProc("SetCapture")
procReleaseCapture = moduser32.NewProc("ReleaseCapture")
procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId")
procMessageBox = moduser32.NewProc("MessageBoxW")
procGetSystemMetrics = moduser32.NewProc("GetSystemMetrics")
procCopyRect = moduser32.NewProc("CopyRect")
procEqualRect = moduser32.NewProc("EqualRect")
procInflateRect = moduser32.NewProc("InflateRect")
procIntersectRect = moduser32.NewProc("IntersectRect")
procIsRectEmpty = moduser32.NewProc("IsRectEmpty")
procOffsetRect = moduser32.NewProc("OffsetRect")
procPtInRect = moduser32.NewProc("PtInRect")
procSetRect = moduser32.NewProc("SetRect")
procSetRectEmpty = moduser32.NewProc("SetRectEmpty")
procSubtractRect = moduser32.NewProc("SubtractRect")
procUnionRect = moduser32.NewProc("UnionRect")
procCreateDialogParam = moduser32.NewProc("CreateDialogParamW")
procDialogBoxParam = moduser32.NewProc("DialogBoxParamW")
procGetDlgItem = moduser32.NewProc("GetDlgItem")
procDrawIcon = moduser32.NewProc("DrawIcon")
procClientToScreen = moduser32.NewProc("ClientToScreen")
procIsDialogMessage = moduser32.NewProc("IsDialogMessageW")
procIsWindow = moduser32.NewProc("IsWindow")
procEndDialog = moduser32.NewProc("EndDialog")
procPeekMessage = moduser32.NewProc("PeekMessageW")
procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW")
procSetWindowPos = moduser32.NewProc("SetWindowPos")
procFillRect = moduser32.NewProc("FillRect")
procDrawText = moduser32.NewProc("DrawTextW")
procAddClipboardFormatListener = moduser32.NewProc("AddClipboardFormatListener")
procRemoveClipboardFormatListener = moduser32.NewProc("RemoveClipboardFormatListener")
procOpenClipboard = moduser32.NewProc("OpenClipboard")
procCloseClipboard = moduser32.NewProc("CloseClipboard")
procEnumClipboardFormats = moduser32.NewProc("EnumClipboardFormats")
procGetClipboardData = moduser32.NewProc("GetClipboardData")
procSetClipboardData = moduser32.NewProc("SetClipboardData")
procEmptyClipboard = moduser32.NewProc("EmptyClipboard")
procGetClipboardFormatName = moduser32.NewProc("GetClipboardFormatNameW")
procIsClipboardFormatAvailable = moduser32.NewProc("IsClipboardFormatAvailable")
procBeginPaint = moduser32.NewProc("BeginPaint")
procEndPaint = moduser32.NewProc("EndPaint")
procGetKeyboardState = moduser32.NewProc("GetKeyboardState")
procMapVirtualKey = moduser32.NewProc("MapVirtualKeyExW")
procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState")
procToAscii = moduser32.NewProc("ToAscii")
procSwapMouseButton = moduser32.NewProc("SwapMouseButton")
procGetCursorPos = moduser32.NewProc("GetCursorPos")
procSetCursorPos = moduser32.NewProc("SetCursorPos")
procSetCursor = moduser32.NewProc("SetCursor")
procCreateIcon = moduser32.NewProc("CreateIcon")
procDestroyIcon = moduser32.NewProc("DestroyIcon")
procMonitorFromPoint = moduser32.NewProc("MonitorFromPoint")
procMonitorFromRect = moduser32.NewProc("MonitorFromRect")
procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow")
procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW")
procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors")
procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW")
procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW")
procSendInput = moduser32.NewProc("SendInput")
)
func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM {
ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx)))
return ATOM(ret)
}
func LoadIcon(instance HINSTANCE, iconName *uint16) HICON {
ret, _, _ := procLoadIcon.Call(
uintptr(instance),
uintptr(unsafe.Pointer(iconName)))
return HICON(ret)
}
func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR {
ret, _, _ := procLoadCursor.Call(
uintptr(instance),
uintptr(unsafe.Pointer(cursorName)))
return HCURSOR(ret)
}
func ShowWindow(hwnd HWND, cmdshow int) bool {
ret, _, _ := procShowWindow.Call(
uintptr(hwnd),
uintptr(cmdshow))
return ret != 0
}
func UpdateWindow(hwnd HWND) bool {
ret, _, _ := procUpdateWindow.Call(
uintptr(hwnd))
return ret != 0
}
func CreateWindowEx(exStyle uint, className, windowName *uint16,
style uint, x, y, width, height int, parent HWND, menu HMENU,
instance HINSTANCE, param unsafe.Pointer) HWND {
ret, _, _ := procCreateWindowEx.Call(
uintptr(exStyle),
uintptr(unsafe.Pointer(className)),
uintptr(unsafe.Pointer(windowName)),
uintptr(style),
uintptr(x),
uintptr(y),
uintptr(width),
uintptr(height),
uintptr(parent),
uintptr(menu),
uintptr(instance),
uintptr(param))
return HWND(ret)
}
func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool {
ret, _, _ := procAdjustWindowRectEx.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(style),
uintptr(BoolToBOOL(menu)),
uintptr(exStyle))
return ret != 0
}
func AdjustWindowRect(rect *RECT, style uint, menu bool) bool {
ret, _, _ := procAdjustWindowRect.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(style),
uintptr(BoolToBOOL(menu)))
return ret != 0
}
func DestroyWindow(hwnd HWND) bool {
ret, _, _ := procDestroyWindow.Call(
uintptr(hwnd))
return ret != 0
}
func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
ret, _, _ := procDefWindowProc.Call(
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
return ret
}
func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
ret, _, _ := procDefDlgProc.Call(
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
return ret
}
func PostQuitMessage(exitCode int) {
procPostQuitMessage.Call(
uintptr(exitCode))
}
func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int {
ret, _, _ := procGetMessage.Call(
uintptr(unsafe.Pointer(msg)),
uintptr(hwnd),
uintptr(msgFilterMin),
uintptr(msgFilterMax))
return int(ret)
}
func TranslateMessage(msg *MSG) bool {
ret, _, _ := procTranslateMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret != 0
}
func DispatchMessage(msg *MSG) uintptr {
ret, _, _ := procDispatchMessage.Call(
uintptr(unsafe.Pointer(msg)))
return ret
}
func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
ret, _, _ := procSendMessage.Call(
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
return ret
}
func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool {
ret, _, _ := procPostMessage.Call(
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
return ret != 0
}
func WaitMessage() bool {
ret, _, _ := procWaitMessage.Call()
return ret != 0
}
func SetWindowText(hwnd HWND, text string) {
procSetWindowText.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))))
}
func GetWindowTextLength(hwnd HWND) int {
ret, _, _ := procGetWindowTextLength.Call(
uintptr(hwnd))
return int(ret)
}
func GetWindowText(hwnd HWND) string {
textLen := GetWindowTextLength(hwnd) + 1
buf := make([]uint16, textLen)
procGetWindowText.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(textLen))
return syscall.UTF16ToString(buf)
}
func GetWindowRect(hwnd HWND) *RECT {
var rect RECT
procGetWindowRect.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&rect)))
return &rect
}
func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool {
ret, _, _ := procMoveWindow.Call(
uintptr(hwnd),
uintptr(x),
uintptr(y),
uintptr(width),
uintptr(height),
uintptr(BoolToBOOL(repaint)))
return ret != 0
}
func ScreenToClient(hwnd HWND, x, y int) (X, Y int, ok bool) {
pt := POINT{X: int32(x), Y: int32(y)}
ret, _, _ := procScreenToClient.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&pt)))
return int(pt.X), int(pt.Y), ret != 0
}
func CallWindowProc(preWndProc uintptr, hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
ret, _, _ := procCallWindowProc.Call(
preWndProc,
uintptr(hwnd),
uintptr(msg),
wParam,
lParam)
return ret
}
func SetWindowLong(hwnd HWND, index int, value uint32) uint32 {
ret, _, _ := procSetWindowLong.Call(
uintptr(hwnd),
uintptr(index),
uintptr(value))
return uint32(ret)
}
func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
ret, _, _ := procSetWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index),
value)
return ret
}
func GetWindowLong(hwnd HWND, index int) int32 {
ret, _, _ := procGetWindowLong.Call(
uintptr(hwnd),
uintptr(index))
return int32(ret)
}
func GetWindowLongPtr(hwnd HWND, index int) uintptr {
ret, _, _ := procGetWindowLongPtr.Call(
uintptr(hwnd),
uintptr(index))
return ret
}
func EnableWindow(hwnd HWND, b bool) bool {
ret, _, _ := procEnableWindow.Call(
uintptr(hwnd),
uintptr(BoolToBOOL(b)))
return ret != 0
}
func IsWindowEnabled(hwnd HWND) bool {
ret, _, _ := procIsWindowEnabled.Call(
uintptr(hwnd))
return ret != 0
}
func IsWindowVisible(hwnd HWND) bool {
ret, _, _ := procIsWindowVisible.Call(
uintptr(hwnd))
return ret != 0
}
func SetFocus(hwnd HWND) HWND {
ret, _, _ := procSetFocus.Call(
uintptr(hwnd))
return HWND(ret)
}
func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool {
ret, _, _ := procInvalidateRect.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(rect)),
uintptr(BoolToBOOL(erase)))
return ret != 0
}
func GetClientRect(hwnd HWND) *RECT {
var rect RECT
ret, _, _ := procGetClientRect.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&rect)))
if ret == 0 {
panic(fmt.Sprintf("GetClientRect(%d) failed", hwnd))
}
return &rect
}
func GetDC(hwnd HWND) HDC {
ret, _, _ := procGetDC.Call(
uintptr(hwnd))
return HDC(ret)
}
func ReleaseDC(hwnd HWND, hDC HDC) bool {
ret, _, _ := procReleaseDC.Call(
uintptr(hwnd),
uintptr(hDC))
return ret != 0
}
func SetCapture(hwnd HWND) HWND {
ret, _, _ := procSetCapture.Call(
uintptr(hwnd))
return HWND(ret)
}
func ReleaseCapture() bool {
ret, _, _ := procReleaseCapture.Call()
return ret != 0
}
func GetWindowThreadProcessId(hwnd HWND) (HANDLE, int) {
var processId int
ret, _, _ := procGetWindowThreadProcessId.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&processId)))
return HANDLE(ret), processId
}
func MessageBox(hwnd HWND, title, caption string, flags uint) int {
ret, _, _ := procMessageBox.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
uintptr(flags))
return int(ret)
}
func GetSystemMetrics(index int) int {
ret, _, _ := procGetSystemMetrics.Call(
uintptr(index))
return int(ret)
}
func CopyRect(dst, src *RECT) bool {
ret, _, _ := procCopyRect.Call(
uintptr(unsafe.Pointer(dst)),
uintptr(unsafe.Pointer(src)))
return ret != 0
}
func EqualRect(rect1, rect2 *RECT) bool {
ret, _, _ := procEqualRect.Call(
uintptr(unsafe.Pointer(rect1)),
uintptr(unsafe.Pointer(rect2)))
return ret != 0
}
func InflateRect(rect *RECT, dx, dy int) bool {
ret, _, _ := procInflateRect.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(dx),
uintptr(dy))
return ret != 0
}
func IntersectRect(dst, src1, src2 *RECT) bool {
ret, _, _ := procIntersectRect.Call(
uintptr(unsafe.Pointer(dst)),
uintptr(unsafe.Pointer(src1)),
uintptr(unsafe.Pointer(src2)))
return ret != 0
}
func IsRectEmpty(rect *RECT) bool {
ret, _, _ := procIsRectEmpty.Call(
uintptr(unsafe.Pointer(rect)))
return ret != 0
}
func OffsetRect(rect *RECT, dx, dy int) bool {
ret, _, _ := procOffsetRect.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(dx),
uintptr(dy))
return ret != 0
}
func PtInRect(rect *RECT, x, y int) bool {
pt := POINT{X: int32(x), Y: int32(y)}
ret, _, _ := procPtInRect.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(unsafe.Pointer(&pt)))
return ret != 0
}
func SetRect(rect *RECT, left, top, right, bottom int) bool {
ret, _, _ := procSetRect.Call(
uintptr(unsafe.Pointer(rect)),
uintptr(left),
uintptr(top),
uintptr(right),
uintptr(bottom))
return ret != 0
}
func SetRectEmpty(rect *RECT) bool {
ret, _, _ := procSetRectEmpty.Call(
uintptr(unsafe.Pointer(rect)))
return ret != 0
}
func SubtractRect(dst, src1, src2 *RECT) bool {
ret, _, _ := procSubtractRect.Call(
uintptr(unsafe.Pointer(dst)),
uintptr(unsafe.Pointer(src1)),
uintptr(unsafe.Pointer(src2)))
return ret != 0
}
func UnionRect(dst, src1, src2 *RECT) bool {
ret, _, _ := procUnionRect.Call(
uintptr(unsafe.Pointer(dst)),
uintptr(unsafe.Pointer(src1)),
uintptr(unsafe.Pointer(src2)))
return ret != 0
}
func CreateDialog(hInstance HINSTANCE, lpTemplate *uint16, hWndParent HWND, lpDialogProc uintptr) HWND {
ret, _, _ := procCreateDialogParam.Call(
uintptr(hInstance),
uintptr(unsafe.Pointer(lpTemplate)),
uintptr(hWndParent),
lpDialogProc,
0)
return HWND(ret)
}
func DialogBox(hInstance HINSTANCE, lpTemplateName *uint16, hWndParent HWND, lpDialogProc uintptr) int {
ret, _, _ := procDialogBoxParam.Call(
uintptr(hInstance),
uintptr(unsafe.Pointer(lpTemplateName)),
uintptr(hWndParent),
lpDialogProc,
0)
return int(ret)
}
func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND {
ret, _, _ := procGetDlgItem.Call(
uintptr(unsafe.Pointer(hDlg)),
uintptr(nIDDlgItem))
return HWND(ret)
}
func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool {
ret, _, _ := procDrawIcon.Call(
uintptr(unsafe.Pointer(hDC)),
uintptr(x),
uintptr(y),
uintptr(unsafe.Pointer(hIcon)))
return ret != 0
}
func ClientToScreen(hwnd HWND, x, y int) (int, int) {
pt := POINT{X: int32(x), Y: int32(y)}
procClientToScreen.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(&pt)))
return int(pt.X), int(pt.Y)
}
func IsDialogMessage(hwnd HWND, msg *MSG) bool {
ret, _, _ := procIsDialogMessage.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(msg)))
return ret != 0
}
func IsWindow(hwnd HWND) bool {
ret, _, _ := procIsWindow.Call(
uintptr(hwnd))
return ret != 0
}
func EndDialog(hwnd HWND, nResult uintptr) bool {
ret, _, _ := procEndDialog.Call(
uintptr(hwnd),
nResult)
return ret != 0
}
func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool {
ret, _, _ := procPeekMessage.Call(
uintptr(unsafe.Pointer(lpMsg)),
uintptr(hwnd),
uintptr(wMsgFilterMin),
uintptr(wMsgFilterMax),
uintptr(wRemoveMsg))
return ret != 0
}
func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool {
ret, _, _ := procTranslateMessage.Call(
uintptr(hwnd),
uintptr(hAccTable),
uintptr(unsafe.Pointer(lpMsg)))
return ret != 0
}
func SetWindowPos(hwnd, hWndInsertAfter HWND, x, y, cx, cy int, uFlags uint) bool {
ret, _, _ := procSetWindowPos.Call(
uintptr(hwnd),
uintptr(hWndInsertAfter),
uintptr(x),
uintptr(y),
uintptr(cx),
uintptr(cy),
uintptr(uFlags))
return ret != 0
}
func FillRect(hDC HDC, lprc *RECT, hbr HBRUSH) bool {
ret, _, _ := procFillRect.Call(
uintptr(hDC),
uintptr(unsafe.Pointer(lprc)),
uintptr(hbr))
return ret != 0
}
func DrawText(hDC HDC, text string, uCount int, lpRect *RECT, uFormat uint) int {
ret, _, _ := procDrawText.Call(
uintptr(hDC),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
uintptr(uCount),
uintptr(unsafe.Pointer(lpRect)),
uintptr(uFormat))
return int(ret)
}
func AddClipboardFormatListener(hwnd HWND) bool {
ret, _, _ := procAddClipboardFormatListener.Call(
uintptr(hwnd))
return ret != 0
}
func RemoveClipboardFormatListener(hwnd HWND) bool {
ret, _, _ := procRemoveClipboardFormatListener.Call(
uintptr(hwnd))
return ret != 0
}
func OpenClipboard(hWndNewOwner HWND) bool {
ret, _, _ := procOpenClipboard.Call(
uintptr(hWndNewOwner))
return ret != 0
}
func CloseClipboard() bool {
ret, _, _ := procCloseClipboard.Call()
return ret != 0
}
func EnumClipboardFormats(format uint) uint {
ret, _, _ := procEnumClipboardFormats.Call(
uintptr(format))
return uint(ret)
}
func GetClipboardData(uFormat uint) HANDLE {
ret, _, _ := procGetClipboardData.Call(
uintptr(uFormat))
return HANDLE(ret)
}
func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE {
ret, _, _ := procSetClipboardData.Call(
uintptr(uFormat),
uintptr(hMem))
return HANDLE(ret)
}
func EmptyClipboard() bool {
ret, _, _ := procEmptyClipboard.Call()
return ret != 0
}
func GetClipboardFormatName(format uint) (string, bool) {
cchMaxCount := 255
buf := make([]uint16, cchMaxCount)
ret, _, _ := procGetClipboardFormatName.Call(
uintptr(format),
uintptr(unsafe.Pointer(&buf[0])),
uintptr(cchMaxCount))
if ret > 0 {
return syscall.UTF16ToString(buf), true
}
return "Requested format does not exist or is predefined", false
}
func IsClipboardFormatAvailable(format uint) bool {
ret, _, _ := procIsClipboardFormatAvailable.Call(uintptr(format))
return ret != 0
}
func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC {
ret, _, _ := procBeginPaint.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(paint)))
return HDC(ret)
}
func EndPaint(hwnd HWND, paint *PAINTSTRUCT) {
procBeginPaint.Call(
uintptr(hwnd),
uintptr(unsafe.Pointer(paint)))
}
func GetKeyboardState(lpKeyState *[]byte) bool {
ret, _, _ := procGetKeyboardState.Call(
uintptr(unsafe.Pointer(&(*lpKeyState)[0])))
return ret != 0
}
func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint {
ret, _, _ := procMapVirtualKey.Call(
uintptr(uCode),
uintptr(uMapType),
uintptr(dwhkl))
return uint(ret)
}
func GetAsyncKeyState(vKey int) uint16 {
ret, _, _ := procGetAsyncKeyState.Call(uintptr(vKey))
return uint16(ret)
}
func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int {
ret, _, _ := procToAscii.Call(
uintptr(uVirtKey),
uintptr(uScanCode),
uintptr(unsafe.Pointer(lpKeyState)),
uintptr(unsafe.Pointer(lpChar)),
uintptr(uFlags))
return int(ret)
}
func SwapMouseButton(fSwap bool) bool {
ret, _, _ := procSwapMouseButton.Call(
uintptr(BoolToBOOL(fSwap)))
return ret != 0
}
func GetCursorPos() (x, y int, ok bool) {
pt := POINT{}
ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt)))
return int(pt.X), int(pt.Y), ret != 0
}
func SetCursorPos(x, y int) bool {
ret, _, _ := procSetCursorPos.Call(
uintptr(x),
uintptr(y),
)
return ret != 0
}
func SetCursor(cursor HCURSOR) HCURSOR {
ret, _, _ := procSetCursor.Call(
uintptr(cursor),
)
return HCURSOR(ret)
}
func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON {
ret, _, _ := procCreateIcon.Call(
uintptr(instance),
uintptr(nWidth),
uintptr(nHeight),
uintptr(cPlanes),
uintptr(cBitsPerPixel),
uintptr(unsafe.Pointer(ANDbits)),
uintptr(unsafe.Pointer(XORbits)),
)
return HICON(ret)
}
func DestroyIcon(icon HICON) bool {
ret, _, _ := procDestroyIcon.Call(
uintptr(icon),
)
return ret != 0
}
func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR {
ret, _, _ := procMonitorFromPoint.Call(
uintptr(x),
uintptr(y),
uintptr(dwFlags),
)
return HMONITOR(ret)
}
func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR {
ret, _, _ := procMonitorFromRect.Call(
uintptr(unsafe.Pointer(rc)),
uintptr(dwFlags),
)
return HMONITOR(ret)
}
func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR {
ret, _, _ := procMonitorFromWindow.Call(
uintptr(hwnd),
uintptr(dwFlags),
)
return HMONITOR(ret)
}
func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool {
ret, _, _ := procGetMonitorInfo.Call(
uintptr(hMonitor),
uintptr(unsafe.Pointer(lmpi)),
)
return ret != 0
}
func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool {
ret, _, _ := procEnumDisplayMonitors.Call(
uintptr(hdc),
uintptr(unsafe.Pointer(clip)),
fnEnum,
dwData,
)
return ret != 0
}
func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool {
ret, _, _ := procEnumDisplaySettingsEx.Call(
uintptr(unsafe.Pointer(szDeviceName)),
uintptr(iModeNum),
uintptr(unsafe.Pointer(devMode)),
uintptr(dwFlags),
)
return ret != 0
}
func ChangeDisplaySettingsEx(szDeviceName *uint16, devMode *DEVMODE, hwnd HWND, dwFlags uint32, lParam uintptr) int32 {
ret, _, _ := procChangeDisplaySettingsEx.Call(
uintptr(unsafe.Pointer(szDeviceName)),
uintptr(unsafe.Pointer(devMode)),
uintptr(hwnd),
uintptr(dwFlags),
lParam,
)
return int32(ret)
}
/* remove to build without cgo
func SendInput(inputs []INPUT) uint32 {
var validInputs []C.INPUT
for _, oneInput := range inputs {
input := C.INPUT{_type: C.DWORD(oneInput.Type)}
switch oneInput.Type {
case INPUT_MOUSE:
(*MouseInput)(unsafe.Pointer(&input)).mi = oneInput.Mi
case INPUT_KEYBOARD:
(*KbdInput)(unsafe.Pointer(&input)).ki = oneInput.Ki
case INPUT_HARDWARE:
(*HardwareInput)(unsafe.Pointer(&input)).hi = oneInput.Hi
default:
panic("unkown type")
}
validInputs = append(validInputs, input)
}
ret, _, _ := procSendInput.Call(
uintptr(len(validInputs)),
uintptr(unsafe.Pointer(&validInputs[0])),
uintptr(unsafe.Sizeof(C.INPUT{})),
)
return uint32(ret)
}
*/

Some files were not shown because too many files have changed in this diff Show More