summaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/containerd/go-runc/utils.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containerd/go-runc/utils.go')
-rw-r--r--vendor/github.com/containerd/go-runc/utils.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/vendor/github.com/containerd/go-runc/utils.go b/vendor/github.com/containerd/go-runc/utils.go
new file mode 100644
index 000000000..69ad6ead7
--- /dev/null
+++ b/vendor/github.com/containerd/go-runc/utils.go
@@ -0,0 +1,107 @@
+/*
+ Copyright The containerd Authors.
+
+ 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.
+*/
+
+package runc
+
+import (
+ "bytes"
+ "io/ioutil"
+ "strconv"
+ "strings"
+ "sync"
+ "syscall"
+)
+
+// ReadPidFile reads the pid file at the provided path and returns
+// the pid or an error if the read and conversion is unsuccessful
+func ReadPidFile(path string) (int, error) {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return -1, err
+ }
+ return strconv.Atoi(string(data))
+}
+
+const exitSignalOffset = 128
+
+// exitStatus returns the correct exit status for a process based on if it
+// was signaled or exited cleanly
+func exitStatus(status syscall.WaitStatus) int {
+ if status.Signaled() {
+ return exitSignalOffset + int(status.Signal())
+ }
+ return status.ExitStatus()
+}
+
+var bytesBufferPool = sync.Pool{
+ New: func() interface{} {
+ return bytes.NewBuffer(nil)
+ },
+}
+
+func getBuf() *bytes.Buffer {
+ return bytesBufferPool.Get().(*bytes.Buffer)
+}
+
+func putBuf(b *bytes.Buffer) {
+ b.Reset()
+ bytesBufferPool.Put(b)
+}
+
+// fieldsASCII is similar to strings.Fields but only allows ASCII whitespaces
+func fieldsASCII(s string) []string {
+ fn := func(r rune) bool {
+ switch r {
+ case '\t', '\n', '\f', '\r', ' ':
+ return true
+ }
+ return false
+ }
+ return strings.FieldsFunc(s, fn)
+}
+
+// ParsePSOutput parses the runtime's ps raw output and returns a TopResults
+func ParsePSOutput(output []byte) (*TopResults, error) {
+ topResults := &TopResults{}
+
+ lines := strings.Split(string(output), "\n")
+ topResults.Headers = fieldsASCII(lines[0])
+
+ pidIndex := -1
+ for i, name := range topResults.Headers {
+ if name == "PID" {
+ pidIndex = i
+ }
+ }
+
+ for _, line := range lines[1:] {
+ if len(line) == 0 {
+ continue
+ }
+
+ fields := fieldsASCII(line)
+
+ if fields[pidIndex] == "-" {
+ continue
+ }
+
+ process := fields[:len(topResults.Headers)-1]
+ process = append(process, strings.Join(fields[len(topResults.Headers)-1:], " "))
+ topResults.Processes = append(topResults.Processes, process)
+
+ }
+ return topResults, nil
+}