mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-03-13 19:01:09 -04:00
A number of PRs have come through which modified the vendor folder without recording the proper information. This resets everything back to the recorded version.
130 lines
2.3 KiB
Go
130 lines
2.3 KiB
Go
// +build linux
|
|
|
|
package ps
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// UnixProcess is an implementation of Process that contains Unix-specific
|
|
// fields and information.
|
|
type UnixProcess struct {
|
|
pid int
|
|
ppid int
|
|
state rune
|
|
pgrp int
|
|
sid int
|
|
|
|
binary string
|
|
}
|
|
|
|
func (p *UnixProcess) Pid() int {
|
|
return p.pid
|
|
}
|
|
|
|
func (p *UnixProcess) PPid() int {
|
|
return p.ppid
|
|
}
|
|
|
|
func (p *UnixProcess) Executable() string {
|
|
return p.binary
|
|
}
|
|
|
|
// Refresh reloads all the data associated with this process.
|
|
func (p *UnixProcess) Refresh() error {
|
|
statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
|
|
dataBytes, err := ioutil.ReadFile(statPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// First, parse out the image name
|
|
data := string(dataBytes)
|
|
binStart := strings.IndexRune(data, '(') + 1
|
|
binEnd := strings.IndexRune(data[binStart:], ')')
|
|
p.binary = data[binStart : binStart+binEnd]
|
|
|
|
// Move past the image name and start parsing the rest
|
|
data = data[binStart+binEnd+2:]
|
|
_, err = fmt.Sscanf(data,
|
|
"%c %d %d %d",
|
|
&p.state,
|
|
&p.ppid,
|
|
&p.pgrp,
|
|
&p.sid)
|
|
|
|
return err
|
|
}
|
|
|
|
func findProcess(pid int) (Process, error) {
|
|
dir := fmt.Sprintf("/proc/%d", pid)
|
|
_, err := os.Stat(dir)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
return newUnixProcess(pid)
|
|
}
|
|
|
|
func processes() ([]Process, error) {
|
|
d, err := os.Open("/proc")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer d.Close()
|
|
|
|
results := make([]Process, 0, 50)
|
|
for {
|
|
fis, err := d.Readdir(10)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, fi := range fis {
|
|
// We only care about directories, since all pids are dirs
|
|
if !fi.IsDir() {
|
|
continue
|
|
}
|
|
|
|
// We only care if the name starts with a numeric
|
|
name := fi.Name()
|
|
if name[0] < '0' || name[0] > '9' {
|
|
continue
|
|
}
|
|
|
|
// From this point forward, any errors we just ignore, because
|
|
// it might simply be that the process doesn't exist anymore.
|
|
pid, err := strconv.ParseInt(name, 10, 0)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
p, err := newUnixProcess(int(pid))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
results = append(results, p)
|
|
}
|
|
}
|
|
|
|
return results, nil
|
|
}
|
|
|
|
func newUnixProcess(pid int) (*UnixProcess, error) {
|
|
p := &UnixProcess{pid: pid}
|
|
return p, p.Refresh()
|
|
}
|