aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/elastic/gosigar
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/elastic/gosigar')
-rw-r--r--vendor/github.com/elastic/gosigar/CHANGELOG.md102
-rw-r--r--vendor/github.com/elastic/gosigar/LICENSE201
-rw-r--r--vendor/github.com/elastic/gosigar/NOTICE9
-rw-r--r--vendor/github.com/elastic/gosigar/README.md57
-rw-r--r--vendor/github.com/elastic/gosigar/Vagrantfile25
-rw-r--r--vendor/github.com/elastic/gosigar/codecov.yml21
-rw-r--r--vendor/github.com/elastic/gosigar/concrete_sigar.go83
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_darwin.go494
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_format.go126
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_freebsd.go108
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_interface.go197
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_linux.go84
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_linux_common.go468
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_openbsd.go418
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_stub.go71
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_unix.go69
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_util.go22
-rw-r--r--vendor/github.com/elastic/gosigar/sigar_windows.go437
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/doc.go2
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/ntquery.go132
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/privileges.go272
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go385
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/version.go43
-rw-r--r--vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go260
24 files changed, 4086 insertions, 0 deletions
diff --git a/vendor/github.com/elastic/gosigar/CHANGELOG.md b/vendor/github.com/elastic/gosigar/CHANGELOG.md
new file mode 100644
index 000000000..12695e10e
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/CHANGELOG.md
@@ -0,0 +1,102 @@
+# Change Log
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased]
+
+### Added
+
+### Fixed
+
+### Changed
+
+### Deprecated
+
+## [0.8.0]
+
+### Added
+- Added partial `getrusage` support for Windows to retrieve system CPU time and user CPU time. #95
+- Added full `getrusage` support for Unix. #95
+
+## [0.7.0]
+
+### Added
+- Added method stubs for process handling for operating system that are not supported
+ by gosigar. All methods return `ErrNotImplemented` on such systems. #88
+
+### Fixed
+- Fix freebsd build by using the common version of Get(pid). #91
+
+### Changed
+- Fixed issues in cgroup package by adding missing error checks and closing
+ file handles. #92
+
+## [0.6.0]
+
+### Added
+- Added method stubs to enable compilation for operating systems that are not
+ supported by gosigar. All methods return `ErrNotImplemented` on these unsupported
+ operating systems. #83
+- FreeBSD returns `ErrNotImplemented` for `ProcTime.Get`. #83
+
+### Changed
+- OpenBSD returns `ErrNotImplemented` for `ProcTime.Get` instead of `nil`. #83
+- Fixed incorrect `Mem.Used` calculation under linux. #82
+- Fixed `ProcState` on Linux and FreeBSD when process names contain parentheses. #81
+
+### Removed
+- Remove NetBSD build from sigar_unix.go as it is not supported by gosigar. #83
+
+## [0.5.0]
+
+### Changed
+- Fixed Trim environment variables when comparing values in the test suite. #79
+- Make `kern_procargs` more robust under darwin when we cannot retrieve
+ all the information about a process. #78
+
+## [0.4.0]
+
+### Changed
+- Fixed Windows issue that caused a hang during `init()` if WMI wasn't ready. #74
+
+## [0.3.0]
+
+### Added
+- Read `MemAvailable` value for kernel 3.14+ #71
+
+## [0.2.0]
+
+### Added
+- Added `ErrCgroupsMissing` to indicate that /proc/cgroups is missing which is
+ an indicator that cgroups were disabled at compile time. #64
+
+### Changed
+- Changed `cgroup.SupportedSubsystems()` to honor the "enabled" column in the
+ /proc/cgroups file. #64
+
+## [0.1.0]
+
+### Added
+- Added `CpuList` implementation for Windows that returns CPU timing information
+ on a per CPU basis. #55
+- Added `Uptime` implementation for Windows. #55
+- Added `Swap` implementation for Windows based on page file metrics. #55
+- Added support to `github.com/gosigar/sys/windows` for querying and enabling
+ privileges in a process token.
+- Added utility code for interfacing with linux NETLINK_INET_DIAG. #60
+- Added `ProcEnv` for getting a process's environment variables. #61
+
+### Changed
+- Changed several `OpenProcess` calls on Windows to request the lowest possible
+ access privileges. #50
+- Removed cgo usage from Windows code.
+- Added OS version checks to `ProcArgs.Get` on Windows because the
+ `Win32_Process` WMI query is not available prior to Windows vista. On XP and
+ Windows 2003, this method returns `ErrNotImplemented`. #55
+
+### Fixed
+- Fixed value of `Mem.ActualFree` and `Mem.ActualUsed` on Windows. #49
+- Fixed `ProcTime.StartTime` on Windows to report value in milliseconds since
+ Unix epoch. #51
+- Fixed `ProcStatus.PPID` value is wrong on Windows. #55
+- Fixed `ProcStatus.Username` error on Windows XP #56
diff --git a/vendor/github.com/elastic/gosigar/LICENSE b/vendor/github.com/elastic/gosigar/LICENSE
new file mode 100644
index 000000000..11069edd7
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/github.com/elastic/gosigar/NOTICE b/vendor/github.com/elastic/gosigar/NOTICE
new file mode 100644
index 000000000..fda553b5c
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/NOTICE
@@ -0,0 +1,9 @@
+Copyright (c) [2009-2011] VMware, Inc. All Rights Reserved.
+
+This product is licensed to you under the Apache License, Version 2.0 (the "License").
+You may not use this product except in compliance with the License.
+
+This product includes a number of subcomponents with
+separate copyright notices and license terms. Your use of these
+subcomponents is subject to the terms and conditions of the
+subcomponent's license, as noted in the LICENSE file. \ No newline at end of file
diff --git a/vendor/github.com/elastic/gosigar/README.md b/vendor/github.com/elastic/gosigar/README.md
new file mode 100644
index 000000000..2482620a8
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/README.md
@@ -0,0 +1,57 @@
+# Go sigar [![Build Status](https://travis-ci.org/elastic/gosigar.svg?branch=master)](https://travis-ci.org/elastic/gosigar) [![Build status](https://ci.appveyor.com/api/projects/status/4yh6sa7u97ek5uib/branch/master?svg=true)](https://ci.appveyor.com/project/elastic-beats/gosigar/branch/master)
+
+
+## Overview
+
+Go sigar is a golang implementation of the
+[sigar API](https://github.com/hyperic/sigar). The Go version of
+sigar has a very similar interface, but is being written from scratch
+in pure go/cgo, rather than cgo bindings for libsigar.
+
+## Test drive
+
+ $ go get github.com/elastic/gosigar
+ $ cd $GOPATH/src/github.com/elastic/gosigar/examples/ps
+ $ go build
+ $ ./ps
+
+## Supported platforms
+
+The features vary by operating system.
+
+| Feature | Linux | Darwin | Windows | OpenBSD | FreeBSD |
+|-----------------|:-----:|:------:|:-------:|:-------:|:-------:|
+| Cpu | X | X | X | X | X |
+| CpuList | X | X | | X | X |
+| FDUsage | X | | | | X |
+| FileSystemList | X | X | X | X | X |
+| FileSystemUsage | X | X | X | X | X |
+| LoadAverage | X | X | | X | X |
+| Mem | X | X | X | X | X |
+| ProcArgs | X | X | X | | X |
+| ProcEnv | X | X | | | X |
+| ProcExe | X | X | | | X |
+| ProcFDUsage | X | | | | X |
+| ProcList | X | X | X | | X |
+| ProcMem | X | X | X | | X |
+| ProcState | X | X | X | | X |
+| ProcTime | X | X | X | | X |
+| Swap | X | X | | X | X |
+| Uptime | X | X | | X | X |
+
+## OS Specific Notes
+
+### FreeBSD
+
+Mount both `linprocfs` and `procfs` for compatability. Consider adding these
+mounts to your `/etc/fstab` file so they are mounted automatically at boot.
+
+```
+sudo mount -t procfs proc /proc
+sudo mkdir -p /compat/linux/proc
+sudo mount -t linprocfs /dev/null /compat/linux/proc
+```
+
+## License
+
+Apache 2.0
diff --git a/vendor/github.com/elastic/gosigar/Vagrantfile b/vendor/github.com/elastic/gosigar/Vagrantfile
new file mode 100644
index 000000000..6fd990c14
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/Vagrantfile
@@ -0,0 +1,25 @@
+# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
+VAGRANTFILE_API_VERSION = "2"
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+ config.vm.box = "hashicorp/precise64"
+ config.vm.provision "shell", inline: "mkdir -p /home/vagrant/go"
+ config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/cloudfoundry/gosigar"
+ config.vm.provision "shell", inline: "chown -R vagrant:vagrant /home/vagrant/go"
+ install_go = <<-BASH
+ set -e
+
+if [ ! -d "/usr/local/go" ]; then
+ cd /tmp && wget https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz
+ cd /usr/local
+ tar xvzf /tmp/go1.3.3.linux-amd64.tar.gz
+ echo 'export GOPATH=/home/vagrant/go; export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin' >> /home/vagrant/.bashrc
+fi
+export GOPATH=/home/vagrant/go
+export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
+/usr/local/go/bin/go get -u github.com/onsi/ginkgo/ginkgo
+/usr/local/go/bin/go get -u github.com/onsi/gomega;
+BASH
+ config.vm.provision "shell", inline: 'apt-get install -y git-core'
+ config.vm.provision "shell", inline: install_go
+end
diff --git a/vendor/github.com/elastic/gosigar/codecov.yml b/vendor/github.com/elastic/gosigar/codecov.yml
new file mode 100644
index 000000000..76ade0fdb
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/codecov.yml
@@ -0,0 +1,21 @@
+# Enable coverage report message for diff on commit
+coverage:
+ status:
+ project: off
+ patch:
+ default:
+ # basic
+ target: auto
+ threshold: null
+ base: auto
+ # advanced
+ branches: null
+ if_no_uploads: error
+ if_not_found: success
+ if_ci_failed: error
+ only_pulls: false
+ flags: null
+ paths: null
+
+# Disable comments on Pull Requests
+comment: false
diff --git a/vendor/github.com/elastic/gosigar/concrete_sigar.go b/vendor/github.com/elastic/gosigar/concrete_sigar.go
new file mode 100644
index 000000000..685aa6ded
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/concrete_sigar.go
@@ -0,0 +1,83 @@
+package gosigar
+
+import (
+ "time"
+)
+
+type ConcreteSigar struct{}
+
+func (c *ConcreteSigar) CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) {
+ // samplesCh is buffered to 1 value to immediately return first CPU sample
+ samplesCh := make(chan Cpu, 1)
+
+ stopCh := make(chan struct{})
+
+ go func() {
+ var cpuUsage Cpu
+
+ // Immediately provide non-delta value.
+ // samplesCh is buffered to 1 value, so it will not block.
+ cpuUsage.Get()
+ samplesCh <- cpuUsage
+
+ ticker := time.NewTicker(collectionInterval)
+
+ for {
+ select {
+ case <-ticker.C:
+ previousCpuUsage := cpuUsage
+
+ cpuUsage.Get()
+
+ select {
+ case samplesCh <- cpuUsage.Delta(previousCpuUsage):
+ default:
+ // Include default to avoid channel blocking
+ }
+
+ case <-stopCh:
+ return
+ }
+ }
+ }()
+
+ return samplesCh, stopCh
+}
+
+func (c *ConcreteSigar) GetLoadAverage() (LoadAverage, error) {
+ l := LoadAverage{}
+ err := l.Get()
+ return l, err
+}
+
+func (c *ConcreteSigar) GetMem() (Mem, error) {
+ m := Mem{}
+ err := m.Get()
+ return m, err
+}
+
+func (c *ConcreteSigar) GetSwap() (Swap, error) {
+ s := Swap{}
+ err := s.Get()
+ return s, err
+}
+
+func (c *ConcreteSigar) GetFileSystemUsage(path string) (FileSystemUsage, error) {
+ f := FileSystemUsage{}
+ err := f.Get(path)
+ return f, err
+}
+
+func (c *ConcreteSigar) GetFDUsage() (FDUsage, error) {
+ fd := FDUsage{}
+ err := fd.Get()
+ return fd, err
+}
+
+// GetRusage return the resource usage of the process
+// Possible params: 0 = RUSAGE_SELF, 1 = RUSAGE_CHILDREN, 2 = RUSAGE_THREAD
+func (c *ConcreteSigar) GetRusage(who int) (Rusage, error) {
+ r := Rusage{}
+ err := r.Get(who)
+ return r, err
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin.go b/vendor/github.com/elastic/gosigar/sigar_darwin.go
new file mode 100644
index 000000000..f989f5160
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_darwin.go
@@ -0,0 +1,494 @@
+// Copyright (c) 2012 VMware, Inc.
+
+package gosigar
+
+/*
+#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>
+#include <libproc.h>
+#include <mach/processor_info.h>
+#include <mach/vm_map.h>
+*/
+import "C"
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "os/user"
+ "runtime"
+ "strconv"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+func (self *LoadAverage) Get() error {
+ avg := []C.double{0, 0, 0}
+
+ C.getloadavg(&avg[0], C.int(len(avg)))
+
+ self.One = float64(avg[0])
+ self.Five = float64(avg[1])
+ self.Fifteen = float64(avg[2])
+
+ return nil
+}
+
+func (self *Uptime) Get() error {
+ tv := syscall.Timeval32{}
+
+ if err := sysctlbyname("kern.boottime", &tv); err != nil {
+ return err
+ }
+
+ self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
+
+ return nil
+}
+
+func (self *Mem) Get() error {
+ var vmstat C.vm_statistics_data_t
+
+ if err := sysctlbyname("hw.memsize", &self.Total); err != nil {
+ return err
+ }
+
+ if err := vm_info(&vmstat); err != nil {
+ return err
+ }
+
+ kern := uint64(vmstat.inactive_count) << 12
+ self.Free = uint64(vmstat.free_count) << 12
+
+ self.Used = self.Total - self.Free
+ self.ActualFree = self.Free + kern
+ self.ActualUsed = self.Used - kern
+
+ return nil
+}
+
+type xsw_usage struct {
+ Total, Avail, Used uint64
+}
+
+func (self *Swap) Get() error {
+ sw_usage := xsw_usage{}
+
+ if err := sysctlbyname("vm.swapusage", &sw_usage); err != nil {
+ return err
+ }
+
+ self.Total = sw_usage.Total
+ self.Used = sw_usage.Used
+ self.Free = sw_usage.Avail
+
+ return nil
+}
+
+func (self *Cpu) Get() error {
+ var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT
+ var cpuload C.host_cpu_load_info_data_t
+
+ 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 fmt.Errorf("host_statistics error=%d", status)
+ }
+
+ self.User = uint64(cpuload.cpu_ticks[C.CPU_STATE_USER])
+ self.Sys = uint64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM])
+ self.Idle = uint64(cpuload.cpu_ticks[C.CPU_STATE_IDLE])
+ self.Nice = uint64(cpuload.cpu_ticks[C.CPU_STATE_NICE])
+
+ return nil
+}
+
+func (self *CpuList) Get() error {
+ var count C.mach_msg_type_number_t
+ var cpuload *C.processor_cpu_load_info_data_t
+ var 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 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 := C.GoBytes(unsafe.Pointer(cpuload), C.int(size))
+
+ bbuf := bytes.NewBuffer(buf)
+
+ self.List = make([]Cpu, 0, ncpu)
+
+ for i := 0; i < int(ncpu); i++ {
+ cpu := Cpu{}
+
+ err := binary.Read(bbuf, binary.LittleEndian, &cpu_ticks)
+ if err != nil {
+ return err
+ }
+
+ cpu.User = uint64(cpu_ticks[C.CPU_STATE_USER])
+ cpu.Sys = uint64(cpu_ticks[C.CPU_STATE_SYSTEM])
+ cpu.Idle = uint64(cpu_ticks[C.CPU_STATE_IDLE])
+ cpu.Nice = uint64(cpu_ticks[C.CPU_STATE_NICE])
+
+ self.List = append(self.List, cpu)
+ }
+
+ return nil
+}
+
+func (self *FDUsage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *FileSystemList) Get() error {
+ num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT)
+ if err != nil {
+ return err
+ }
+
+ buf := make([]syscall.Statfs_t, num)
+
+ _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT)
+ if err != nil {
+ return err
+ }
+
+ fslist := make([]FileSystem, 0, num)
+
+ for i := 0; i < num; i++ {
+ fs := FileSystem{}
+
+ fs.DirName = bytePtrToString(&buf[i].Mntonname[0])
+ fs.DevName = bytePtrToString(&buf[i].Mntfromname[0])
+ fs.SysTypeName = bytePtrToString(&buf[i].Fstypename[0])
+
+ fslist = append(fslist, fs)
+ }
+
+ self.List = fslist
+
+ return err
+}
+
+func (self *ProcList) Get() error {
+ n := C.proc_listpids(C.PROC_ALL_PIDS, 0, nil, 0)
+ if n <= 0 {
+ return syscall.EINVAL
+ }
+ buf := make([]byte, n)
+ n = C.proc_listpids(C.PROC_ALL_PIDS, 0, unsafe.Pointer(&buf[0]), n)
+ if n <= 0 {
+ return syscall.ENOMEM
+ }
+
+ var pid int32
+ num := int(n) / binary.Size(pid)
+ list := make([]int, 0, num)
+ bbuf := bytes.NewBuffer(buf)
+
+ for i := 0; i < num; i++ {
+ if err := binary.Read(bbuf, binary.LittleEndian, &pid); err != nil {
+ return err
+ }
+ if pid == 0 {
+ continue
+ }
+
+ list = append(list, int(pid))
+ }
+
+ self.List = list
+
+ return nil
+}
+
+func (self *ProcState) Get(pid int) error {
+ info := C.struct_proc_taskallinfo{}
+
+ if err := task_info(pid, &info); err != nil {
+ return err
+ }
+
+ self.Name = C.GoString(&info.pbsd.pbi_comm[0])
+
+ switch info.pbsd.pbi_status {
+ case C.SIDL:
+ self.State = RunStateIdle
+ case C.SRUN:
+ self.State = RunStateRun
+ case C.SSLEEP:
+ self.State = RunStateSleep
+ case C.SSTOP:
+ self.State = RunStateStop
+ case C.SZOMB:
+ self.State = RunStateZombie
+ default:
+ self.State = RunStateUnknown
+ }
+
+ self.Ppid = int(info.pbsd.pbi_ppid)
+
+ self.Pgid = int(info.pbsd.pbi_pgid)
+
+ self.Tty = int(info.pbsd.e_tdev)
+
+ self.Priority = int(info.ptinfo.pti_priority)
+
+ self.Nice = int(info.pbsd.pbi_nice)
+
+ // Get process username. Fallback to UID if username is not available.
+ uid := strconv.Itoa(int(info.pbsd.pbi_uid))
+ user, err := user.LookupId(uid)
+ if err == nil && user.Username != "" {
+ self.Username = user.Username
+ } else {
+ self.Username = uid
+ }
+
+ return nil
+}
+
+func (self *ProcMem) Get(pid int) error {
+ info := C.struct_proc_taskallinfo{}
+
+ if err := task_info(pid, &info); err != nil {
+ return err
+ }
+
+ self.Size = uint64(info.ptinfo.pti_virtual_size)
+ self.Resident = uint64(info.ptinfo.pti_resident_size)
+ self.PageFaults = uint64(info.ptinfo.pti_faults)
+
+ return nil
+}
+
+func (self *ProcTime) Get(pid int) error {
+ info := C.struct_proc_taskallinfo{}
+
+ if err := task_info(pid, &info); err != nil {
+ return err
+ }
+
+ self.User =
+ uint64(info.ptinfo.pti_total_user) / uint64(time.Millisecond)
+
+ self.Sys =
+ uint64(info.ptinfo.pti_total_system) / uint64(time.Millisecond)
+
+ self.Total = self.User + self.Sys
+
+ self.StartTime = (uint64(info.pbsd.pbi_start_tvsec) * 1000) +
+ (uint64(info.pbsd.pbi_start_tvusec) / 1000)
+
+ return nil
+}
+
+func (self *ProcArgs) Get(pid int) error {
+ var args []string
+
+ argv := func(arg string) {
+ args = append(args, arg)
+ }
+
+ err := kern_procargs(pid, nil, argv, nil)
+
+ self.List = args
+
+ return err
+}
+
+func (self *ProcEnv) Get(pid int) error {
+ if self.Vars == nil {
+ self.Vars = map[string]string{}
+ }
+
+ env := func(k, v string) {
+ self.Vars[k] = v
+ }
+
+ return kern_procargs(pid, nil, nil, env)
+}
+
+func (self *ProcExe) Get(pid int) error {
+ exe := func(arg string) {
+ self.Name = arg
+ }
+
+ return kern_procargs(pid, exe, nil, nil)
+}
+
+func (self *ProcFDUsage) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+// wrapper around sysctl KERN_PROCARGS2
+// callbacks params are optional,
+// up to the caller as to which pieces of data they want
+func kern_procargs(pid int,
+ exe func(string),
+ argv func(string),
+ env func(string, string)) error {
+
+ mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)}
+ argmax := uintptr(C.ARG_MAX)
+ buf := make([]byte, argmax)
+ err := sysctl(mib, &buf[0], &argmax, nil, 0)
+ if err != nil {
+ return nil
+ }
+
+ bbuf := bytes.NewBuffer(buf)
+ bbuf.Truncate(int(argmax))
+
+ var argc int32
+ binary.Read(bbuf, binary.LittleEndian, &argc)
+
+ path, err := bbuf.ReadBytes(0)
+ if err != nil {
+ return fmt.Errorf("Error reading the argv[0]: %v", err)
+ }
+ if exe != nil {
+ exe(string(chop(path)))
+ }
+
+ // skip trailing \0's
+ for {
+ c, err := bbuf.ReadByte()
+ if err != nil {
+ return fmt.Errorf("Error skipping nils: %v", err)
+ }
+ if c != 0 {
+ bbuf.UnreadByte()
+ break // start of argv[0]
+ }
+ }
+
+ for i := 0; i < int(argc); i++ {
+ arg, err := bbuf.ReadBytes(0)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return fmt.Errorf("Error reading args: %v", err)
+ }
+ if argv != nil {
+ argv(string(chop(arg)))
+ }
+ }
+
+ if env == nil {
+ return nil
+ }
+
+ delim := []byte{61} // "="
+
+ for {
+ line, err := bbuf.ReadBytes(0)
+ if err == io.EOF || line[0] == 0 {
+ break
+ }
+ if err != nil {
+ return fmt.Errorf("Error reading args: %v", err)
+ }
+ pair := bytes.SplitN(chop(line), delim, 2)
+
+ if len(pair) != 2 {
+ return fmt.Errorf("Error reading process information for PID: %d", pid)
+ }
+
+ env(string(pair[0]), string(pair[1]))
+ }
+
+ return nil
+}
+
+// XXX copied from zsyscall_darwin_amd64.go
+func sysctl(mib []C.int, old *byte, oldlen *uintptr,
+ new *byte, newlen uintptr) (err error) {
+ var p0 unsafe.Pointer
+ p0 = unsafe.Pointer(&mib[0])
+ _, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p0),
+ uintptr(len(mib)),
+ uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)),
+ uintptr(unsafe.Pointer(new)), uintptr(newlen))
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func vm_info(vmstat *C.vm_statistics_data_t) error {
+ var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT
+
+ 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 fmt.Errorf("host_statistics=%d", status)
+ }
+
+ return nil
+}
+
+// generic Sysctl buffer unmarshalling
+func sysctlbyname(name string, data interface{}) (err error) {
+ val, err := syscall.Sysctl(name)
+ if err != nil {
+ return err
+ }
+
+ buf := []byte(val)
+
+ switch v := data.(type) {
+ case *uint64:
+ *v = *(*uint64)(unsafe.Pointer(&buf[0]))
+ return
+ }
+
+ bbuf := bytes.NewBuffer([]byte(val))
+ return binary.Read(bbuf, binary.LittleEndian, data)
+}
+
+func task_info(pid int, info *C.struct_proc_taskallinfo) error {
+ size := C.int(unsafe.Sizeof(*info))
+ ptr := unsafe.Pointer(info)
+
+ n := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size)
+ if n != size {
+ return fmt.Errorf("Could not read process info for pid %d", pid)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_format.go b/vendor/github.com/elastic/gosigar/sigar_format.go
new file mode 100644
index 000000000..ac56c9873
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_format.go
@@ -0,0 +1,126 @@
+// Copyright (c) 2012 VMware, Inc.
+
+package gosigar
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "strconv"
+ "time"
+)
+
+// Go version of apr_strfsize
+func FormatSize(size uint64) string {
+ ord := []string{"K", "M", "G", "T", "P", "E"}
+ o := 0
+ buf := new(bytes.Buffer)
+ w := bufio.NewWriter(buf)
+
+ if size < 973 {
+ fmt.Fprintf(w, "%3d ", size)
+ w.Flush()
+ return buf.String()
+ }
+
+ for {
+ remain := size & 1023
+ size >>= 10
+
+ if size >= 973 {
+ o++
+ continue
+ }
+
+ if size < 9 || (size == 9 && remain < 973) {
+ remain = ((remain * 5) + 256) / 512
+ if remain >= 10 {
+ size++
+ remain = 0
+ }
+
+ fmt.Fprintf(w, "%d.%d%s", size, remain, ord[o])
+ break
+ }
+
+ if remain >= 512 {
+ size++
+ }
+
+ fmt.Fprintf(w, "%3d%s", size, ord[o])
+ break
+ }
+
+ w.Flush()
+ return buf.String()
+}
+
+func FormatPercent(percent float64) string {
+ return strconv.FormatFloat(percent, 'f', -1, 64) + "%"
+}
+
+func (self *FileSystemUsage) UsePercent() float64 {
+ b_used := (self.Total - self.Free) / 1024
+ b_avail := self.Avail / 1024
+ utotal := b_used + b_avail
+ used := b_used
+
+ if utotal != 0 {
+ u100 := used * 100
+ pct := u100 / utotal
+ if u100%utotal != 0 {
+ pct += 1
+ }
+ return (float64(pct) / float64(100)) * 100.0
+ }
+
+ return 0.0
+}
+
+func (self *Uptime) Format() string {
+ buf := new(bytes.Buffer)
+ w := bufio.NewWriter(buf)
+ uptime := uint64(self.Length)
+
+ days := uptime / (60 * 60 * 24)
+
+ if days != 0 {
+ s := ""
+ if days > 1 {
+ s = "s"
+ }
+ fmt.Fprintf(w, "%d day%s, ", days, s)
+ }
+
+ minutes := uptime / 60
+ hours := minutes / 60
+ hours %= 24
+ minutes %= 60
+
+ fmt.Fprintf(w, "%2d:%02d", hours, minutes)
+
+ w.Flush()
+ return buf.String()
+}
+
+func (self *ProcTime) FormatStartTime() string {
+ if self.StartTime == 0 {
+ return "00:00"
+ }
+ start := time.Unix(int64(self.StartTime)/1000, 0)
+ format := "Jan02"
+ if time.Since(start).Seconds() < (60 * 60 * 24) {
+ format = "15:04"
+ }
+ return start.Format(format)
+}
+
+func (self *ProcTime) FormatTotal() string {
+ t := self.Total / 1000
+ ss := t % 60
+ t /= 60
+ mm := t % 60
+ t /= 60
+ hh := t % 24
+ return fmt.Sprintf("%02d:%02d:%02d", hh, mm, ss)
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_freebsd.go b/vendor/github.com/elastic/gosigar/sigar_freebsd.go
new file mode 100644
index 000000000..602b4a0aa
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_freebsd.go
@@ -0,0 +1,108 @@
+// Copied and modified from sigar_linux.go.
+
+package gosigar
+
+import (
+ "io/ioutil"
+ "strconv"
+ "strings"
+ "unsafe"
+)
+
+/*
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/ucred.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <time.h>
+*/
+import "C"
+
+func init() {
+ system.ticks = uint64(C.sysconf(C._SC_CLK_TCK))
+
+ Procd = "/compat/linux/proc"
+
+ getLinuxBootTime()
+}
+
+func getMountTableFileName() string {
+ return Procd + "/mtab"
+}
+
+func (self *Uptime) Get() error {
+ ts := C.struct_timespec{}
+
+ if _, err := C.clock_gettime(C.CLOCK_UPTIME, &ts); err != nil {
+ return err
+ }
+
+ self.Length = float64(ts.tv_sec) + 1e-9*float64(ts.tv_nsec)
+
+ return nil
+}
+
+func (self *FDUsage) Get() error {
+ val := C.uint32_t(0)
+ sc := C.size_t(4)
+
+ name := C.CString("kern.openfiles")
+ _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
+ C.free(unsafe.Pointer(name))
+ if err != nil {
+ return err
+ }
+ self.Open = uint64(val)
+
+ name = C.CString("kern.maxfiles")
+ _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
+ C.free(unsafe.Pointer(name))
+ if err != nil {
+ return err
+ }
+ self.Max = uint64(val)
+
+ self.Unused = self.Max - self.Open
+
+ return nil
+}
+
+func (self *ProcFDUsage) Get(pid int) error {
+ err := readFile("/proc/"+strconv.Itoa(pid)+"/rlimit", func(line string) bool {
+ if strings.HasPrefix(line, "nofile") {
+ fields := strings.Fields(line)
+ if len(fields) == 3 {
+ self.SoftLimit, _ = strconv.ParseUint(fields[1], 10, 64)
+ self.HardLimit, _ = strconv.ParseUint(fields[2], 10, 64)
+ }
+ return false
+ }
+ return true
+ })
+ if err != nil {
+ return err
+ }
+
+ // linprocfs only provides this information for this process (self).
+ fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
+ if err != nil {
+ return err
+ }
+ self.Open = uint64(len(fds))
+
+ return nil
+}
+
+func parseCpuStat(self *Cpu, line string) error {
+ fields := strings.Fields(line)
+
+ self.User, _ = strtoull(fields[1])
+ self.Nice, _ = strtoull(fields[2])
+ self.Sys, _ = strtoull(fields[3])
+ self.Idle, _ = strtoull(fields[4])
+ return nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_interface.go b/vendor/github.com/elastic/gosigar/sigar_interface.go
new file mode 100644
index 000000000..a956af604
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_interface.go
@@ -0,0 +1,197 @@
+package gosigar
+
+import (
+ "time"
+)
+
+type ErrNotImplemented struct {
+ OS string
+}
+
+func (e ErrNotImplemented) Error() string {
+ return "not implemented on " + e.OS
+}
+
+func IsNotImplemented(err error) bool {
+ switch err.(type) {
+ case ErrNotImplemented, *ErrNotImplemented:
+ return true
+ default:
+ return false
+ }
+}
+
+type Sigar interface {
+ CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
+ GetLoadAverage() (LoadAverage, error)
+ GetMem() (Mem, error)
+ GetSwap() (Swap, error)
+ GetFileSystemUsage(string) (FileSystemUsage, error)
+ GetFDUsage() (FDUsage, error)
+ GetRusage(who int) (Rusage, error)
+}
+
+type Cpu struct {
+ User uint64
+ Nice uint64
+ Sys uint64
+ Idle uint64
+ Wait uint64
+ Irq uint64
+ SoftIrq uint64
+ Stolen uint64
+}
+
+func (cpu *Cpu) Total() uint64 {
+ return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
+ cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
+}
+
+func (cpu Cpu) Delta(other Cpu) Cpu {
+ return Cpu{
+ User: cpu.User - other.User,
+ Nice: cpu.Nice - other.Nice,
+ Sys: cpu.Sys - other.Sys,
+ Idle: cpu.Idle - other.Idle,
+ Wait: cpu.Wait - other.Wait,
+ Irq: cpu.Irq - other.Irq,
+ SoftIrq: cpu.SoftIrq - other.SoftIrq,
+ Stolen: cpu.Stolen - other.Stolen,
+ }
+}
+
+type LoadAverage struct {
+ One, Five, Fifteen float64
+}
+
+type Uptime struct {
+ Length float64
+}
+
+type Mem struct {
+ Total uint64
+ Used uint64
+ Free uint64
+ ActualFree uint64
+ ActualUsed uint64
+}
+
+type Swap struct {
+ Total uint64
+ Used uint64
+ Free uint64
+}
+
+type CpuList struct {
+ List []Cpu
+}
+
+type FDUsage struct {
+ Open uint64
+ Unused uint64
+ Max uint64
+}
+
+type FileSystem struct {
+ DirName string
+ DevName string
+ TypeName string
+ SysTypeName string
+ Options string
+ Flags uint32
+}
+
+type FileSystemList struct {
+ List []FileSystem
+}
+
+type FileSystemUsage struct {
+ Total uint64
+ Used uint64
+ Free uint64
+ Avail uint64
+ Files uint64
+ FreeFiles uint64
+}
+
+type ProcList struct {
+ List []int
+}
+
+type RunState byte
+
+const (
+ RunStateSleep = 'S'
+ RunStateRun = 'R'
+ RunStateStop = 'T'
+ RunStateZombie = 'Z'
+ RunStateIdle = 'D'
+ RunStateUnknown = '?'
+)
+
+type ProcState struct {
+ Name string
+ Username string
+ State RunState
+ Ppid int
+ Pgid int
+ Tty int
+ Priority int
+ Nice int
+ Processor int
+}
+
+type ProcMem struct {
+ Size uint64
+ Resident uint64
+ Share uint64
+ MinorFaults uint64
+ MajorFaults uint64
+ PageFaults uint64
+}
+
+type ProcTime struct {
+ StartTime uint64
+ User uint64
+ Sys uint64
+ Total uint64
+}
+
+type ProcArgs struct {
+ List []string
+}
+
+type ProcEnv struct {
+ Vars map[string]string
+}
+
+type ProcExe struct {
+ Name string
+ Cwd string
+ Root string
+}
+
+type ProcFDUsage struct {
+ Open uint64
+ SoftLimit uint64
+ HardLimit uint64
+}
+
+type Rusage struct {
+ Utime time.Duration
+ Stime time.Duration
+ 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
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_linux.go b/vendor/github.com/elastic/gosigar/sigar_linux.go
new file mode 100644
index 000000000..cb1d3525b
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_linux.go
@@ -0,0 +1,84 @@
+// Copyright (c) 2012 VMware, Inc.
+
+package gosigar
+
+import (
+ "io/ioutil"
+ "strconv"
+ "strings"
+ "syscall"
+)
+
+func init() {
+ system.ticks = 100 // C.sysconf(C._SC_CLK_TCK)
+
+ Procd = "/proc"
+
+ getLinuxBootTime()
+}
+
+func getMountTableFileName() string {
+ return "/etc/mtab"
+}
+
+func (self *Uptime) Get() error {
+ sysinfo := syscall.Sysinfo_t{}
+
+ if err := syscall.Sysinfo(&sysinfo); err != nil {
+ return err
+ }
+
+ self.Length = float64(sysinfo.Uptime)
+
+ return nil
+}
+
+func (self *FDUsage) Get() error {
+ return readFile(Procd+"/sys/fs/file-nr", func(line string) bool {
+ fields := strings.Fields(line)
+ if len(fields) == 3 {
+ self.Open, _ = strconv.ParseUint(fields[0], 10, 64)
+ self.Unused, _ = strconv.ParseUint(fields[1], 10, 64)
+ self.Max, _ = strconv.ParseUint(fields[2], 10, 64)
+ }
+ return false
+ })
+}
+
+func (self *ProcFDUsage) Get(pid int) error {
+ err := readFile(procFileName(pid, "limits"), func(line string) bool {
+ if strings.HasPrefix(line, "Max open files") {
+ fields := strings.Fields(line)
+ if len(fields) == 6 {
+ self.SoftLimit, _ = strconv.ParseUint(fields[3], 10, 64)
+ self.HardLimit, _ = strconv.ParseUint(fields[4], 10, 64)
+ }
+ return false
+ }
+ return true
+ })
+ if err != nil {
+ return err
+ }
+ fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
+ if err != nil {
+ return err
+ }
+ self.Open = uint64(len(fds))
+ return nil
+}
+
+func parseCpuStat(self *Cpu, line string) error {
+ fields := strings.Fields(line)
+
+ self.User, _ = strtoull(fields[1])
+ self.Nice, _ = strtoull(fields[2])
+ self.Sys, _ = strtoull(fields[3])
+ self.Idle, _ = strtoull(fields[4])
+ self.Wait, _ = strtoull(fields[5])
+ self.Irq, _ = strtoull(fields[6])
+ self.SoftIrq, _ = strtoull(fields[7])
+ self.Stolen, _ = strtoull(fields[8])
+
+ return nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_linux_common.go b/vendor/github.com/elastic/gosigar/sigar_linux_common.go
new file mode 100644
index 000000000..8e5e7856f
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_linux_common.go
@@ -0,0 +1,468 @@
+// Copyright (c) 2012 VMware, Inc.
+
+// +build freebsd linux
+
+package gosigar
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/user"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "syscall"
+)
+
+var system struct {
+ ticks uint64
+ btime uint64
+}
+
+var Procd string
+
+func getLinuxBootTime() {
+ // grab system boot time
+ readFile(Procd+"/stat", func(line string) bool {
+ if strings.HasPrefix(line, "btime") {
+ system.btime, _ = strtoull(line[6:])
+ return false // stop reading
+ }
+ return true
+ })
+}
+
+func (self *LoadAverage) Get() error {
+ line, err := ioutil.ReadFile(Procd + "/loadavg")
+ if err != nil {
+ return nil
+ }
+
+ fields := strings.Fields(string(line))
+
+ self.One, _ = strconv.ParseFloat(fields[0], 64)
+ self.Five, _ = strconv.ParseFloat(fields[1], 64)
+ self.Fifteen, _ = strconv.ParseFloat(fields[2], 64)
+
+ return nil
+}
+
+func (self *Mem) Get() error {
+
+ table, err := parseMeminfo()
+ if err != nil {
+ return err
+ }
+
+ self.Total, _ = table["MemTotal"]
+ self.Free, _ = table["MemFree"]
+ buffers, _ := table["Buffers"]
+ cached, _ := table["Cached"]
+
+ if available, ok := table["MemAvailable"]; ok {
+ // MemAvailable is in /proc/meminfo (kernel 3.14+)
+ self.ActualFree = available
+ } else {
+ self.ActualFree = self.Free + buffers + cached
+ }
+
+ self.Used = self.Total - self.Free
+ self.ActualUsed = self.Total - self.ActualFree
+
+ return nil
+}
+
+func (self *Swap) Get() error {
+
+ table, err := parseMeminfo()
+ if err != nil {
+ return err
+ }
+ self.Total, _ = table["SwapTotal"]
+ self.Free, _ = table["SwapFree"]
+
+ self.Used = self.Total - self.Free
+ return nil
+}
+
+func (self *Cpu) Get() error {
+ return readFile(Procd+"/stat", func(line string) bool {
+ if len(line) > 4 && line[0:4] == "cpu " {
+ parseCpuStat(self, line)
+ return false
+ }
+ return true
+
+ })
+}
+
+func (self *CpuList) Get() error {
+ capacity := len(self.List)
+ if capacity == 0 {
+ capacity = 4
+ }
+ list := make([]Cpu, 0, capacity)
+
+ err := readFile(Procd+"/stat", func(line string) bool {
+ if len(line) > 3 && line[0:3] == "cpu" && line[3] != ' ' {
+ cpu := Cpu{}
+ parseCpuStat(&cpu, line)
+ list = append(list, cpu)
+ }
+ return true
+ })
+
+ self.List = list
+
+ return err
+}
+
+func (self *FileSystemList) Get() error {
+ capacity := len(self.List)
+ if capacity == 0 {
+ capacity = 10
+ }
+ fslist := make([]FileSystem, 0, capacity)
+
+ err := readFile(getMountTableFileName(), func(line string) bool {
+ fields := strings.Fields(line)
+
+ fs := FileSystem{}
+ fs.DevName = fields[0]
+ fs.DirName = fields[1]
+ fs.SysTypeName = fields[2]
+ fs.Options = fields[3]
+
+ fslist = append(fslist, fs)
+
+ return true
+ })
+
+ self.List = fslist
+
+ return err
+}
+
+func (self *ProcList) Get() error {
+ dir, err := os.Open(Procd)
+ if err != nil {
+ return err
+ }
+ defer dir.Close()
+
+ const readAllDirnames = -1 // see os.File.Readdirnames doc
+
+ names, err := dir.Readdirnames(readAllDirnames)
+ if err != nil {
+ return err
+ }
+
+ capacity := len(names)
+ list := make([]int, 0, capacity)
+
+ for _, name := range names {
+ if name[0] < '0' || name[0] > '9' {
+ continue
+ }
+ pid, err := strconv.Atoi(name)
+ if err == nil {
+ list = append(list, pid)
+ }
+ }
+
+ self.List = list
+
+ return nil
+}
+
+func (self *ProcState) Get(pid int) error {
+ data, err := readProcFile(pid, "stat")
+ if err != nil {
+ return err
+ }
+
+ // Extract the comm value with is surrounded by parentheses.
+ lIdx := bytes.Index(data, []byte("("))
+ rIdx := bytes.LastIndex(data, []byte(")"))
+ if lIdx < 0 || rIdx < 0 || lIdx >= rIdx || rIdx+2 >= len(data) {
+ return fmt.Errorf("failed to extract comm for pid %d from '%v'", pid, string(data))
+ }
+ self.Name = string(data[lIdx+1 : rIdx])
+
+ // Extract the rest of the fields that we are interested in.
+ fields := bytes.Fields(data[rIdx+2:])
+ if len(fields) <= 36 {
+ return fmt.Errorf("expected more stat fields for pid %d from '%v'", pid, string(data))
+ }
+
+ interests := bytes.Join([][]byte{
+ fields[0], // state
+ fields[1], // ppid
+ fields[2], // pgrp
+ fields[4], // tty_nr
+ fields[15], // priority
+ fields[16], // nice
+ fields[36], // processor (last processor executed on)
+ }, []byte(" "))
+
+ var state string
+ _, err = fmt.Fscan(bytes.NewBuffer(interests),
+ &state,
+ &self.Ppid,
+ &self.Pgid,
+ &self.Tty,
+ &self.Priority,
+ &self.Nice,
+ &self.Processor,
+ )
+ if err != nil {
+ return fmt.Errorf("failed to parse stat fields for pid %d from '%v': %v", pid, string(data), err)
+ }
+ self.State = RunState(state[0])
+
+ // Read /proc/[pid]/status to get the uid, then lookup uid to get username.
+ status, err := getProcStatus(pid)
+ if err != nil {
+ return fmt.Errorf("failed to read process status for pid %d: %v", pid, err)
+ }
+ uids, err := getUIDs(status)
+ if err != nil {
+ return fmt.Errorf("failed to read process status for pid %d: %v", pid, err)
+ }
+ user, err := user.LookupId(uids[0])
+ if err == nil {
+ self.Username = user.Username
+ } else {
+ self.Username = uids[0]
+ }
+
+ return nil
+}
+
+func (self *ProcMem) Get(pid int) error {
+ contents, err := readProcFile(pid, "statm")
+ if err != nil {
+ return err
+ }
+
+ fields := strings.Fields(string(contents))
+
+ size, _ := strtoull(fields[0])
+ self.Size = size << 12
+
+ rss, _ := strtoull(fields[1])
+ self.Resident = rss << 12
+
+ share, _ := strtoull(fields[2])
+ self.Share = share << 12
+
+ contents, err = readProcFile(pid, "stat")
+ if err != nil {
+ return err
+ }
+
+ fields = strings.Fields(string(contents))
+
+ self.MinorFaults, _ = strtoull(fields[10])
+ self.MajorFaults, _ = strtoull(fields[12])
+ self.PageFaults = self.MinorFaults + self.MajorFaults
+
+ return nil
+}
+
+func (self *ProcTime) Get(pid int) error {
+ contents, err := readProcFile(pid, "stat")
+ if err != nil {
+ return err
+ }
+
+ fields := strings.Fields(string(contents))
+
+ user, _ := strtoull(fields[13])
+ sys, _ := strtoull(fields[14])
+ // convert to millis
+ self.User = user * (1000 / system.ticks)
+ self.Sys = sys * (1000 / system.ticks)
+ self.Total = self.User + self.Sys
+
+ // convert to millis
+ self.StartTime, _ = strtoull(fields[21])
+ self.StartTime /= system.ticks
+ self.StartTime += system.btime
+ self.StartTime *= 1000
+
+ return nil
+}
+
+func (self *ProcArgs) Get(pid int) error {
+ contents, err := readProcFile(pid, "cmdline")
+ if err != nil {
+ return err
+ }
+
+ bbuf := bytes.NewBuffer(contents)
+
+ var args []string
+
+ for {
+ arg, err := bbuf.ReadBytes(0)
+ if err == io.EOF {
+ break
+ }
+ args = append(args, string(chop(arg)))
+ }
+
+ self.List = args
+
+ return nil
+}
+
+func (self *ProcEnv) Get(pid int) error {
+ contents, err := readProcFile(pid, "environ")
+ if err != nil {
+ return err
+ }
+
+ if self.Vars == nil {
+ self.Vars = map[string]string{}
+ }
+
+ pairs := bytes.Split(contents, []byte{0})
+ for _, kv := range pairs {
+ parts := bytes.SplitN(kv, []byte{'='}, 2)
+ if len(parts) != 2 {
+ continue
+ }
+
+ key := string(bytes.TrimSpace(parts[0]))
+ if key == "" {
+ continue
+ }
+
+ self.Vars[key] = string(bytes.TrimSpace(parts[1]))
+ }
+
+ return nil
+}
+
+func (self *ProcExe) Get(pid int) error {
+ fields := map[string]*string{
+ "exe": &self.Name,
+ "cwd": &self.Cwd,
+ "root": &self.Root,
+ }
+
+ for name, field := range fields {
+ val, err := os.Readlink(procFileName(pid, name))
+
+ if err != nil {
+ return err
+ }
+
+ *field = val
+ }
+
+ return nil
+}
+
+func parseMeminfo() (map[string]uint64, error) {
+ table := map[string]uint64{}
+
+ err := readFile(Procd+"/meminfo", func(line string) bool {
+ fields := strings.Split(line, ":")
+
+ if len(fields) != 2 {
+ return true // skip on errors
+ }
+
+ num := strings.TrimLeft(fields[1], " ")
+ val, err := strtoull(strings.Fields(num)[0])
+ if err != nil {
+ return true // skip on errors
+ }
+ table[fields[0]] = val * 1024 //in bytes
+
+ return true
+ })
+ return table, err
+}
+
+func readFile(file string, handler func(string) bool) error {
+ contents, err := ioutil.ReadFile(file)
+ if err != nil {
+ return err
+ }
+
+ reader := bufio.NewReader(bytes.NewBuffer(contents))
+
+ for {
+ line, _, err := reader.ReadLine()
+ if err == io.EOF {
+ break
+ }
+ if !handler(string(line)) {
+ break
+ }
+ }
+
+ return nil
+}
+
+func strtoull(val string) (uint64, error) {
+ return strconv.ParseUint(val, 10, 64)
+}
+
+func procFileName(pid int, name string) string {
+ return Procd + "/" + strconv.Itoa(pid) + "/" + name
+}
+
+func readProcFile(pid int, name string) ([]byte, error) {
+ path := procFileName(pid, name)
+ contents, err := ioutil.ReadFile(path)
+
+ if err != nil {
+ if perr, ok := err.(*os.PathError); ok {
+ if perr.Err == syscall.ENOENT {
+ return nil, syscall.ESRCH
+ }
+ }
+ }
+
+ return contents, err
+}
+
+// getProcStatus reads /proc/[pid]/status which contains process status
+// information in human readable form.
+func getProcStatus(pid int) (map[string]string, error) {
+ status := make(map[string]string, 42)
+ path := filepath.Join(Procd, strconv.Itoa(pid), "status")
+ err := readFile(path, func(line string) bool {
+ fields := strings.SplitN(line, ":", 2)
+ if len(fields) == 2 {
+ status[fields[0]] = strings.TrimSpace(fields[1])
+ }
+
+ return true
+ })
+ return status, err
+}
+
+// getUIDs reads the "Uid" value from status and splits it into four values --
+// real, effective, saved set, and file system UIDs.
+func getUIDs(status map[string]string) ([]string, error) {
+ uidLine, ok := status["Uid"]
+ if !ok {
+ return nil, fmt.Errorf("Uid not found in proc status")
+ }
+
+ uidStrs := strings.Fields(uidLine)
+ if len(uidStrs) != 4 {
+ return nil, fmt.Errorf("Uid line ('%s') did not contain four values", uidLine)
+ }
+
+ return uidStrs, nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_openbsd.go b/vendor/github.com/elastic/gosigar/sigar_openbsd.go
new file mode 100644
index 000000000..4f1383a6b
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_openbsd.go
@@ -0,0 +1,418 @@
+// Copyright (c) 2016 Jasper Lievisse Adriaanse <j@jasper.la>.
+
+// +build openbsd
+
+package gosigar
+
+/*
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/mount.h>
+#include <sys/sched.h>
+#include <sys/swap.h>
+#include <stdlib.h>
+#include <unistd.h>
+*/
+import "C"
+
+//import "github.com/davecgh/go-spew/spew"
+
+import (
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+type Uvmexp struct {
+ pagesize uint32
+ pagemask uint32
+ pageshift uint32
+ npages uint32
+ free uint32
+ active uint32
+ inactive uint32
+ paging uint32
+ wired uint32
+ zeropages uint32
+ reserve_pagedaemon uint32
+ reserve_kernel uint32
+ anonpages uint32
+ vnodepages uint32
+ vtextpages uint32
+ freemin uint32
+ freetarg uint32
+ inactarg uint32
+ wiredmax uint32
+ anonmin uint32
+ vtextmin uint32
+ vnodemin uint32
+ anonminpct uint32
+ vtextmi uint32
+ npct uint32
+ vnodeminpct uint32
+ nswapdev uint32
+ swpages uint32
+ swpginuse uint32
+ swpgonly uint32
+ nswget uint32
+ nanon uint32
+ nanonneeded uint32
+ nfreeanon uint32
+ faults uint32
+ traps uint32
+ intrs uint32
+ swtch uint32
+ softs uint32
+ syscalls uint32
+ pageins uint32
+ obsolete_swapins uint32
+ obsolete_swapouts uint32
+ pgswapin uint32
+ pgswapout uint32
+ forks uint32
+ forks_ppwait uint32
+ forks_sharevm uint32
+ pga_zerohit uint32
+ pga_zeromiss uint32
+ zeroaborts uint32
+ fltnoram uint32
+ fltnoanon uint32
+ fltpgwait uint32
+ fltpgrele uint32
+ fltrelck uint32
+ fltrelckok uint32
+ fltanget uint32
+ fltanretry uint32
+ fltamcopy uint32
+ fltnamap uint32
+ fltnomap uint32
+ fltlget uint32
+ fltget uint32
+ flt_anon uint32
+ flt_acow uint32
+ flt_obj uint32
+ flt_prcopy uint32
+ flt_przero uint32
+ pdwoke uint32
+ pdrevs uint32
+ pdswout uint32
+ pdfreed uint32
+ pdscans uint32
+ pdanscan uint32
+ pdobscan uint32
+ pdreact uint32
+ pdbusy uint32
+ pdpageouts uint32
+ pdpending uint32
+ pddeact uint32
+ pdreanon uint32
+ pdrevnode uint32
+ pdrevtext uint32
+ fpswtch uint32
+ kmapent uint32
+}
+
+type Bcachestats struct {
+ numbufs uint64
+ numbufpages uint64
+ numdirtypages uint64
+ numcleanpages uint64
+ pendingwrites uint64
+ pendingreads uint64
+ numwrites uint64
+ numreads uint64
+ cachehits uint64
+ busymapped uint64
+ dmapages uint64
+ highpages uint64
+ delwribufs uint64
+ kvaslots uint64
+ kvaslots_avail uint64
+}
+
+type Swapent struct {
+ se_dev C.dev_t
+ se_flags int32
+ se_nblks int32
+ se_inuse int32
+ se_priority int32
+ sw_path []byte
+}
+
+func (self *FileSystemList) Get() error {
+ num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT)
+ if err != nil {
+ return err
+ }
+
+ buf := make([]syscall.Statfs_t, num)
+
+ _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT)
+ if err != nil {
+ return err
+ }
+
+ fslist := make([]FileSystem, 0, num)
+
+ for i := 0; i < num; i++ {
+ fs := FileSystem{}
+
+ fs.DirName = bytePtrToString(&buf[i].F_mntonname[0])
+ fs.DevName = bytePtrToString(&buf[i].F_mntfromname[0])
+ fs.SysTypeName = bytePtrToString(&buf[i].F_fstypename[0])
+
+ fslist = append(fslist, fs)
+ }
+
+ self.List = fslist
+
+ return err
+}
+
+func (self *FileSystemUsage) Get(path string) error {
+ stat := syscall.Statfs_t{}
+ err := syscall.Statfs(path, &stat)
+ if err != nil {
+ return err
+ }
+
+ self.Total = uint64(stat.F_blocks) * uint64(stat.F_bsize)
+ self.Free = uint64(stat.F_bfree) * uint64(stat.F_bsize)
+ self.Avail = uint64(stat.F_bavail) * uint64(stat.F_bsize)
+ self.Used = self.Total - self.Free
+ self.Files = stat.F_files
+ self.FreeFiles = stat.F_ffree
+
+ return nil
+}
+
+func (self *FDUsage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *LoadAverage) Get() error {
+ avg := []C.double{0, 0, 0}
+
+ C.getloadavg(&avg[0], C.int(len(avg)))
+
+ self.One = float64(avg[0])
+ self.Five = float64(avg[1])
+ self.Fifteen = float64(avg[2])
+
+ return nil
+}
+
+func (self *Uptime) Get() error {
+ tv := syscall.Timeval{}
+ mib := [2]int32{C.CTL_KERN, C.KERN_BOOTTIME}
+
+ n := uintptr(0)
+ // First we determine how much memory we'll need to pass later on (via `n`)
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ // Now perform the actual sysctl(3) call, storing the result in tv
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&tv)), uintptr(unsafe.Pointer(&n)), 0, 0)
+
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
+
+ return nil
+}
+
+func (self *Mem) Get() error {
+ n := uintptr(0)
+
+ var uvmexp Uvmexp
+ mib := [2]int32{C.CTL_VM, C.VM_UVMEXP}
+ n = uintptr(0)
+ // First we determine how much memory we'll need to pass later on (via `n`)
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ var bcachestats Bcachestats
+ mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT}
+ n = uintptr(0)
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ self.Total = uint64(uvmexp.npages) << uvmexp.pageshift
+ self.Used = uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift
+ self.Free = uint64(uvmexp.free) << uvmexp.pageshift
+
+ self.ActualFree = self.Free + (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
+ self.ActualUsed = self.Used - (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
+
+ return nil
+}
+
+func (self *Swap) Get() error {
+ nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0)
+
+ // If there are no swap devices, nothing to do here.
+ if nswap == 0 {
+ return nil
+ }
+
+ swdev := make([]Swapent, nswap)
+
+ rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap)
+ if rnswap == 0 {
+ return nil
+ }
+
+ for i := 0; i < int(nswap); i++ {
+ if swdev[i].se_flags&C.SWF_ENABLE == 2 {
+ self.Used = self.Used + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE))
+ self.Total = self.Total + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE))
+ }
+ }
+
+ self.Free = self.Total - self.Used
+
+ return nil
+}
+
+func (self *Cpu) Get() error {
+ load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
+
+ mib := [2]int32{C.CTL_KERN, C.KERN_CPTIME}
+ n := uintptr(0)
+ // First we determine how much memory we'll need to pass later on (via `n`)
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&load)), uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ self.User = uint64(load[0])
+ self.Nice = uint64(load[1])
+ self.Sys = uint64(load[2])
+ self.Irq = uint64(load[3])
+ self.Idle = uint64(load[4])
+
+ return nil
+}
+
+func (self *CpuList) Get() error {
+ mib := [2]int32{C.CTL_HW, C.HW_NCPU}
+ var ncpu int
+
+ n := uintptr(0)
+ // First we determine how much memory we'll need to pass later on (via `n`)
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ // Now perform the actual sysctl(3) call, storing the result in ncpu
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&n)), 0, 0)
+
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
+
+ self.List = make([]Cpu, ncpu)
+ for curcpu := range self.List {
+ sysctlCptime(ncpu, curcpu, &load)
+ fillCpu(&self.List[curcpu], load)
+ }
+
+ return nil
+}
+
+func (self *ProcList) Get() error {
+ return nil
+}
+
+func (self *ProcArgs) Get(pid int) error {
+ return nil
+}
+
+func (self *ProcEnv) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *ProcState) Get(pid int) error {
+ return nil
+}
+
+func (self *ProcMem) Get(pid int) error {
+ return nil
+}
+
+func (self *ProcTime) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *ProcExe) Get(pid int) error {
+ return nil
+}
+
+func (self *ProcFDUsage) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) {
+ cpu.User = uint64(load[0])
+ cpu.Nice = uint64(load[1])
+ cpu.Sys = uint64(load[2])
+ cpu.Irq = uint64(load[3])
+ cpu.Idle = uint64(load[4])
+}
+
+func sysctlCptime(ncpu int, curcpu int, load *[C.CPUSTATES]C.long) error {
+ var mib []int32
+
+ // Use the correct mib based on the number of CPUs and fill out the
+ // current CPU number in case of SMP. (0 indexed cf. self.List)
+ if ncpu == 0 {
+ mib = []int32{C.CTL_KERN, C.KERN_CPTIME}
+ } else {
+ mib = []int32{C.CTL_KERN, C.KERN_CPTIME2, int32(curcpu)}
+ }
+
+ len := len(mib)
+
+ n := uintptr(0)
+ // First we determine how much memory we'll need to pass later on (via `n`)
+ _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), 0, uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), uintptr(unsafe.Pointer(load)), uintptr(unsafe.Pointer(&n)), 0, 0)
+ if errno != 0 || n == 0 {
+ return nil
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_stub.go b/vendor/github.com/elastic/gosigar/sigar_stub.go
new file mode 100644
index 000000000..0b858f1c0
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_stub.go
@@ -0,0 +1,71 @@
+// +build !darwin,!freebsd,!linux,!openbsd,!windows
+
+package gosigar
+
+import (
+ "runtime"
+)
+
+func (c *Cpu) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (l *LoadAverage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (m *Mem) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (s *Swap) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (f *FDUsage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcTime) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *FileSystemUsage) Get(path string) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *CpuList) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcState) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcExe) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcMem) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcFDUsage) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcEnv) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcList) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (p *ProcArgs) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *Rusage) Get(int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_unix.go b/vendor/github.com/elastic/gosigar/sigar_unix.go
new file mode 100644
index 000000000..3f3a9f7ff
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_unix.go
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 VMware, Inc.
+
+// +build darwin freebsd linux
+
+package gosigar
+
+import (
+ "syscall"
+ "time"
+
+ "golang.org/x/sys/unix"
+)
+
+func (self *FileSystemUsage) Get(path string) error {
+ stat := syscall.Statfs_t{}
+ err := syscall.Statfs(path, &stat)
+ if err != nil {
+ return err
+ }
+
+ self.Total = uint64(stat.Blocks) * uint64(stat.Bsize)
+ self.Free = uint64(stat.Bfree) * uint64(stat.Bsize)
+ self.Avail = uint64(stat.Bavail) * uint64(stat.Bsize)
+ self.Used = self.Total - self.Free
+ self.Files = stat.Files
+ self.FreeFiles = uint64(stat.Ffree)
+
+ return nil
+}
+
+func (r *Rusage) Get(who int) error {
+ ru, err := getResourceUsage(who)
+ if err != nil {
+ return err
+ }
+
+ uTime := convertRtimeToDur(ru.Utime)
+ sTime := convertRtimeToDur(ru.Stime)
+
+ r.Utime = uTime
+ r.Stime = sTime
+ r.Maxrss = int64(ru.Maxrss)
+ r.Ixrss = int64(ru.Ixrss)
+ r.Idrss = int64(ru.Idrss)
+ r.Isrss = int64(ru.Isrss)
+ r.Minflt = int64(ru.Minflt)
+ r.Majflt = int64(ru.Majflt)
+ r.Nswap = int64(ru.Nswap)
+ r.Inblock = int64(ru.Inblock)
+ r.Oublock = int64(ru.Oublock)
+ r.Msgsnd = int64(ru.Msgsnd)
+ r.Msgrcv = int64(ru.Msgrcv)
+ r.Nsignals = int64(ru.Nsignals)
+ r.Nvcsw = int64(ru.Nvcsw)
+ r.Nivcsw = int64(ru.Nivcsw)
+
+ return nil
+}
+
+func getResourceUsage(who int) (unix.Rusage, error) {
+ r := unix.Rusage{}
+ err := unix.Getrusage(who, &r)
+
+ return r, err
+}
+
+func convertRtimeToDur(t unix.Timeval) time.Duration {
+ return time.Duration(t.Nano())
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_util.go b/vendor/github.com/elastic/gosigar/sigar_util.go
new file mode 100644
index 000000000..bf93b02b2
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_util.go
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 VMware, Inc.
+
+package gosigar
+
+import (
+ "unsafe"
+)
+
+func bytePtrToString(ptr *int8) string {
+ bytes := (*[10000]byte)(unsafe.Pointer(ptr))
+
+ n := 0
+ for bytes[n] != 0 {
+ n++
+ }
+
+ return string(bytes[0:n])
+}
+
+func chop(buf []byte) []byte {
+ return buf[0 : len(buf)-1]
+}
diff --git a/vendor/github.com/elastic/gosigar/sigar_windows.go b/vendor/github.com/elastic/gosigar/sigar_windows.go
new file mode 100644
index 000000000..0cdf928d1
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sigar_windows.go
@@ -0,0 +1,437 @@
+// Copyright (c) 2012 VMware, Inc.
+
+package gosigar
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "sync"
+ "syscall"
+ "time"
+
+ "github.com/StackExchange/wmi"
+ "github.com/elastic/gosigar/sys/windows"
+ "github.com/pkg/errors"
+)
+
+// Win32_Process represents a process on the Windows operating system. If
+// additional fields are added here (that match the Windows struct) they will
+// automatically be populated when calling getWin32Process.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372(v=vs.85).aspx
+type Win32_Process struct {
+ CommandLine string
+}
+
+// Win32_OperatingSystem WMI class represents a Windows-based operating system
+// installed on a computer.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa394239(v=vs.85).aspx
+type Win32_OperatingSystem struct {
+ LastBootUpTime time.Time
+}
+
+var (
+ // version is Windows version of the host OS.
+ version = windows.GetWindowsVersion()
+
+ // processQueryLimitedInfoAccess is set to PROCESS_QUERY_INFORMATION for Windows
+ // 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
+ // OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
+ processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
+
+ // bootTime is the time when the OS was last booted. This value may be nil
+ // on operating systems that do not support the WMI query used to obtain it.
+ bootTime *time.Time
+ bootTimeLock sync.Mutex
+)
+
+func init() {
+ if !version.IsWindowsVistaOrGreater() {
+ // PROCESS_QUERY_LIMITED_INFORMATION cannot be used on 2003 or XP.
+ processQueryLimitedInfoAccess = syscall.PROCESS_QUERY_INFORMATION
+ }
+}
+
+func (self *LoadAverage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *FDUsage) Get() error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *ProcEnv) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *ProcExe) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *ProcFDUsage) Get(pid int) error {
+ return ErrNotImplemented{runtime.GOOS}
+}
+
+func (self *Uptime) Get() error {
+ // Minimum supported OS is Windows Vista.
+ if !version.IsWindowsVistaOrGreater() {
+ return ErrNotImplemented{runtime.GOOS}
+ }
+
+ bootTimeLock.Lock()
+ defer bootTimeLock.Unlock()
+ if bootTime == nil {
+ os, err := getWin32OperatingSystem()
+ if err != nil {
+ return errors.Wrap(err, "failed to get boot time using WMI")
+ }
+ bootTime = &os.LastBootUpTime
+ }
+
+ self.Length = time.Since(*bootTime).Seconds()
+ return nil
+}
+
+func (self *Mem) Get() error {
+ memoryStatusEx, err := windows.GlobalMemoryStatusEx()
+ if err != nil {
+ return errors.Wrap(err, "GlobalMemoryStatusEx failed")
+ }
+
+ self.Total = memoryStatusEx.TotalPhys
+ self.Free = memoryStatusEx.AvailPhys
+ self.Used = self.Total - self.Free
+ self.ActualFree = self.Free
+ self.ActualUsed = self.Used
+ return nil
+}
+
+func (self *Swap) Get() error {
+ memoryStatusEx, err := windows.GlobalMemoryStatusEx()
+ if err != nil {
+ return errors.Wrap(err, "GlobalMemoryStatusEx failed")
+ }
+
+ self.Total = memoryStatusEx.TotalPageFile
+ self.Free = memoryStatusEx.AvailPageFile
+ self.Used = self.Total - self.Free
+ return nil
+}
+
+func (self *Cpu) Get() error {
+ idle, kernel, user, err := windows.GetSystemTimes()
+ if err != nil {
+ return errors.Wrap(err, "GetSystemTimes failed")
+ }
+
+ // CPU times are reported in milliseconds by gosigar.
+ self.Idle = uint64(idle / time.Millisecond)
+ self.Sys = uint64(kernel / time.Millisecond)
+ self.User = uint64(user / time.Millisecond)
+ return nil
+}
+
+func (self *CpuList) Get() error {
+ cpus, err := windows.NtQuerySystemProcessorPerformanceInformation()
+ if err != nil {
+ return errors.Wrap(err, "NtQuerySystemProcessorPerformanceInformation failed")
+ }
+
+ self.List = make([]Cpu, 0, len(cpus))
+ for _, cpu := range cpus {
+ self.List = append(self.List, Cpu{
+ Idle: uint64(cpu.IdleTime / time.Millisecond),
+ Sys: uint64(cpu.KernelTime / time.Millisecond),
+ User: uint64(cpu.UserTime / time.Millisecond),
+ })
+ }
+ return nil
+}
+
+func (self *FileSystemList) Get() error {
+ drives, err := windows.GetLogicalDriveStrings()
+ if err != nil {
+ return errors.Wrap(err, "GetLogicalDriveStrings failed")
+ }
+
+ for _, drive := range drives {
+ dt, err := windows.GetDriveType(drive)
+ if err != nil {
+ return errors.Wrapf(err, "GetDriveType failed")
+ }
+
+ self.List = append(self.List, FileSystem{
+ DirName: drive,
+ DevName: drive,
+ TypeName: dt.String(),
+ })
+ }
+ return nil
+}
+
+// Get retrieves a list of all process identifiers (PIDs) in the system.
+func (self *ProcList) Get() error {
+ pids, err := windows.EnumProcesses()
+ if err != nil {
+ return errors.Wrap(err, "EnumProcesses failed")
+ }
+
+ // Convert uint32 PIDs to int.
+ self.List = make([]int, 0, len(pids))
+ for _, pid := range pids {
+ self.List = append(self.List, int(pid))
+ }
+ return nil
+}
+
+func (self *ProcState) Get(pid int) error {
+ var errs []error
+
+ var err error
+ self.Name, err = getProcName(pid)
+ if err != nil {
+ errs = append(errs, errors.Wrap(err, "getProcName failed"))
+ }
+
+ self.State, err = getProcStatus(pid)
+ if err != nil {
+ errs = append(errs, errors.Wrap(err, "getProcStatus failed"))
+ }
+
+ self.Ppid, err = getParentPid(pid)
+ if err != nil {
+ errs = append(errs, errors.Wrap(err, "getParentPid failed"))
+ }
+
+ self.Username, err = getProcCredName(pid)
+ if err != nil {
+ errs = append(errs, errors.Wrap(err, "getProcCredName failed"))
+ }
+
+ if len(errs) > 0 {
+ errStrs := make([]string, 0, len(errs))
+ for _, e := range errs {
+ errStrs = append(errStrs, e.Error())
+ }
+ return errors.New(strings.Join(errStrs, "; "))
+ }
+ return nil
+}
+
+// getProcName returns the process name associated with the PID.
+func getProcName(pid int) (string, error) {
+ handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
+ if err != nil {
+ return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ filename, err := windows.GetProcessImageFileName(handle)
+ if err != nil {
+ return "", errors.Wrapf(err, "GetProcessImageFileName failed for pid=%v", pid)
+ }
+
+ return filepath.Base(filename), nil
+}
+
+// getProcStatus returns the status of a process.
+func getProcStatus(pid int) (RunState, error) {
+ handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
+ if err != nil {
+ return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ var exitCode uint32
+ err = syscall.GetExitCodeProcess(handle, &exitCode)
+ if err != nil {
+ return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v")
+ }
+
+ if exitCode == 259 { //still active
+ return RunStateRun, nil
+ }
+ return RunStateSleep, nil
+}
+
+// getParentPid returns the parent process ID of a process.
+func getParentPid(pid int) (int, error) {
+ handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
+ if err != nil {
+ return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ procInfo, err := windows.NtQueryProcessBasicInformation(handle)
+ if err != nil {
+ return 0, errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid)
+ }
+
+ return int(procInfo.InheritedFromUniqueProcessID), nil
+}
+
+func getProcCredName(pid int) (string, error) {
+ handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
+ if err != nil {
+ return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ // Find process token via win32.
+ var token syscall.Token
+ err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token)
+ if err != nil {
+ return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid)
+ }
+
+ // Find the token user.
+ tokenUser, err := token.GetTokenUser()
+ if err != nil {
+ return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid)
+ }
+
+ // Close token to prevent handle leaks.
+ err = token.Close()
+ if err != nil {
+ return "", errors.Wrapf(err, "failed while closing process token handle for pid=%v", pid)
+ }
+
+ // Look up domain account by SID.
+ account, domain, _, err := tokenUser.User.Sid.LookupAccount("")
+ if err != nil {
+ sid, sidErr := tokenUser.User.Sid.String()
+ if sidErr != nil {
+ return "", errors.Wrapf(err, "failed while looking up account name for pid=%v", pid)
+ }
+ return "", errors.Wrapf(err, "failed while looking up account name for SID=%v of pid=%v", sid, pid)
+ }
+
+ return fmt.Sprintf(`%s\%s`, domain, account), nil
+}
+
+func (self *ProcMem) Get(pid int) error {
+ handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid))
+ if err != nil {
+ return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ counters, err := windows.GetProcessMemoryInfo(handle)
+ if err != nil {
+ return errors.Wrapf(err, "GetProcessMemoryInfo failed for pid=%v", pid)
+ }
+
+ self.Resident = uint64(counters.WorkingSetSize)
+ self.Size = uint64(counters.PrivateUsage)
+ return nil
+}
+
+func (self *ProcTime) Get(pid int) error {
+ cpu, err := getProcTimes(pid)
+ if err != nil {
+ return err
+ }
+
+ // Windows epoch times are expressed as time elapsed since midnight on
+ // January 1, 1601 at Greenwich, England. This converts the Filetime to
+ // unix epoch in milliseconds.
+ self.StartTime = uint64(cpu.CreationTime.Nanoseconds() / 1e6)
+
+ // Convert to millis.
+ self.User = uint64(windows.FiletimeToDuration(&cpu.UserTime).Nanoseconds() / 1e6)
+ self.Sys = uint64(windows.FiletimeToDuration(&cpu.KernelTime).Nanoseconds() / 1e6)
+ self.Total = self.User + self.Sys
+
+ return nil
+}
+
+func getProcTimes(pid int) (*syscall.Rusage, error) {
+ handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
+ if err != nil {
+ return nil, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
+ }
+ defer syscall.CloseHandle(handle)
+
+ var cpu syscall.Rusage
+ if err := syscall.GetProcessTimes(handle, &cpu.CreationTime, &cpu.ExitTime, &cpu.KernelTime, &cpu.UserTime); err != nil {
+ return nil, errors.Wrapf(err, "GetProcessTimes failed for pid=%v", pid)
+ }
+
+ return &cpu, nil
+}
+
+func (self *ProcArgs) Get(pid int) error {
+ // The minimum supported client for Win32_Process is Windows Vista.
+ if !version.IsWindowsVistaOrGreater() {
+ return ErrNotImplemented{runtime.GOOS}
+ }
+
+ process, err := getWin32Process(int32(pid))
+ if err != nil {
+ return errors.Wrapf(err, "ProcArgs failed for pid=%v", pid)
+ }
+
+ self.List = []string{process.CommandLine}
+ return nil
+}
+
+func (self *FileSystemUsage) Get(path string) error {
+ freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, err := windows.GetDiskFreeSpaceEx(path)
+ if err != nil {
+ return errors.Wrap(err, "GetDiskFreeSpaceEx failed")
+ }
+
+ self.Total = totalNumberOfBytes
+ self.Free = totalNumberOfFreeBytes
+ self.Used = self.Total - self.Free
+ self.Avail = freeBytesAvailable
+ return nil
+}
+
+// getWin32Process gets information about the process with the given process ID.
+// It uses a WMI query to get the information from the local system.
+func getWin32Process(pid int32) (Win32_Process, error) {
+ var dst []Win32_Process
+ query := fmt.Sprintf("WHERE ProcessId = %d", pid)
+ q := wmi.CreateQuery(&dst, query)
+ err := wmi.Query(q, &dst)
+ if err != nil {
+ return Win32_Process{}, fmt.Errorf("could not get Win32_Process %s: %v", query, err)
+ }
+ if len(dst) < 1 {
+ return Win32_Process{}, fmt.Errorf("could not get Win32_Process %s: Process not found", query)
+ }
+ return dst[0], nil
+}
+
+func getWin32OperatingSystem() (Win32_OperatingSystem, error) {
+ var dst []Win32_OperatingSystem
+ q := wmi.CreateQuery(&dst, "")
+ err := wmi.Query(q, &dst)
+ if err != nil {
+ return Win32_OperatingSystem{}, errors.Wrap(err, "wmi query for Win32_OperatingSystem failed")
+ }
+ if len(dst) != 1 {
+ return Win32_OperatingSystem{}, errors.New("wmi query for Win32_OperatingSystem failed")
+ }
+ return dst[0], nil
+}
+
+func (self *Rusage) Get(who int) error {
+ if who != 0 {
+ return ErrNotImplemented{runtime.GOOS}
+ }
+
+ pid := os.Getpid()
+ cpu, err := getProcTimes(pid)
+ if err != nil {
+ return err
+ }
+
+ self.Utime = windows.FiletimeToDuration(&cpu.UserTime)
+ self.Stime = windows.FiletimeToDuration(&cpu.KernelTime)
+
+ return nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/doc.go b/vendor/github.com/elastic/gosigar/sys/windows/doc.go
new file mode 100644
index 000000000..dda57aa83
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/doc.go
@@ -0,0 +1,2 @@
+// Package windows contains various Windows system call.
+package windows
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go b/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go
new file mode 100644
index 000000000..85de365e1
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/ntquery.go
@@ -0,0 +1,132 @@
+// +build windows
+
+package windows
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/pkg/errors"
+)
+
+// On both 32-bit and 64-bit systems NtQuerySystemInformation expects the
+// size of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION to be 48.
+const sizeofSystemProcessorPerformanceInformation = 48
+
+// ProcessBasicInformation is an equivalent representation of
+// PROCESS_BASIC_INFORMATION in the Windows API.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
+type ProcessBasicInformation struct {
+ ExitStatus uint
+ PebBaseAddress uintptr
+ AffinityMask uint
+ BasePriority uint
+ UniqueProcessID uint
+ InheritedFromUniqueProcessID uint
+}
+
+// NtQueryProcessBasicInformation queries basic information about the process
+// associated with the given handle (provided by OpenProcess). It uses the
+// NtQueryInformationProcess function to collect the data.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
+func NtQueryProcessBasicInformation(handle syscall.Handle) (ProcessBasicInformation, error) {
+ var processBasicInfo ProcessBasicInformation
+ processBasicInfoPtr := (*byte)(unsafe.Pointer(&processBasicInfo))
+ size := uint32(unsafe.Sizeof(processBasicInfo))
+ ntStatus, _ := _NtQueryInformationProcess(handle, 0, processBasicInfoPtr, size, nil)
+ if ntStatus != 0 {
+ return ProcessBasicInformation{}, errors.Errorf("NtQueryInformationProcess failed, NTSTATUS=0x%X", ntStatus)
+ }
+
+ return processBasicInfo, nil
+}
+
+// SystemProcessorPerformanceInformation contains CPU performance information
+// for a single CPU.
+type SystemProcessorPerformanceInformation struct {
+ IdleTime time.Duration // Amount of time spent idle.
+ KernelTime time.Duration // Kernel time does NOT include time spent in idle.
+ UserTime time.Duration // Amount of time spent executing in user mode.
+}
+
+// _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION is an equivalent representation of
+// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION in the Windows API. This struct is
+// used internally with NtQuerySystemInformation call and is not exported. The
+// exported equivalent is SystemProcessorPerformanceInformation.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
+type _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION struct {
+ IdleTime int64
+ KernelTime int64
+ UserTime int64
+ Reserved1 [2]int64
+ Reserved2 uint32
+}
+
+// NtQuerySystemProcessorPerformanceInformation queries CPU performance
+// information for each CPU. It uses the NtQuerySystemInformation function to
+// collect the SystemProcessorPerformanceInformation.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
+func NtQuerySystemProcessorPerformanceInformation() ([]SystemProcessorPerformanceInformation, error) {
+ // NTSTATUS code for success.
+ // https://msdn.microsoft.com/en-us/library/cc704588.aspx
+ const STATUS_SUCCESS = 0
+
+ // From the _SYSTEM_INFORMATION_CLASS enum.
+ // http://processhacker.sourceforge.net/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0
+ const systemProcessorPerformanceInformation = 8
+
+ // Create a buffer large enough to hold an entry for each processor.
+ b := make([]byte, runtime.NumCPU()*sizeofSystemProcessorPerformanceInformation)
+
+ // Query the performance information. Note that this function uses 0 to
+ // indicate success. Most other Windows functions use non-zero for success.
+ var returnLength uint32
+ ntStatus, _ := _NtQuerySystemInformation(systemProcessorPerformanceInformation, &b[0], uint32(len(b)), &returnLength)
+ if ntStatus != STATUS_SUCCESS {
+ return nil, errors.Errorf("NtQuerySystemInformation failed, NTSTATUS=0x%X, bufLength=%v, returnLength=%v", ntStatus, len(b), returnLength)
+ }
+
+ return readSystemProcessorPerformanceInformationBuffer(b)
+}
+
+// readSystemProcessorPerformanceInformationBuffer reads from a buffer
+// containing SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION data. The buffer should
+// contain one entry for each CPU.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
+func readSystemProcessorPerformanceInformationBuffer(b []byte) ([]SystemProcessorPerformanceInformation, error) {
+ n := len(b) / sizeofSystemProcessorPerformanceInformation
+ r := bytes.NewReader(b)
+
+ rtn := make([]SystemProcessorPerformanceInformation, 0, n)
+ for i := 0; i < n; i++ {
+ _, err := r.Seek(int64(i*sizeofSystemProcessorPerformanceInformation), io.SeekStart)
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed to seek to cpuN=%v in buffer", i)
+ }
+
+ times := make([]uint64, 3)
+ for j := range times {
+ err := binary.Read(r, binary.LittleEndian, &times[j])
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed reading cpu times for cpuN=%v", i)
+ }
+ }
+
+ idleTime := time.Duration(times[0] * 100)
+ kernelTime := time.Duration(times[1] * 100)
+ userTime := time.Duration(times[2] * 100)
+
+ rtn = append(rtn, SystemProcessorPerformanceInformation{
+ IdleTime: idleTime,
+ KernelTime: kernelTime - idleTime, // Subtract out idle time from kernel time.
+ UserTime: userTime,
+ })
+ }
+
+ return rtn, nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/privileges.go b/vendor/github.com/elastic/gosigar/sys/windows/privileges.go
new file mode 100644
index 000000000..28c78fd22
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/privileges.go
@@ -0,0 +1,272 @@
+// +build windows
+
+package windows
+
+import (
+ "bytes"
+ "encoding/binary"
+ "encoding/json"
+ "fmt"
+ "runtime"
+ "strings"
+ "sync"
+ "syscall"
+
+ "github.com/pkg/errors"
+ "golang.org/x/sys/windows"
+)
+
+// Cache of privilege names to LUIDs.
+var (
+ privNames = make(map[string]int64)
+ privNameMutex sync.Mutex
+)
+
+const (
+ // SeDebugPrivilege is the name of the privilege used to debug programs.
+ SeDebugPrivilege = "SeDebugPrivilege"
+)
+
+// Errors returned by AdjustTokenPrivileges.
+const (
+ ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
+)
+
+// Attribute bits for privileges.
+const (
+ _SE_PRIVILEGE_ENABLED_BY_DEFAULT uint32 = 0x00000001
+ _SE_PRIVILEGE_ENABLED uint32 = 0x00000002
+ _SE_PRIVILEGE_REMOVED uint32 = 0x00000004
+ _SE_PRIVILEGE_USED_FOR_ACCESS uint32 = 0x80000000
+)
+
+// Privilege contains information about a single privilege associated with a
+// Token.
+type Privilege struct {
+ LUID int64 `json:"-"` // Locally unique identifier (guaranteed only until the system is restarted).
+ Name string `json:"-"`
+ EnabledByDefault bool `json:"enabled_by_default,omitempty"`
+ Enabled bool `json:"enabled"`
+ Removed bool `json:"removed,omitempty"`
+ Used bool `json:"used,omitempty"`
+}
+
+func (p Privilege) String() string {
+ var buf bytes.Buffer
+ buf.WriteString(p.Name)
+ buf.WriteString("=(")
+
+ opts := make([]string, 0, 4)
+ if p.EnabledByDefault {
+ opts = append(opts, "Default")
+ }
+ if p.Enabled {
+ opts = append(opts, "Enabled")
+ }
+ if !p.EnabledByDefault && !p.Enabled {
+ opts = append(opts, "Disabled")
+ }
+ if p.Removed {
+ opts = append(opts, "Removed")
+ }
+ if p.Used {
+ opts = append(opts, "Used")
+ }
+
+ buf.WriteString(strings.Join(opts, ", "))
+ buf.WriteString(")")
+
+ // Example: SeDebugPrivilege=(Default, Enabled)
+ return buf.String()
+}
+
+// User represent the information about a Windows account.
+type User struct {
+ SID string
+ Account string
+ Domain string
+ Type uint32
+}
+
+func (u User) String() string {
+ return fmt.Sprintf(`User:%v\%v, SID:%v, Type:%v`, u.Domain, u.Account, u.SID, u.Type)
+}
+
+// DebugInfo contains general debug info about the current process.
+type DebugInfo struct {
+ OSVersion Version // OS version info.
+ Arch string // Architecture of the machine.
+ NumCPU int // Number of CPUs.
+ User User // User that this process is running as.
+ ProcessPrivs map[string]Privilege // Privileges held by the process.
+}
+
+func (d DebugInfo) String() string {
+ bytes, _ := json.Marshal(d)
+ return string(bytes)
+}
+
+// LookupPrivilegeName looks up a privilege name given a LUID value.
+func LookupPrivilegeName(systemName string, luid int64) (string, error) {
+ buf := make([]uint16, 256)
+ bufSize := uint32(len(buf))
+ err := _LookupPrivilegeName(systemName, &luid, &buf[0], &bufSize)
+ if err != nil {
+ return "", errors.Wrapf(err, "LookupPrivilegeName failed for luid=%v", luid)
+ }
+
+ return syscall.UTF16ToString(buf), nil
+}
+
+// mapPrivileges maps privilege names to LUID values.
+func mapPrivileges(names []string) ([]int64, error) {
+ var privileges []int64
+ privNameMutex.Lock()
+ defer privNameMutex.Unlock()
+ for _, name := range names {
+ p, ok := privNames[name]
+ if !ok {
+ err := _LookupPrivilegeValue("", name, &p)
+ if err != nil {
+ return nil, errors.Wrapf(err, "LookupPrivilegeValue failed on '%v'", name)
+ }
+ privNames[name] = p
+ }
+ privileges = append(privileges, p)
+ }
+ return privileges, nil
+}
+
+// EnableTokenPrivileges enables the specified privileges in the given
+// Token. The token must have TOKEN_ADJUST_PRIVILEGES access. If the token
+// does not already contain the privilege it cannot be enabled.
+func EnableTokenPrivileges(token syscall.Token, privileges ...string) error {
+ privValues, err := mapPrivileges(privileges)
+ if err != nil {
+ return err
+ }
+
+ var b bytes.Buffer
+ binary.Write(&b, binary.LittleEndian, uint32(len(privValues)))
+ for _, p := range privValues {
+ binary.Write(&b, binary.LittleEndian, p)
+ binary.Write(&b, binary.LittleEndian, uint32(_SE_PRIVILEGE_ENABLED))
+ }
+
+ success, err := _AdjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(b.Len()), nil, nil)
+ if !success {
+ return err
+ }
+ if err == ERROR_NOT_ALL_ASSIGNED {
+ return errors.Wrap(err, "error not all privileges were assigned")
+ }
+
+ return nil
+}
+
+// GetTokenPrivileges returns a list of privileges associated with a token.
+// The provided token must have at a minimum TOKEN_QUERY access. This is a
+// wrapper around the GetTokenInformation function.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
+func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) {
+ // Determine the required buffer size.
+ var size uint32
+ syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size)
+
+ // This buffer will receive a TOKEN_PRIVILEGE structure.
+ b := bytes.NewBuffer(make([]byte, size))
+ err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size)
+ if err != nil {
+ return nil, errors.Wrap(err, "GetTokenInformation failed")
+ }
+
+ var privilegeCount uint32
+ err = binary.Read(b, binary.LittleEndian, &privilegeCount)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to read PrivilegeCount")
+ }
+
+ rtn := make(map[string]Privilege, privilegeCount)
+ for i := 0; i < int(privilegeCount); i++ {
+ var luid int64
+ err = binary.Read(b, binary.LittleEndian, &luid)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to read LUID value")
+ }
+
+ var attributes uint32
+ err = binary.Read(b, binary.LittleEndian, &attributes)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to read attributes")
+ }
+
+ name, err := LookupPrivilegeName("", luid)
+ if err != nil {
+ return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid)
+ }
+
+ rtn[name] = Privilege{
+ LUID: luid,
+ Name: name,
+ EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0,
+ Enabled: (attributes & _SE_PRIVILEGE_ENABLED) > 0,
+ Removed: (attributes & _SE_PRIVILEGE_REMOVED) > 0,
+ Used: (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0,
+ }
+ }
+
+ return rtn, nil
+}
+
+// GetTokenUser returns the User associated with the given Token.
+func GetTokenUser(token syscall.Token) (User, error) {
+ tokenUser, err := token.GetTokenUser()
+ if err != nil {
+ return User{}, errors.Wrap(err, "GetTokenUser failed")
+ }
+
+ var user User
+ user.SID, err = tokenUser.User.Sid.String()
+ if err != nil {
+ return user, errors.Wrap(err, "ConvertSidToStringSid failed")
+ }
+
+ user.Account, user.Domain, user.Type, err = tokenUser.User.Sid.LookupAccount("")
+ if err != nil {
+ return user, errors.Wrap(err, "LookupAccountSid failed")
+ }
+
+ return user, nil
+}
+
+// GetDebugInfo returns general debug info about the current process.
+func GetDebugInfo() (*DebugInfo, error) {
+ h, err := windows.GetCurrentProcess()
+ if err != nil {
+ return nil, err
+ }
+
+ var token syscall.Token
+ err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token)
+ if err != nil {
+ return nil, err
+ }
+
+ privs, err := GetTokenPrivileges(token)
+ if err != nil {
+ return nil, err
+ }
+
+ user, err := GetTokenUser(token)
+ if err != nil {
+ return nil, err
+ }
+
+ return &DebugInfo{
+ User: user,
+ ProcessPrivs: privs,
+ OSVersion: GetWindowsVersion(),
+ Arch: runtime.GOARCH,
+ NumCPU: runtime.NumCPU(),
+ }, nil
+}
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
new file mode 100644
index 000000000..88df0febf
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
@@ -0,0 +1,385 @@
+package windows
+
+import (
+ "fmt"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/pkg/errors"
+)
+
+var (
+ sizeofUint32 = 4
+ sizeofProcessEntry32 = uint32(unsafe.Sizeof(ProcessEntry32{}))
+ sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{}))
+ sizeofMemoryStatusEx = uint32(unsafe.Sizeof(MemoryStatusEx{}))
+)
+
+// Process-specific access rights. Others are declared in the syscall package.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx
+const (
+ PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000
+ PROCESS_VM_READ uint32 = 0x0010
+)
+
+// MAX_PATH is the maximum length for a path in Windows.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
+const MAX_PATH = 260
+
+// DriveType represents a type of drive (removable, fixed, CD-ROM, RAM disk, or
+// network drive).
+type DriveType uint32
+
+// Drive types as returned by GetDriveType.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx
+const (
+ DRIVE_UNKNOWN DriveType = iota
+ DRIVE_NO_ROOT_DIR
+ DRIVE_REMOVABLE
+ DRIVE_FIXED
+ DRIVE_REMOTE
+ DRIVE_CDROM
+ DRIVE_RAMDISK
+)
+
+func (dt DriveType) String() string {
+ names := map[DriveType]string{
+ DRIVE_UNKNOWN: "unknown",
+ DRIVE_NO_ROOT_DIR: "invalid",
+ DRIVE_REMOVABLE: "removable",
+ DRIVE_FIXED: "fixed",
+ DRIVE_REMOTE: "remote",
+ DRIVE_CDROM: "cdrom",
+ DRIVE_RAMDISK: "ramdisk",
+ }
+
+ name, found := names[dt]
+ if !found {
+ return "unknown DriveType value"
+ }
+ return name
+}
+
+// Flags that can be used with CreateToolhelp32Snapshot.
+const (
+ TH32CS_INHERIT uint32 = 0x80000000 // Indicates that the snapshot handle is to be inheritable.
+ TH32CS_SNAPHEAPLIST uint32 = 0x00000001 // Includes all heaps of the process specified in th32ProcessID in the snapshot.
+ TH32CS_SNAPMODULE uint32 = 0x00000008 // Includes all modules of the process specified in th32ProcessID in the snapshot.
+ TH32CS_SNAPMODULE32 uint32 = 0x00000010 // Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process.
+ TH32CS_SNAPPROCESS uint32 = 0x00000002 // Includes all processes in the system in the snapshot.
+ TH32CS_SNAPTHREAD uint32 = 0x00000004 // Includes all threads in the system in the snapshot.
+)
+
+// ProcessEntry32 is an equivalent representation of PROCESSENTRY32 in the
+// Windows API. It contains a process's information. Do not modify or reorder.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx
+type ProcessEntry32 struct {
+ size uint32
+ CntUsage uint32
+ ProcessID uint32
+ DefaultHeapID uintptr
+ ModuleID uint32
+ CntThreads uint32
+ ParentProcessID uint32
+ PriorityClassBase int32
+ Flags uint32
+ exeFile [MAX_PATH]uint16
+}
+
+// ExeFile returns the name of the executable file for the process. It does
+// not contain the full path.
+func (p ProcessEntry32) ExeFile() string {
+ return syscall.UTF16ToString(p.exeFile[:])
+}
+
+func (p ProcessEntry32) String() string {
+ return fmt.Sprintf("{CntUsage:%v ProcessID:%v DefaultHeapID:%v ModuleID:%v "+
+ "CntThreads:%v ParentProcessID:%v PriorityClassBase:%v Flags:%v ExeFile:%v",
+ p.CntUsage, p.ProcessID, p.DefaultHeapID, p.ModuleID, p.CntThreads,
+ p.ParentProcessID, p.PriorityClassBase, p.Flags, p.ExeFile())
+}
+
+// MemoryStatusEx is an equivalent representation of MEMORYSTATUSEX in the
+// Windows API. It contains information about the current state of both physical
+// and virtual memory, including extended memory.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770
+type MemoryStatusEx struct {
+ length uint32
+ MemoryLoad uint32
+ TotalPhys uint64
+ AvailPhys uint64
+ TotalPageFile uint64
+ AvailPageFile uint64
+ TotalVirtual uint64
+ AvailVirtual uint64
+ AvailExtendedVirtual uint64
+}
+
+// ProcessMemoryCountersEx is an equivalent representation of
+// PROCESS_MEMORY_COUNTERS_EX in the Windows API.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx
+type ProcessMemoryCountersEx struct {
+ cb uint32
+ PageFaultCount uint32
+ PeakWorkingSetSize uintptr
+ WorkingSetSize uintptr
+ QuotaPeakPagedPoolUsage uintptr
+ QuotaPagedPoolUsage uintptr
+ QuotaPeakNonPagedPoolUsage uintptr
+ QuotaNonPagedPoolUsage uintptr
+ PagefileUsage uintptr
+ PeakPagefileUsage uintptr
+ PrivateUsage uintptr
+}
+
+// GetLogicalDriveStrings returns a list of drives in the system.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364975(v=vs.85).aspx
+func GetLogicalDriveStrings() ([]string, error) {
+ // Determine the size of the buffer required to receive all drives.
+ bufferLength, err := _GetLogicalDriveStringsW(0, nil)
+ if err != nil {
+ return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed to get buffer length")
+ }
+ if bufferLength < 0 {
+ return nil, errors.New("GetLogicalDriveStringsW returned an invalid buffer length")
+ }
+
+ buffer := make([]uint16, bufferLength)
+ _, err = _GetLogicalDriveStringsW(uint32(len(buffer)), &buffer[0])
+ if err != nil {
+ return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed")
+ }
+
+ // Split the uint16 slice at null-terminators.
+ var startIdx int
+ var drivesUTF16 [][]uint16
+ for i, value := range buffer {
+ if value == 0 {
+ drivesUTF16 = append(drivesUTF16, buffer[startIdx:i])
+ startIdx = i + 1
+ }
+ }
+
+ // Convert the utf16 slices to strings.
+ drives := make([]string, 0, len(drivesUTF16))
+ for _, driveUTF16 := range drivesUTF16 {
+ if len(driveUTF16) > 0 {
+ drives = append(drives, syscall.UTF16ToString(driveUTF16))
+ }
+ }
+
+ return drives, nil
+}
+
+// GlobalMemoryStatusEx retrieves information about the system's current usage
+// of both physical and virtual memory.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx
+func GlobalMemoryStatusEx() (MemoryStatusEx, error) {
+ memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx}
+ err := _GlobalMemoryStatusEx(&memoryStatusEx)
+ if err != nil {
+ return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed")
+ }
+
+ return memoryStatusEx, nil
+}
+
+// GetProcessMemoryInfo retrieves information about the memory usage of the
+// specified process.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx
+func GetProcessMemoryInfo(handle syscall.Handle) (ProcessMemoryCountersEx, error) {
+ processMemoryCountersEx := ProcessMemoryCountersEx{cb: sizeofProcessMemoryCountersEx}
+ err := _GetProcessMemoryInfo(handle, &processMemoryCountersEx, processMemoryCountersEx.cb)
+ if err != nil {
+ return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed")
+ }
+
+ return processMemoryCountersEx, nil
+}
+
+// GetProcessImageFileName Retrieves the name of the executable file for the
+// specified process.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx
+func GetProcessImageFileName(handle syscall.Handle) (string, error) {
+ buffer := make([]uint16, MAX_PATH)
+ _, err := _GetProcessImageFileName(handle, &buffer[0], uint32(len(buffer)))
+ if err != nil {
+ return "", errors.Wrap(err, "GetProcessImageFileName failed")
+ }
+
+ return syscall.UTF16ToString(buffer), nil
+}
+
+// GetSystemTimes retrieves system timing information. On a multiprocessor
+// system, the values returned are the sum of the designated times across all
+// processors. The returned kernel time does not include the system idle time.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx
+func GetSystemTimes() (idle, kernel, user time.Duration, err error) {
+ var idleTime, kernelTime, userTime syscall.Filetime
+ err = _GetSystemTimes(&idleTime, &kernelTime, &userTime)
+ if err != nil {
+ return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed")
+ }
+
+ idle = FiletimeToDuration(&idleTime)
+ kernel = FiletimeToDuration(&kernelTime) // Kernel time includes idle time so we subtract it out.
+ user = FiletimeToDuration(&userTime)
+
+ return idle, kernel - idle, user, nil
+}
+
+// FiletimeToDuration converts a Filetime to a time.Duration. Do not use this
+// method to convert a Filetime to an actual clock time, for that use
+// Filetime.Nanosecond().
+func FiletimeToDuration(ft *syscall.Filetime) time.Duration {
+ n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
+ return time.Duration(n * 100)
+}
+
+// GetDriveType Determines whether a disk drive is a removable, fixed, CD-ROM,
+// RAM disk, or network drive. A trailing backslash is required on the
+// rootPathName.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939
+func GetDriveType(rootPathName string) (DriveType, error) {
+ rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName)
+ if err != nil {
+ return DRIVE_UNKNOWN, errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName)
+ }
+
+ dt, err := _GetDriveType(rootPathNamePtr)
+ if err != nil {
+ return DRIVE_UNKNOWN, errors.Wrapf(err, "GetDriveType failed for rootPathName=%v", rootPathName)
+ }
+
+ return dt, nil
+}
+
+// EnumProcesses retrieves the process identifier for each process object in the
+// system. This function can return a max of 65536 PIDs. If there are more
+// processes than that then this will not return them all.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx
+func EnumProcesses() ([]uint32, error) {
+ enumProcesses := func(size int) ([]uint32, error) {
+ var (
+ pids = make([]uint32, size)
+ sizeBytes = len(pids) * sizeofUint32
+ bytesWritten uint32
+ )
+
+ err := _EnumProcesses(&pids[0], uint32(sizeBytes), &bytesWritten)
+
+ pidsWritten := int(bytesWritten) / sizeofUint32
+ if int(bytesWritten)%sizeofUint32 != 0 || pidsWritten > len(pids) {
+ return nil, errors.Errorf("EnumProcesses returned an invalid bytesWritten value of %v", bytesWritten)
+ }
+ pids = pids[:pidsWritten]
+
+ return pids, err
+ }
+
+ // Retry the EnumProcesses call with larger arrays if needed.
+ size := 2048
+ var pids []uint32
+ for tries := 0; tries < 5; tries++ {
+ var err error
+ pids, err = enumProcesses(size)
+ if err != nil {
+ return nil, errors.Wrap(err, "EnumProcesses failed")
+ }
+
+ if len(pids) < size {
+ break
+ }
+
+ // Increase the size the pids array and retry the enumProcesses call
+ // because the array wasn't large enough to hold all of the processes.
+ size *= 2
+ }
+
+ return pids, nil
+}
+
+// GetDiskFreeSpaceEx retrieves information about the amount of space that is
+// available on a disk volume, which is the total amount of space, the total
+// amount of free space, and the total amount of free space available to the
+// user that is associated with the calling thread.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx
+func GetDiskFreeSpaceEx(directoryName string) (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64, err error) {
+ directoryNamePtr, err := syscall.UTF16PtrFromString(directoryName)
+ if err != nil {
+ return 0, 0, 0, errors.Wrapf(err, "UTF16PtrFromString failed for directoryName=%v", directoryName)
+ }
+
+ err = _GetDiskFreeSpaceEx(directoryNamePtr, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes)
+ if err != nil {
+ return 0, 0, 0, err
+ }
+
+ return freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, nil
+}
+
+// CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well
+// as the heaps, modules, and threads used by these processes.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx
+func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) {
+ h, err := _CreateToolhelp32Snapshot(flags, pid)
+ if err != nil {
+ return syscall.InvalidHandle, err
+ }
+ if h == syscall.InvalidHandle {
+ return syscall.InvalidHandle, syscall.GetLastError()
+ }
+
+ return h, nil
+}
+
+// Process32First retrieves information about the first process encountered in a
+// system snapshot.
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834
+func Process32First(handle syscall.Handle) (ProcessEntry32, error) {
+ processEntry32 := ProcessEntry32{size: sizeofProcessEntry32}
+ err := _Process32First(handle, &processEntry32)
+ if err != nil {
+ return ProcessEntry32{}, errors.Wrap(err, "Process32First failed")
+ }
+
+ return processEntry32, nil
+}
+
+// Process32Next retrieves information about the next process recorded in a
+// system snapshot. When there are no more processes to iterate then
+// syscall.ERROR_NO_MORE_FILES is returned (use errors.Cause() to unwrap).
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684836
+func Process32Next(handle syscall.Handle) (ProcessEntry32, error) {
+ processEntry32 := ProcessEntry32{size: sizeofProcessEntry32}
+ err := _Process32Next(handle, &processEntry32)
+ if err != nil {
+ return ProcessEntry32{}, errors.Wrap(err, "Process32Next failed")
+ }
+
+ return processEntry32, nil
+}
+
+// Use "GOOS=windows go generate -v -x ." to generate the source.
+
+// Add -trace to enable debug prints around syscalls.
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go
+
+// Windows API calls
+//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
+//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
+//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo
+//sys _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW
+//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes
+//sys _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW
+//sys _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
+//sys _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW
+//sys _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW
+//sys _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32NextW
+//sys _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) = kernel32.CreateToolhelp32Snapshot
+//sys _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQuerySystemInformation
+//sys _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQueryInformationProcess
+//sys _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
+//sys _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW
+//sys _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/version.go b/vendor/github.com/elastic/gosigar/sys/windows/version.go
new file mode 100644
index 000000000..d0bca89c1
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/version.go
@@ -0,0 +1,43 @@
+// +build windows
+
+package windows
+
+import (
+ "fmt"
+ "syscall"
+)
+
+// Version identifies a Windows version by major, minor, and build number.
+type Version struct {
+ Major int
+ Minor int
+ Build int
+}
+
+// GetWindowsVersion returns the Windows version information. Applications not
+// manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version
+// value (6.2).
+//
+// For a table of version numbers see:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
+func GetWindowsVersion() Version {
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
+ ver, err := syscall.GetVersion()
+ if err != nil {
+ // GetVersion should never return an error.
+ panic(fmt.Errorf("GetVersion failed: %v", err))
+ }
+
+ return Version{
+ Major: int(ver & 0xFF),
+ Minor: int(ver >> 8 & 0xFF),
+ Build: int(ver >> 16),
+ }
+}
+
+// IsWindowsVistaOrGreater returns true if the Windows version is Vista or
+// greater.
+func (v Version) IsWindowsVistaOrGreater() bool {
+ // Vista is 6.0.
+ return v.Major >= 6 && v.Minor >= 0
+}
diff --git a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
new file mode 100644
index 000000000..53fae4e3b
--- /dev/null
+++ b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
@@ -0,0 +1,260 @@
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+
+package windows
+
+import "unsafe"
+import "syscall"
+
+var _ unsafe.Pointer
+
+var (
+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+ modpsapi = syscall.NewLazyDLL("psapi.dll")
+ modntdll = syscall.NewLazyDLL("ntdll.dll")
+ modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
+
+ procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
+ procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
+ procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
+ procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW")
+ procGetSystemTimes = modkernel32.NewProc("GetSystemTimes")
+ procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW")
+ procEnumProcesses = modpsapi.NewProc("EnumProcesses")
+ procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
+ procProcess32FirstW = modkernel32.NewProc("Process32FirstW")
+ procProcess32NextW = modkernel32.NewProc("Process32NextW")
+ procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
+ procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation")
+ procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
+ procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
+ procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
+ procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
+)
+
+func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) {
+ r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) {
+ r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0)
+ length = uint32(r0)
+ if length == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) {
+ r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size))
+ length = uint32(r0)
+ if length == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) {
+ r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0)
+ dt = DriveType(r0)
+ if dt == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned)))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) {
+ r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) {
+ r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0)
+ handle = syscall.Handle(r0)
+ if handle == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) {
+ r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0)
+ ntstatus = uint32(r0)
+ if ntstatus == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) {
+ r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0)
+ ntstatus = uint32(r0)
+ if ntstatus == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ return __LookupPrivilegeName(_p0, luid, buffer, size)
+}
+
+func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(systemName)
+ if err != nil {
+ return
+ }
+ var _p1 *uint16
+ _p1, err = syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return
+ }
+ return __LookupPrivilegeValue(_p0, _p1, luid)
+}
+
+func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) {
+ r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
+ var _p0 uint32
+ if releaseAll {
+ _p0 = 1
+ } else {
+ _p0 = 0
+ }
+ r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
+ success = r0 != 0
+ if true {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}