bug fix & netconn add
This commit is contained in:
parent
fd5cf2c1f6
commit
d981a03b14
21
files_darwin.go
Normal file
21
files_darwin.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//+build darwin
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||||
|
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
//+build linux darwin
|
//+build linux
|
||||||
|
|
||||||
package staros
|
package staros
|
||||||
|
|
||||||
@ -18,4 +18,4 @@ func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
|||||||
|
|
||||||
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
|
||||||
}
|
}
|
||||||
|
@ -23,5 +23,5 @@ func SetFileTimes(file *os.File,info os.FileInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetFileTimesbyTime(file *os.File) {
|
func SetFileTimesbyTime(file *os.File) {
|
||||||
syscall.SetFileTime()
|
|
||||||
}
|
}
|
@ -2,7 +2,100 @@
|
|||||||
|
|
||||||
package staros
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
// Memory 系统内存信息
|
// Memory 系统内存信息
|
||||||
func Memory() MemStatus {
|
func Memory() (MemStatus,error) {
|
||||||
return MemStatus{}
|
return darwinMemory()
|
||||||
|
}
|
||||||
|
|
||||||
|
type swapUsage struct {
|
||||||
|
Total uint64
|
||||||
|
Avail uint64
|
||||||
|
Used uint64
|
||||||
|
Pagesize int32
|
||||||
|
Encrypted bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func darwinMemory() (MemStatus, error) {
|
||||||
|
var err error
|
||||||
|
var res MemStatus
|
||||||
|
vm_stat, err := exec.LookPath("vm_stat")
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
out, err := exec.Command(vm_stat).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
totalString, err := unix.Sysctl("hw.memsize")
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// unix.sysctl() helpfully assumes the result is a null-terminated string and
|
||||||
|
// removes the last byte of the result if it's 0 :/
|
||||||
|
totalString += "\x00"
|
||||||
|
|
||||||
|
res.All = uint64(binary.LittleEndian.Uint64([]byte(totalString)))
|
||||||
|
|
||||||
|
lines := strings.Split(string(out), "\n")
|
||||||
|
pagesize := uint64(unix.Getpagesize())
|
||||||
|
for _, line := range lines {
|
||||||
|
fields := strings.Split(line, ":")
|
||||||
|
if len(fields) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key := strings.TrimSpace(fields[0])
|
||||||
|
value := strings.Trim(fields[1], " .")
|
||||||
|
switch key {
|
||||||
|
case "Pages free":
|
||||||
|
free, e := strconv.ParseUint(value, 10, 64)
|
||||||
|
if e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
res.Free = free * pagesize
|
||||||
|
case "Pages inactive":
|
||||||
|
inactive, e := strconv.ParseUint(value, 10, 64)
|
||||||
|
if e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
res.Available = inactive * pagesize
|
||||||
|
case "Pages active":
|
||||||
|
active, e := strconv.ParseUint(value, 10, 64)
|
||||||
|
if e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
_ = active * pagesize
|
||||||
|
case "Pages wired down":
|
||||||
|
wired, e := strconv.ParseUint(value, 10, 64)
|
||||||
|
if e != nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
_ = wired * pagesize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Available += res.Free
|
||||||
|
res.Used = res.All - res.Available
|
||||||
|
//swap
|
||||||
|
value, err := unix.SysctlRaw("vm.swapusage")
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
if len(value) != 32 {
|
||||||
|
return res, fmt.Errorf("unexpected output of sysctl vm.swapusage: %v (len: %d)", value, len(value))
|
||||||
|
}
|
||||||
|
swap := (*swapUsage)(unsafe.Pointer(&value[0]))
|
||||||
|
res.SwapAll = swap.Total
|
||||||
|
res.SwapUsed = swap.Used
|
||||||
|
res.SwapFree = swap.Avail
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,11 @@ package staros
|
|||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
||||||
// Memory 系统内存信息
|
// Memory 系统内存信息
|
||||||
func Memory() MemStatus {
|
func Memory() (MemStatus, error) {
|
||||||
var mem MemStatus
|
var mem MemStatus
|
||||||
ram := new(syscall.Sysinfo_t)
|
ram := new(syscall.Sysinfo_t)
|
||||||
if err := syscall.Sysinfo(ram); err != nil {
|
if err := syscall.Sysinfo(ram); err != nil {
|
||||||
return mem
|
return mem, err
|
||||||
}
|
}
|
||||||
mem.All = uint64(ram.Totalram)
|
mem.All = uint64(ram.Totalram)
|
||||||
mem.BuffCache = uint64(ram.Bufferram)
|
mem.BuffCache = uint64(ram.Bufferram)
|
||||||
@ -20,5 +20,5 @@ func Memory() MemStatus {
|
|||||||
mem.SwapFree = uint64(ram.Freeswap)
|
mem.SwapFree = uint64(ram.Freeswap)
|
||||||
mem.SwapUsed = uint64(mem.SwapAll - mem.SwapFree)
|
mem.SwapUsed = uint64(mem.SwapAll - mem.SwapFree)
|
||||||
mem.Used = uint64(mem.All - mem.Free)
|
mem.Used = uint64(mem.All - mem.Free)
|
||||||
return mem
|
return mem, nil
|
||||||
}
|
}
|
||||||
|
26
memory_windows.go
Normal file
26
memory_windows.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import "b612.me/win32api"
|
||||||
|
|
||||||
|
// Memory 系统内存信息
|
||||||
|
func Memory() (MemStatus, error) {
|
||||||
|
var mem MemStatus
|
||||||
|
ram := new(win32api.MEMORYSTATUSEX)
|
||||||
|
_, err := win32api.GlobalMemoryStatusEx(ram)
|
||||||
|
if err != nil {
|
||||||
|
return mem, err
|
||||||
|
}
|
||||||
|
mem.All = uint64(ram.UllTotalPhys)
|
||||||
|
mem.Free = uint64(ram.UllAvailPhys)
|
||||||
|
mem.Available = uint64(ram.UllAvailPhys)
|
||||||
|
mem.Used = uint64(mem.All - mem.Free)
|
||||||
|
mem.SwapAll = uint64(ram.UllTotalPageFile)
|
||||||
|
mem.SwapFree = uint64(ram.UllAvailPageFile)
|
||||||
|
mem.SwapUsed = mem.SwapAll - mem.SwapFree
|
||||||
|
mem.VirtualAll = uint64(mem.VirtualAll)
|
||||||
|
mem.VirtualAvail = uint64(mem.VirtualAvail)
|
||||||
|
mem.VirtualUsed = mem.VirtualAll - mem.VirtualUsed
|
||||||
|
return mem, nil
|
||||||
|
}
|
85
network.go
85
network.go
@ -1,85 +0,0 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package staros
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NetUsage() ([]NetAdapter, error) {
|
|
||||||
data, err := ioutil.ReadFile("/proc/net/dev")
|
|
||||||
if err != nil {
|
|
||||||
return []NetAdapter{}, err
|
|
||||||
}
|
|
||||||
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
|
|
||||||
if len(sps) < 3 {
|
|
||||||
return []NetAdapter{}, errors.New("No Adaptor")
|
|
||||||
}
|
|
||||||
var res []NetAdapter
|
|
||||||
netLists := sps[2:]
|
|
||||||
for _, v := range netLists {
|
|
||||||
v = strings.ReplaceAll(v, " ", " ")
|
|
||||||
for strings.Contains(v, " ") {
|
|
||||||
v = strings.ReplaceAll(v, " ", " ")
|
|
||||||
}
|
|
||||||
v = strings.TrimSpace(v)
|
|
||||||
card := strings.Split(v, " ")
|
|
||||||
name := strings.ReplaceAll(card[0], ":", "")
|
|
||||||
recvBytes, _ := strconv.Atoi(card[1])
|
|
||||||
sendBytes, _ := strconv.Atoi(card[9])
|
|
||||||
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NetUsageByname(name string) (NetAdapter, error) {
|
|
||||||
ada, err := NetUsage()
|
|
||||||
if err != nil {
|
|
||||||
return NetAdapter{}, err
|
|
||||||
}
|
|
||||||
for _, v := range ada {
|
|
||||||
if v.Name == name {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NetAdapter{}, errors.New("Not Found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
|
|
||||||
list1, err := NetUsage()
|
|
||||||
if err != nil {
|
|
||||||
return []NetSpeed{}, err
|
|
||||||
}
|
|
||||||
time.Sleep(duration)
|
|
||||||
list2, err := NetUsage()
|
|
||||||
if err != nil {
|
|
||||||
return []NetSpeed{}, err
|
|
||||||
}
|
|
||||||
if len(list1) > len(list2) {
|
|
||||||
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
|
|
||||||
}
|
|
||||||
var res []NetSpeed
|
|
||||||
for k, v := range list1 {
|
|
||||||
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
|
|
||||||
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
|
|
||||||
res = append(res, NetSpeed{v.Name, recv, send})
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
|
||||||
ada, err := NetSpeeds(duration)
|
|
||||||
if err != nil {
|
|
||||||
return NetSpeed{}, err
|
|
||||||
}
|
|
||||||
for _, v := range ada {
|
|
||||||
if v.Name == name {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NetSpeed{}, errors.New("Not Found")
|
|
||||||
}
|
|
9
network_test.go
Normal file
9
network_test.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_TrimSpace(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
248
network_unix.go
Normal file
248
network_unix.go
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NetUsage() ([]NetAdapter, error) {
|
||||||
|
data, err := ioutil.ReadFile("/proc/net/dev")
|
||||||
|
if err != nil {
|
||||||
|
return []NetAdapter{}, err
|
||||||
|
}
|
||||||
|
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||||
|
if len(sps) < 3 {
|
||||||
|
return []NetAdapter{}, errors.New("No Adaptor")
|
||||||
|
}
|
||||||
|
var res []NetAdapter
|
||||||
|
netLists := sps[2:]
|
||||||
|
for _, v := range netLists {
|
||||||
|
v = strings.ReplaceAll(v, " ", " ")
|
||||||
|
for strings.Contains(v, " ") {
|
||||||
|
v = strings.ReplaceAll(v, " ", " ")
|
||||||
|
}
|
||||||
|
v = strings.TrimSpace(v)
|
||||||
|
card := strings.Split(v, " ")
|
||||||
|
name := strings.ReplaceAll(card[0], ":", "")
|
||||||
|
recvBytes, _ := strconv.Atoi(card[1])
|
||||||
|
sendBytes, _ := strconv.Atoi(card[9])
|
||||||
|
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetUsageByname(name string) (NetAdapter, error) {
|
||||||
|
ada, err := NetUsage()
|
||||||
|
if err != nil {
|
||||||
|
return NetAdapter{}, err
|
||||||
|
}
|
||||||
|
for _, v := range ada {
|
||||||
|
if v.Name == name {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NetAdapter{}, errors.New("Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
|
||||||
|
list1, err := NetUsage()
|
||||||
|
if err != nil {
|
||||||
|
return []NetSpeed{}, err
|
||||||
|
}
|
||||||
|
time.Sleep(duration)
|
||||||
|
list2, err := NetUsage()
|
||||||
|
if err != nil {
|
||||||
|
return []NetSpeed{}, err
|
||||||
|
}
|
||||||
|
if len(list1) > len(list2) {
|
||||||
|
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
|
||||||
|
}
|
||||||
|
var res []NetSpeed
|
||||||
|
for k, v := range list1 {
|
||||||
|
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
|
||||||
|
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
|
||||||
|
res = append(res, NetSpeed{v.Name, recv, send})
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
||||||
|
ada, err := NetSpeeds(duration)
|
||||||
|
if err != nil {
|
||||||
|
return NetSpeed{}, err
|
||||||
|
}
|
||||||
|
for _, v := range ada {
|
||||||
|
if v.Name == name {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NetSpeed{}, errors.New("Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections
|
||||||
|
// if your uid != 0 ,and analysePid==true ,you should have CAP_SYS_PRTACE and CAP_DAC_OVERRIDE/CAP_DAC_READ_SEARCH Caps
|
||||||
|
func NetConnections(analysePid bool) ([]NetConn, error) {
|
||||||
|
var result []NetConn
|
||||||
|
var inodeMap map[string]int64
|
||||||
|
var err error
|
||||||
|
fileList := []string{
|
||||||
|
"/proc/net/tcp",
|
||||||
|
"/proc/net/tcp6",
|
||||||
|
"/proc/net/udp",
|
||||||
|
"/proc/net/udp6",
|
||||||
|
"/proc/net/unix",
|
||||||
|
}
|
||||||
|
if analysePid {
|
||||||
|
inodeMap, err = GetInodeMap()
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, file := range fileList {
|
||||||
|
data, err := ioutil.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
tmpRes, err := analyseNetFiles(data, inodeMap, file[strings.LastIndex(file, "/")+1:])
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
result = append(result, tmpRes...)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetInodeMap() (map[string]int64, error) {
|
||||||
|
res := make(map[string]int64)
|
||||||
|
paths, err := ioutil.ReadDir("/proc")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, v := range paths {
|
||||||
|
if v.IsDir() && Exists("/proc/"+v.Name()+"/fd") {
|
||||||
|
fds, err := ioutil.ReadDir("/proc/" + v.Name() + "/fd")
|
||||||
|
if err != nil && Exists("/proc/"+v.Name()+"/fd") {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, fd := range fds {
|
||||||
|
socket, err := os.Readlink("/proc/" + v.Name() + "/fd/" + fd.Name())
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
start := strings.Index(socket, "[")
|
||||||
|
if start < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pid, err := strconv.ParseInt(v.Name(), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
res[socket[start+1:len(socket)-1]] = pid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
|
||||||
|
if typed == "unix" {
|
||||||
|
return analyseUnixFiles(data, inodeMap, typed)
|
||||||
|
}
|
||||||
|
var result []NetConn
|
||||||
|
strdata := strings.TrimSpace(string(data))
|
||||||
|
strdata = remainOne(strdata, " ", " ")
|
||||||
|
csvData := strings.Split(strdata, "\n")
|
||||||
|
pidMap := make(map[int64]*Process)
|
||||||
|
for line, lineData := range csvData {
|
||||||
|
if line == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v := strings.Split(strings.TrimSpace(lineData), " ")
|
||||||
|
var res NetConn
|
||||||
|
ip, port, err := parseHexIpPort(v[1])
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
res.LocalAddr = ip
|
||||||
|
res.LocalPort = port
|
||||||
|
ip, port, err = parseHexIpPort(v[2])
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
res.RemoteAddr = ip
|
||||||
|
res.RemotePort = port
|
||||||
|
res.Uid, err = strconv.ParseInt(v[7], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
res.Inode = v[9]
|
||||||
|
if inodeMap != nil && len(inodeMap) > 0 {
|
||||||
|
var ok bool
|
||||||
|
res.Pid, ok = inodeMap[res.Inode]
|
||||||
|
if !ok {
|
||||||
|
res.Pid = -1
|
||||||
|
} else {
|
||||||
|
_, ok := pidMap[res.Pid]
|
||||||
|
if !ok {
|
||||||
|
tmp, err := FindProcessByPid(res.Pid)
|
||||||
|
if err != nil {
|
||||||
|
pidMap[res.Pid] = nil
|
||||||
|
} else {
|
||||||
|
pidMap[res.Pid] = &tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Process = pidMap[res.Pid]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Typed = typed
|
||||||
|
result = append(result, res)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
|
||||||
|
var result []NetConn
|
||||||
|
strdata := strings.TrimSpace(string(data))
|
||||||
|
strdata = remainOne(strdata, " ", " ")
|
||||||
|
csvData := strings.Split(strdata, "\n")
|
||||||
|
pidMap := make(map[int64]*Process)
|
||||||
|
for line, lineData := range csvData {
|
||||||
|
if line == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v := strings.Split(strings.TrimSpace(lineData), " ")
|
||||||
|
var res NetConn
|
||||||
|
res.Inode = v[6]
|
||||||
|
if len(v) == 8 {
|
||||||
|
res.Socket = v[7]
|
||||||
|
}
|
||||||
|
if inodeMap != nil && len(inodeMap) > 0 {
|
||||||
|
var ok bool
|
||||||
|
res.Pid, ok = inodeMap[res.Inode]
|
||||||
|
if !ok {
|
||||||
|
res.Pid = -1
|
||||||
|
} else {
|
||||||
|
_, ok := pidMap[res.Pid]
|
||||||
|
if !ok {
|
||||||
|
tmp, err := FindProcessByPid(res.Pid)
|
||||||
|
if err != nil {
|
||||||
|
pidMap[res.Pid] = nil
|
||||||
|
} else {
|
||||||
|
pidMap[res.Pid] = &tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Uid = int64(pidMap[res.Pid].RUID)
|
||||||
|
res.Process = pidMap[res.Pid]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.Typed = typed
|
||||||
|
result = append(result, res)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
@ -24,3 +24,10 @@ func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
|||||||
|
|
||||||
return NetSpeed{}, nil
|
return NetSpeed{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections
|
||||||
|
// if your uid != 0 ,and analysePid==true ,you should have CAP_SYS_PRTACE and CAP_DAC_OVERRIDE/CAP_DAC_READ_SEARCH Caps
|
||||||
|
func NetConnections(analysePid bool) ([]NetConn, error) {
|
||||||
|
var result []NetConn
|
||||||
|
return result, nil
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// +build !windows
|
// +build linux darwin unix
|
||||||
|
|
||||||
package staros
|
package staros
|
||||||
|
|
||||||
|
@ -27,23 +27,6 @@ func IsRoot() bool {
|
|||||||
return wincmd.Isas()
|
return wincmd.Isas()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory 系统内存信息
|
|
||||||
func Memory() MemStatus {
|
|
||||||
var mem MemStatus
|
|
||||||
ram := new(win32api.MEMORYSTATUSEX)
|
|
||||||
win32api.GlobalMemoryStatusEx(ram)
|
|
||||||
mem.All = uint64(ram.UllTotalPhys)
|
|
||||||
mem.Free = uint64(ram.UllAvailPhys)
|
|
||||||
mem.Available = uint64(ram.UllAvailPhys)
|
|
||||||
mem.Used = uint64(mem.All - mem.Free)
|
|
||||||
mem.SwapAll = uint64(ram.UllTotalPageFile)
|
|
||||||
mem.SwapFree = uint64(ram.UllAvailPageFile)
|
|
||||||
mem.SwapUsed = mem.SwapAll - mem.SwapFree
|
|
||||||
mem.VirtualAll = uint64(mem.VirtualAll)
|
|
||||||
mem.VirtualAvail = uint64(mem.VirtualAvail)
|
|
||||||
mem.VirtualUsed = mem.VirtualAll - mem.VirtualUsed
|
|
||||||
return mem
|
|
||||||
}
|
|
||||||
|
|
||||||
func DiskUsage(path string) (disk DiskStatus) {
|
func DiskUsage(path string) (disk DiskStatus) {
|
||||||
kernel32, err := syscall.LoadLibrary("Kernel32.dll")
|
kernel32, err := syscall.LoadLibrary("Kernel32.dll")
|
||||||
|
32
process.go
32
process.go
@ -7,6 +7,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -31,6 +33,7 @@ type StarCmd struct {
|
|||||||
stderrBuf *bytes.Buffer
|
stderrBuf *bytes.Buffer
|
||||||
stdoutpoint int
|
stdoutpoint int
|
||||||
stderrpoint int
|
stderrpoint int
|
||||||
|
lock sync.Mutex
|
||||||
prewrite []string
|
prewrite []string
|
||||||
prewritetime time.Duration
|
prewritetime time.Duration
|
||||||
stopctxfunc context.CancelFunc
|
stopctxfunc context.CancelFunc
|
||||||
@ -98,12 +101,13 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
break
|
|
||||||
}
|
}
|
||||||
out := make([]byte, 65535)
|
out := make([]byte, 65535)
|
||||||
n, err := starcli.outfile.Read(out)
|
n, err := starcli.outfile.Read(out)
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
|
starcli.lock.Lock()
|
||||||
starcli.stdoutBuf.Write(out[:n])
|
starcli.stdoutBuf.Write(out[:n])
|
||||||
|
starcli.lock.Unlock()
|
||||||
for _, v := range out[:n] {
|
for _, v := range out[:n] {
|
||||||
starcli.stdout = append(starcli.stdout, v)
|
starcli.stdout = append(starcli.stdout, v)
|
||||||
}
|
}
|
||||||
@ -112,7 +116,9 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
|||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
starcli.runerr = err
|
if !strings.Contains(err.Error(),"file already closed") {
|
||||||
|
starcli.runerr = err
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,12 +131,13 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
break
|
|
||||||
}
|
}
|
||||||
out := make([]byte, 65535)
|
out := make([]byte, 65535)
|
||||||
n, err := starcli.errfile.Read(out)
|
n, err := starcli.errfile.Read(out)
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
|
starcli.lock.Lock()
|
||||||
starcli.stderrBuf.Write(out[:n])
|
starcli.stderrBuf.Write(out[:n])
|
||||||
|
starcli.lock.Unlock()
|
||||||
for _, v := range out[:n] {
|
for _, v := range out[:n] {
|
||||||
starcli.errout = append(starcli.errout, v)
|
starcli.errout = append(starcli.errout, v)
|
||||||
}
|
}
|
||||||
@ -139,7 +146,9 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
|||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
starcli.runerr = err
|
if !strings.Contains(err.Error(),"file already closed") {
|
||||||
|
starcli.runerr = err
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,8 +156,10 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (starcli *StarCmd) NowLineOutput() (string, error) {
|
func (starcli *StarCmd) NowLineOutput() (string, error) {
|
||||||
|
starcli.lock.Lock()
|
||||||
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
||||||
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
||||||
|
starcli.lock.Unlock()
|
||||||
if len(buferr) != 0 {
|
if len(buferr) != 0 {
|
||||||
return string(buf), errors.New(string(buferr))
|
return string(buf), errors.New(string(buferr))
|
||||||
}
|
}
|
||||||
@ -156,11 +167,15 @@ func (starcli *StarCmd) NowLineOutput() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (starcli *StarCmd) NowLineStdOut() string {
|
func (starcli *StarCmd) NowLineStdOut() string {
|
||||||
|
starcli.lock.Lock()
|
||||||
|
defer starcli.lock.Unlock()
|
||||||
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
||||||
return string(buf)
|
return string(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (starcli *StarCmd) NowLineStdErr() error {
|
func (starcli *StarCmd) NowLineStdErr() error {
|
||||||
|
starcli.lock.Lock()
|
||||||
|
defer starcli.lock.Unlock()
|
||||||
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
||||||
if len(buferr) != 0 {
|
if len(buferr) != 0 {
|
||||||
return errors.New(string(buferr))
|
return errors.New(string(buferr))
|
||||||
@ -170,16 +185,20 @@ func (starcli *StarCmd) NowLineStdErr() error {
|
|||||||
|
|
||||||
func (starcli *StarCmd) NowAllOutput() (string, error) {
|
func (starcli *StarCmd) NowAllOutput() (string, error) {
|
||||||
var outstr string
|
var outstr string
|
||||||
|
starcli.lock.Lock()
|
||||||
buf := make([]byte, starcli.stdoutBuf.Len())
|
buf := make([]byte, starcli.stdoutBuf.Len())
|
||||||
n, _ := starcli.stdoutBuf.Read(buf)
|
n, _ := starcli.stdoutBuf.Read(buf)
|
||||||
|
starcli.lock.Unlock()
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
outstr = string(buf[:n])
|
outstr = string(buf[:n])
|
||||||
}
|
}
|
||||||
if starcli.runerr != nil {
|
if starcli.runerr != nil {
|
||||||
return outstr, starcli.runerr
|
return outstr, starcli.runerr
|
||||||
}
|
}
|
||||||
|
starcli.lock.Lock()
|
||||||
buf = make([]byte, starcli.stderrBuf.Len())
|
buf = make([]byte, starcli.stderrBuf.Len())
|
||||||
n, _ = starcli.stderrBuf.Read(buf)
|
n, _ = starcli.stderrBuf.Read(buf)
|
||||||
|
starcli.lock.Unlock()
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
return outstr, errors.New(string(buf[:n]))
|
return outstr, errors.New(string(buf[:n]))
|
||||||
}
|
}
|
||||||
@ -188,8 +207,10 @@ func (starcli *StarCmd) NowAllOutput() (string, error) {
|
|||||||
|
|
||||||
func (starcli *StarCmd) NowStdOut() string {
|
func (starcli *StarCmd) NowStdOut() string {
|
||||||
var outstr string
|
var outstr string
|
||||||
|
starcli.lock.Lock()
|
||||||
buf := make([]byte, starcli.stdoutBuf.Len())
|
buf := make([]byte, starcli.stdoutBuf.Len())
|
||||||
n, _ := starcli.stdoutBuf.Read(buf)
|
n, _ := starcli.stdoutBuf.Read(buf)
|
||||||
|
starcli.lock.Unlock()
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
outstr = string(buf[:n])
|
outstr = string(buf[:n])
|
||||||
}
|
}
|
||||||
@ -197,9 +218,10 @@ func (starcli *StarCmd) NowStdOut() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (starcli *StarCmd) NowStdErr() error {
|
func (starcli *StarCmd) NowStdErr() error {
|
||||||
|
starcli.lock.Lock()
|
||||||
buf := make([]byte, starcli.stderrBuf.Len())
|
buf := make([]byte, starcli.stderrBuf.Len())
|
||||||
n, _ := starcli.stderrBuf.Read(buf)
|
n, _ := starcli.stderrBuf.Read(buf)
|
||||||
|
starcli.lock.Unlock()
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
return errors.New(string(buf[:n]))
|
return errors.New(string(buf[:n]))
|
||||||
}
|
}
|
||||||
|
175
process_unix.go
175
process_unix.go
@ -30,11 +30,43 @@ func FindProcessByName(name string) (datas []Process, err error) {
|
|||||||
func FindProcess(compare func(Process) bool) (datas []Process, err error) {
|
func FindProcess(compare func(Process) bool) (datas []Process, err error) {
|
||||||
var name, main string
|
var name, main string
|
||||||
var mainb []byte
|
var mainb []byte
|
||||||
paths, errs := ioutil.ReadDir("/proc")
|
var netErr error
|
||||||
if errs != nil {
|
var netInfo []NetConn
|
||||||
err = errs
|
paths, err := ioutil.ReadDir("/proc")
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
netInfo, netErr = NetConnections(false)
|
||||||
|
appendNetInfo := func(p *Process) {
|
||||||
|
if netErr != nil {
|
||||||
|
p.netErr = netErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fds, err := ioutil.ReadDir("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd")
|
||||||
|
if err != nil && Exists("/proc/"+strconv.Itoa(int(p.Pid))+"/fd") {
|
||||||
|
p.netErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, fd := range fds {
|
||||||
|
socket, err := os.Readlink("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd/" + fd.Name())
|
||||||
|
if err != nil {
|
||||||
|
p.netErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start := strings.Index(socket, "[")
|
||||||
|
if start < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sid := socket[start+1 : len(socket)-1]
|
||||||
|
for _, v := range netInfo {
|
||||||
|
if v.Inode == sid {
|
||||||
|
v.Pid = p.Pid
|
||||||
|
v.Process = p
|
||||||
|
p.netConn = append(p.netConn, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, v := range paths {
|
for _, v := range paths {
|
||||||
if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") {
|
if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") {
|
||||||
name, err = readAsString("/proc/" + v.Name() + "/comm")
|
name, err = readAsString("/proc/" + v.Name() + "/comm")
|
||||||
@ -49,68 +81,80 @@ func FindProcess(compare func(Process) bool) (datas []Process, err error) {
|
|||||||
tmp.Name = strings.TrimSpace(name)
|
tmp.Name = strings.TrimSpace(name)
|
||||||
main, err = readAsString("/proc/" + v.Name() + "/status")
|
main, err = readAsString("/proc/" + v.Name() + "/status")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tmp.Err = err
|
||||||
if compare(tmp) {
|
if compare(tmp) {
|
||||||
|
appendNetInfo(&tmp)
|
||||||
datas = append(datas, tmp)
|
datas = append(datas, tmp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
data := splitBy(main, ":")
|
||||||
|
tmp.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
|
||||||
|
tmp.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
|
||||||
|
tmp.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
|
||||||
|
uids := splitBySpace(data["Uid"])
|
||||||
|
gids := splitBySpace(data["Gid"])
|
||||||
|
tmp.RUID, _ = strconv.Atoi(uids[0])
|
||||||
|
tmp.EUID, _ = strconv.Atoi(uids[1])
|
||||||
|
tmp.RGID, _ = strconv.Atoi(gids[0])
|
||||||
|
tmp.EGID, _ = strconv.Atoi(gids[1])
|
||||||
|
tmp.VmPeak, _ = strconv.ParseInt(splitBySpace(data["VmPeak"])[0], 10, 64)
|
||||||
|
tmp.VmSize, _ = strconv.ParseInt(splitBySpace(data["VmSize"])[0], 10, 64)
|
||||||
|
tmp.VmHWM, _ = strconv.ParseInt(splitBySpace(data["VmHWM"])[0], 10, 64)
|
||||||
|
tmp.VmRSS, _ = strconv.ParseInt(splitBySpace(data["VmRSS"])[0], 10, 64)
|
||||||
|
tmp.VmLck, _ = strconv.ParseInt(splitBySpace(data["VmLck"])[0], 10, 64)
|
||||||
|
tmp.VmData, _ = strconv.ParseInt(splitBySpace(data["VmData"])[0], 10, 64)
|
||||||
|
tmp.VmLck *= 1024
|
||||||
|
tmp.VmData *= 1024
|
||||||
|
tmp.VmPeak *= 1024
|
||||||
|
tmp.VmSize *= 1024
|
||||||
|
tmp.VmHWM *= 1024
|
||||||
|
tmp.VmRSS *= 1024
|
||||||
}
|
}
|
||||||
data := splitBy(main, ":")
|
|
||||||
tmp.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
|
|
||||||
tmp.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
|
|
||||||
tmp.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
|
|
||||||
uids := splitBySpace(data["Uid"])
|
|
||||||
gids := splitBySpace(data["Gid"])
|
|
||||||
tmp.RUID, _ = strconv.Atoi(uids[0])
|
|
||||||
tmp.EUID, _ = strconv.Atoi(uids[1])
|
|
||||||
tmp.RGID, _ = strconv.Atoi(gids[0])
|
|
||||||
tmp.EGID, _ = strconv.Atoi(gids[1])
|
|
||||||
tmp.VmPeak, _ = strconv.ParseInt(splitBySpace(data["VmPeak"])[0], 10, 64)
|
|
||||||
tmp.VmSize, _ = strconv.ParseInt(splitBySpace(data["VmSize"])[0], 10, 64)
|
|
||||||
tmp.VmHWM, _ = strconv.ParseInt(splitBySpace(data["VmHWM"])[0], 10, 64)
|
|
||||||
tmp.VmRSS, _ = strconv.ParseInt(splitBySpace(data["VmRSS"])[0], 10, 64)
|
|
||||||
tmp.VmLck, _ = strconv.ParseInt(splitBySpace(data["VmLck"])[0], 10, 64)
|
|
||||||
tmp.VmData, _ = strconv.ParseInt(splitBySpace(data["VmData"])[0], 10, 64)
|
|
||||||
tmp.VmLck *= 1024
|
|
||||||
tmp.VmData *= 1024
|
|
||||||
tmp.VmPeak *= 1024
|
|
||||||
tmp.VmSize *= 1024
|
|
||||||
tmp.VmHWM *= 1024
|
|
||||||
tmp.VmRSS *= 1024
|
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/cmdline")
|
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/cmdline")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tmp.Err = err
|
||||||
if compare(tmp) {
|
if compare(tmp) {
|
||||||
|
appendNetInfo(&tmp)
|
||||||
datas = append(datas, tmp)
|
datas = append(datas, tmp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
args := bytes.Split(mainb, []byte{0})
|
||||||
|
for _, v := range args {
|
||||||
|
tmp.Args = append(tmp.Args, string(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
args := bytes.Split(mainb, []byte{0})
|
|
||||||
for _, v := range args {
|
|
||||||
tmp.Args = append(tmp.Args, string(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/environ")
|
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/environ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tmp.Err = err
|
||||||
if compare(tmp) {
|
if compare(tmp) {
|
||||||
|
appendNetInfo(&tmp)
|
||||||
datas = append(datas, tmp)
|
datas = append(datas, tmp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
args = bytes.Split(mainb, []byte{0})
|
args := bytes.Split(mainb, []byte{0})
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
tmp.Env = append(tmp.Env, string(v))
|
tmp.Env = append(tmp.Env, string(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main, err = readAsString("/proc/" + v.Name() + "/stat")
|
main, err = readAsString("/proc/" + v.Name() + "/stat")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tmp.Err = err
|
||||||
if compare(tmp) {
|
if compare(tmp) {
|
||||||
|
appendNetInfo(&tmp)
|
||||||
datas = append(datas, tmp)
|
datas = append(datas, tmp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
times := splitBySpace(main)
|
||||||
|
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
|
||||||
|
tmp.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
|
||||||
}
|
}
|
||||||
times := splitBySpace(main)
|
|
||||||
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
|
|
||||||
tmp.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
|
|
||||||
if compare(tmp) {
|
if compare(tmp) {
|
||||||
|
appendNetInfo(&tmp)
|
||||||
datas = append(datas, tmp)
|
datas = append(datas, tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,6 +170,38 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
|
|||||||
err = errors.New("Not Found")
|
err = errors.New("Not Found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
netInfo, netErr := NetConnections(false)
|
||||||
|
appendNetInfo := func(p *Process) {
|
||||||
|
if netErr != nil {
|
||||||
|
p.netErr = netErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fds, err := ioutil.ReadDir("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd")
|
||||||
|
if err != nil && Exists("/proc/"+strconv.Itoa(int(p.Pid))+"/fd") {
|
||||||
|
p.netErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, fd := range fds {
|
||||||
|
socket, err := os.Readlink("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd/" + fd.Name())
|
||||||
|
if err != nil {
|
||||||
|
p.netErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
start := strings.Index(socket, "[")
|
||||||
|
if start < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sid := socket[start+1 : len(socket)-1]
|
||||||
|
for _, v := range netInfo {
|
||||||
|
if v.Inode == sid {
|
||||||
|
v.Pid = p.Pid
|
||||||
|
v.Process = p
|
||||||
|
p.netConn = append(p.netConn, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm")
|
name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -157,22 +233,27 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
|
|||||||
datas.VmSize *= 1024
|
datas.VmSize *= 1024
|
||||||
datas.VmHWM *= 1024
|
datas.VmHWM *= 1024
|
||||||
datas.VmRSS *= 1024
|
datas.VmRSS *= 1024
|
||||||
|
appendNetInfo(&datas)
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/cmdline")
|
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/cmdline")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
datas.Err = err
|
||||||
}
|
err = nil
|
||||||
args := bytes.Split(mainb, []byte{0})
|
} else {
|
||||||
for _, v := range args {
|
args := bytes.Split(mainb, []byte{0})
|
||||||
datas.Args = append(datas.Args, string(v))
|
for _, v := range args {
|
||||||
|
datas.Args = append(datas.Args, string(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/environ")
|
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/environ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
datas.Err = err
|
||||||
}
|
err = nil
|
||||||
args = bytes.Split(mainb, []byte{0})
|
} else {
|
||||||
for _, v := range args {
|
args := bytes.Split(mainb, []byte{0})
|
||||||
datas.Env = append(datas.Env, string(v))
|
for _, v := range args {
|
||||||
|
datas.Env = append(datas.Env, string(v))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
datas.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe")
|
datas.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe")
|
||||||
|
@ -62,3 +62,11 @@ func Daemon(path string, args ...string) (int, error) {
|
|||||||
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
|
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Release() error {
|
||||||
|
if err := starcli.CMD.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
starcli.CMD.Process.Release()
|
||||||
|
return nil
|
||||||
|
}
|
@ -9,8 +9,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"b612.me/staros"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SysConf struct {
|
type SysConf struct {
|
||||||
@ -76,9 +74,6 @@ func NewLinuxConf(EqualFlag string) *SysConf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (syscfg *SysConf) ParseFromFile(filepath string) error {
|
func (syscfg *SysConf) ParseFromFile(filepath string) error {
|
||||||
if !staros.Exists(filepath) {
|
|
||||||
return errors.New(filepath + " 不存在")
|
|
||||||
}
|
|
||||||
data, err := ioutil.ReadFile(filepath)
|
data, err := ioutil.ReadFile(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
115
tools.go
115
tools.go
@ -2,7 +2,9 @@ package staros
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,3 +44,116 @@ func readAsString(path string) (string, error) {
|
|||||||
}
|
}
|
||||||
return string(data), nil
|
return string(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func remainOne(data, old, new string) string {
|
||||||
|
data = strings.TrimSpace(data)
|
||||||
|
if !strings.Contains(data, old) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
data = strings.ReplaceAll(data, old, new)
|
||||||
|
return remainOne(data, old, new)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseHexIpPort(str string) (string, int, error) {
|
||||||
|
str = strings.TrimSpace(str)
|
||||||
|
if len(str) != 13 && len(str) != 37 {
|
||||||
|
return "", 0, errors.New("Not a valid ip:port addr:" + str)
|
||||||
|
}
|
||||||
|
ipPort := strings.Split(str, ":")
|
||||||
|
if len(ipPort) != 2 {
|
||||||
|
return "", 0, errors.New("Not a valid ip:port addr:" + str)
|
||||||
|
}
|
||||||
|
if len(ipPort[0]) == 8 {
|
||||||
|
ip, err := parseHexIPv4(ipPort[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
port, err := parseHexPort(ipPort[1])
|
||||||
|
return ip, port, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ipPort[0]) == 32 {
|
||||||
|
ip, err := parseHexIPv6(ipPort[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
port, err := parseHexPort(ipPort[1])
|
||||||
|
return ip, port, err
|
||||||
|
}
|
||||||
|
return "", 0, errors.New("Invalid ip address:" + str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseHexPort(str string) (int, error) {
|
||||||
|
tmpUint32, err := strconv.ParseUint(str, 16, 32)
|
||||||
|
return int(tmpUint32), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseHexIPv4(str string) (string, error) {
|
||||||
|
var result string
|
||||||
|
if len(str) != 8 {
|
||||||
|
return "", errors.New("Not a vaild ipv4:" + str)
|
||||||
|
}
|
||||||
|
tmpUint64, err := strconv.ParseUint(str, 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
numicIp := uint32(tmpUint64)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
result += strconv.FormatUint(uint64(uint8(numicIp>>(8*uint8(i)))), 10) + "."
|
||||||
|
}
|
||||||
|
return result[0 : len(result)-1], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseHexIPv6(str string) (string, error) {
|
||||||
|
var result string
|
||||||
|
if len(str) != 32 {
|
||||||
|
return "", errors.New("Not a vaild ipv6:" + str)
|
||||||
|
}
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
part := str[i*8 : (i+1)*8]
|
||||||
|
tmpUint64, err := strconv.ParseUint(part, 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
tmpUint32 := uint32(tmpUint64)
|
||||||
|
//07C2022A
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
tmp := strconv.FormatUint(uint64(uint8(tmpUint32>>uint8(8*i))), 16)
|
||||||
|
if len(tmp) == 1 {
|
||||||
|
tmp = "0" + tmp
|
||||||
|
}
|
||||||
|
result += tmp
|
||||||
|
if (i+1)%2 == 0 {
|
||||||
|
result += ":"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipv6 := result[0 : len(result)-1]
|
||||||
|
ipv6List := strings.Split(ipv6, ":")
|
||||||
|
prepareZero := false
|
||||||
|
alreadyZero := false
|
||||||
|
for k, v := range ipv6List {
|
||||||
|
if v == "0000" && !alreadyZero {
|
||||||
|
ipv6List[k] = ""
|
||||||
|
prepareZero = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if v != "0000" && prepareZero {
|
||||||
|
alreadyZero = true
|
||||||
|
}
|
||||||
|
var nonZero = 0
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
sig := v[i : i+1]
|
||||||
|
if sig != "0" {
|
||||||
|
nonZero = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipv6List[k] = v[nonZero:4]
|
||||||
|
}
|
||||||
|
ipv6 = strings.TrimSuffix(remainOne(strings.Join(ipv6List, ":"), ":::", "::"), "::")
|
||||||
|
if ipv6 == "" {
|
||||||
|
ipv6 = "::0"
|
||||||
|
}
|
||||||
|
return ipv6, nil
|
||||||
|
}
|
||||||
|
20
typed.go
20
typed.go
@ -46,6 +46,13 @@ type Process struct {
|
|||||||
VmHWM int64
|
VmHWM int64
|
||||||
VmRSS int64
|
VmRSS int64
|
||||||
VmData int64
|
VmData int64
|
||||||
|
netConn []NetConn
|
||||||
|
netErr error
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Process) GetNetConns() ([]NetConn, error) {
|
||||||
|
return p.netConn, p.netErr
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemStatus struct {
|
type MemStatus struct {
|
||||||
@ -70,3 +77,16 @@ type DiskStatus struct {
|
|||||||
Free uint64
|
Free uint64
|
||||||
Available uint64
|
Available uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NetConn struct {
|
||||||
|
LocalAddr string
|
||||||
|
LocalPort int
|
||||||
|
Typed string
|
||||||
|
RemoteAddr string
|
||||||
|
RemotePort int
|
||||||
|
Socket string
|
||||||
|
Inode string
|
||||||
|
Pid int64
|
||||||
|
Uid int64
|
||||||
|
Process *Process
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user