Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c3a165e64a | |||
| ad5c18667a | |||
| cdf3a18981 | |||
| 6de9af62cc | |||
| bca0d42559 | |||
| 26da8c8b88 | |||
| 5c2cce2da2 | |||
| a94fc8d19d |
@@ -0,0 +1,21 @@
|
|||||||
|
//+build linux 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).Ctim)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||||
|
return time.Unix(0, d.CreationTime.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
|
||||||
|
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||||
|
return time.Unix(0, d.LastAccessTime.Nanoseconds())
|
||||||
|
}
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Calc(math string) (float64, error) {
|
||||||
|
math = strings.Replace(math, " ", "", -1)
|
||||||
|
math = strings.ToLower(math)
|
||||||
|
if err := check(math); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return calc(math)
|
||||||
|
}
|
||||||
|
|
||||||
|
func check(math string) error {
|
||||||
|
math = strings.Replace(math, " ", "", -1)
|
||||||
|
math = strings.ToLower(math)
|
||||||
|
var bracketSum int
|
||||||
|
var signReady bool
|
||||||
|
for k, v := range math {
|
||||||
|
if string([]rune{v}) == "(" {
|
||||||
|
bracketSum++
|
||||||
|
}
|
||||||
|
if string([]rune{v}) == ")" {
|
||||||
|
bracketSum--
|
||||||
|
}
|
||||||
|
if bracketSum < 0 {
|
||||||
|
return fmt.Errorf("err at position %d.Reason is right bracket position not correct,except (", k)
|
||||||
|
}
|
||||||
|
if containSign(string([]rune{v})) {
|
||||||
|
if signReady {
|
||||||
|
if string([]rune{v}) != "+" && string([]rune{v}) != "-" {
|
||||||
|
return fmt.Errorf("err at position %d.Reason is sign %s not correct", k, string([]rune{v}))
|
||||||
|
}
|
||||||
|
signReady = false
|
||||||
|
} else {
|
||||||
|
signReady = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bracketSum != 0 {
|
||||||
|
return fmt.Errorf("Error:right bracket is not equal as left bracket")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calc(math string) (float64, error) {
|
||||||
|
var bracketLeft int
|
||||||
|
var bracketRight int
|
||||||
|
var DupStart int = -1
|
||||||
|
for pos, str := range math {
|
||||||
|
if string(str) == "(" {
|
||||||
|
bracketLeft = pos
|
||||||
|
}
|
||||||
|
if string(str) == ")" {
|
||||||
|
bracketRight = pos
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if bracketRight == 0 && bracketLeft != 0 || (bracketLeft > bracketRight) {
|
||||||
|
return 0, fmt.Errorf("Error:bracket not correct at %d ,except )", bracketLeft)
|
||||||
|
}
|
||||||
|
if bracketRight == 0 && bracketLeft == 0 {
|
||||||
|
return calcLong(math)
|
||||||
|
}
|
||||||
|
line := math[bracketLeft+1 : bracketRight]
|
||||||
|
num, err := calcLong(line)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
for i := bracketLeft - 1; i >= 0; i-- {
|
||||||
|
if !containSign(math[i : i+1]) {
|
||||||
|
DupStart = i
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if DupStart != -1 {
|
||||||
|
sign := math[DupStart:bracketLeft]
|
||||||
|
num, err := calcDuaFloat(sign, num)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
math = math[:DupStart] + fmt.Sprintf("%.15f", num) + math[bracketRight+1:]
|
||||||
|
DupStart = -1
|
||||||
|
} else {
|
||||||
|
math = math[:bracketLeft] + fmt.Sprintf("%.15f", num) + math[bracketRight+1:]
|
||||||
|
}
|
||||||
|
return calc(math)
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcLong(str string) (float64, error) {
|
||||||
|
var sigReady bool = false
|
||||||
|
var sigApply bool = false
|
||||||
|
var numPool []float64
|
||||||
|
var operPool []string
|
||||||
|
var numStr string
|
||||||
|
var oper string
|
||||||
|
if str[0:1] == "+" || str[0:1] == "-" {
|
||||||
|
sigReady = true
|
||||||
|
}
|
||||||
|
for _, stp := range str {
|
||||||
|
if sigReady && containSign(string(stp)) {
|
||||||
|
sigReady = false
|
||||||
|
sigApply = true
|
||||||
|
oper = string(stp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !containSign(string(stp)) {
|
||||||
|
sigReady = false
|
||||||
|
numStr = string(append([]rune(numStr), stp))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !sigReady {
|
||||||
|
sigReady = true
|
||||||
|
}
|
||||||
|
if sigApply {
|
||||||
|
num, err := calcDua(oper, numStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
sigApply = false
|
||||||
|
numPool = append(numPool, num)
|
||||||
|
} else {
|
||||||
|
num, err := parseNumbic(numStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
numPool = append(numPool, num)
|
||||||
|
}
|
||||||
|
numStr = ""
|
||||||
|
operPool = append(operPool, string(stp))
|
||||||
|
}
|
||||||
|
if sigApply {
|
||||||
|
num, err := calcDua(oper, numStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
numPool = append(numPool, num)
|
||||||
|
} else {
|
||||||
|
num, err := parseNumbic(numStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
numPool = append(numPool, num)
|
||||||
|
}
|
||||||
|
return calcPool(numPool, operPool)
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcPool(numPool []float64, operPool []string) (float64, error) {
|
||||||
|
if len(numPool) == 1 && len(operPool) == 0 {
|
||||||
|
return numPool[0], nil
|
||||||
|
}
|
||||||
|
if len(numPool) < len(operPool) {
|
||||||
|
return 0, errors.New(("Operate Signal Is too much"))
|
||||||
|
}
|
||||||
|
calcFunc := func(k int, v string) (float64, error) {
|
||||||
|
num, err := calcSigFloat(numPool[k], v, numPool[k+1])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
tmp := append(numPool[:k], num)
|
||||||
|
numPool = append(tmp, numPool[k+2:]...)
|
||||||
|
operPool = append(operPool[:k], operPool[k+1:]...)
|
||||||
|
return calcPool(numPool, operPool)
|
||||||
|
}
|
||||||
|
for k, v := range operPool {
|
||||||
|
if v == "^" {
|
||||||
|
return calcFunc(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range operPool {
|
||||||
|
if v == "*" || v == "/" {
|
||||||
|
return calcFunc(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range operPool {
|
||||||
|
return calcFunc(k, v)
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcSigFloat(floatA float64, b string, floatC float64) (float64, error) {
|
||||||
|
switch b {
|
||||||
|
case "+":
|
||||||
|
return floatA + floatC, nil
|
||||||
|
case "-":
|
||||||
|
return floatA - floatC, nil
|
||||||
|
case "*":
|
||||||
|
return floatA * floatC, nil
|
||||||
|
case "/":
|
||||||
|
if floatC == 0 {
|
||||||
|
return 0, errors.New("Divisor cannot be 0")
|
||||||
|
}
|
||||||
|
return floatA / floatC, nil
|
||||||
|
case "^":
|
||||||
|
return math.Pow(floatA, floatC), nil
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unexpect method:%s", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcSig(a, b, c string) (float64, error) {
|
||||||
|
floatA, err := parseNumbic(a)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
floatC, err := parseNumbic(c)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return calcSigFloat(floatA, b, floatC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func calcDuaFloat(a string, floatB float64) (float64, error) {
|
||||||
|
switch a {
|
||||||
|
case "sin":
|
||||||
|
return math.Sin(floatB), nil
|
||||||
|
case "cos":
|
||||||
|
return math.Cos(floatB), nil
|
||||||
|
case "tan":
|
||||||
|
return math.Tan(floatB), nil
|
||||||
|
case "abs":
|
||||||
|
return math.Abs(floatB), nil
|
||||||
|
case "arcsin":
|
||||||
|
return math.Asin(floatB), nil
|
||||||
|
case "arccos":
|
||||||
|
return math.Acos(floatB), nil
|
||||||
|
case "arctan":
|
||||||
|
return math.Atan(floatB), nil
|
||||||
|
case "sqrt":
|
||||||
|
return math.Sqrt(floatB), nil
|
||||||
|
case "loge":
|
||||||
|
return math.Log(floatB), nil
|
||||||
|
case "log10":
|
||||||
|
return math.Log10(floatB), nil
|
||||||
|
case "log2":
|
||||||
|
return math.Log2(floatB), nil
|
||||||
|
case "floor":
|
||||||
|
return math.Floor(floatB), nil
|
||||||
|
case "ceil":
|
||||||
|
return math.Ceil(floatB), nil
|
||||||
|
case "round":
|
||||||
|
return math.Round(floatB), nil
|
||||||
|
case "trunc":
|
||||||
|
return math.Trunc(floatB), nil
|
||||||
|
case "+":
|
||||||
|
return 0 + floatB, nil
|
||||||
|
case "-":
|
||||||
|
return 0 - floatB, nil
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("unexpect method:%s", a)
|
||||||
|
}
|
||||||
|
func calcDua(a, b string) (float64, error) {
|
||||||
|
floatB, err := parseNumbic(b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return calcDuaFloat(a, floatB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseNumbic(str string) (float64, error) {
|
||||||
|
switch str {
|
||||||
|
case "pi":
|
||||||
|
return float64(math.Pi), nil
|
||||||
|
case "e":
|
||||||
|
return float64(math.E), nil
|
||||||
|
default:
|
||||||
|
return strconv.ParseFloat(str, 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func containSign(str string) bool {
|
||||||
|
var sign []string = []string{"+", "-", "*", "/", "^"}
|
||||||
|
for _, v := range sign {
|
||||||
|
if str == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func contain(pool []string, str string) bool {
|
||||||
|
for _, v := range pool {
|
||||||
|
if v == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
//+build darwin
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
// Memory 系统内存信息
|
||||||
|
func Memory() MemStatus {
|
||||||
|
return MemStatus{}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//+build linux
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// Memory 系统内存信息
|
||||||
|
func Memory() MemStatus {
|
||||||
|
var mem MemStatus
|
||||||
|
ram := new(syscall.Sysinfo_t)
|
||||||
|
if err := syscall.Sysinfo(ram); err != nil {
|
||||||
|
return mem
|
||||||
|
}
|
||||||
|
mem.All = uint64(ram.Totalram)
|
||||||
|
mem.BuffCache = uint64(ram.Bufferram)
|
||||||
|
mem.Free = uint64(ram.Freeram)
|
||||||
|
mem.Shared = uint64(ram.Sharedram)
|
||||||
|
mem.Available = uint64(ram.Freeram + ram.Sharedram + ram.Bufferram)
|
||||||
|
mem.SwapAll = uint64(ram.Totalswap)
|
||||||
|
mem.SwapFree = uint64(ram.Freeswap)
|
||||||
|
mem.SwapUsed = uint64(mem.SwapAll - mem.SwapFree)
|
||||||
|
mem.Used = uint64(mem.All - mem.Free)
|
||||||
|
return mem
|
||||||
|
}
|
||||||
+85
@@ -0,0 +1,85 @@
|
|||||||
|
// +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")
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NetUsage() ([]NetAdapter, error) {
|
||||||
|
var res []NetAdapter
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetUsageByname(name string) (NetAdapter, error) {
|
||||||
|
return NetAdapter{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
|
||||||
|
var res []NetSpeed
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
|
||||||
|
|
||||||
|
return NetSpeed{}, nil
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// +build linux darwin
|
// +build !windows
|
||||||
|
|
||||||
package staros
|
package staros
|
||||||
|
|
||||||
@@ -29,25 +29,6 @@ func IsRoot() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory 系统内存信息
|
|
||||||
func Memory() MemStatus {
|
|
||||||
var mem MemStatus
|
|
||||||
ram := new(syscall.Sysinfo_t)
|
|
||||||
if err := syscall.Sysinfo(ram); err != nil {
|
|
||||||
return mem
|
|
||||||
}
|
|
||||||
mem.All = ram.Totalram
|
|
||||||
mem.BuffCache = ram.Bufferram
|
|
||||||
mem.Free = ram.Freeram
|
|
||||||
mem.Shared = ram.Sharedram
|
|
||||||
mem.Available = ram.Freeram + ram.Sharedram + ram.Bufferram
|
|
||||||
mem.SwapAll = ram.Totalswap
|
|
||||||
mem.SwapFree = ram.Freeswap
|
|
||||||
mem.SwapUsed = mem.SwapAll - mem.SwapFree
|
|
||||||
mem.Used = mem.All - mem.Free
|
|
||||||
return mem
|
|
||||||
}
|
|
||||||
|
|
||||||
func Whoami() (uid, gid int, uname, gname, home string, err error) {
|
func Whoami() (uid, gid int, uname, gname, home string, err error) {
|
||||||
var me *user.User
|
var me *user.User
|
||||||
var gup *user.Group
|
var gup *user.Group
|
||||||
@@ -105,8 +86,6 @@ func CpuUsage(sleep time.Duration) float64 {
|
|||||||
//fmt.Printf("CPU usage is %f%% [busy: %f, total: %f]\n", cpuUsage, totalTicks-idleTicks, totalTicks)
|
//fmt.Printf("CPU usage is %f%% [busy: %f, total: %f]\n", cpuUsage, totalTicks-idleTicks, totalTicks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func DiskUsage(path string) (disk DiskStatus) {
|
func DiskUsage(path string) (disk DiskStatus) {
|
||||||
fs := syscall.Statfs_t{}
|
fs := syscall.Statfs_t{}
|
||||||
err := syscall.Statfs(path, &fs)
|
err := syscall.Statfs(path, &fs)
|
||||||
@@ -71,3 +71,7 @@ func DiskUsage(path string) (disk DiskStatus) {
|
|||||||
disk.Available = uint64(lpFreeBytesAvailable)
|
disk.Available = uint64(lpFreeBytesAvailable)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CpuUsage(sleep time.Duration) float64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|||||||
+306
@@ -0,0 +1,306 @@
|
|||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//StarCmd Is Here
|
||||||
|
|
||||||
|
type StarCmd struct {
|
||||||
|
CMD *exec.Cmd
|
||||||
|
outfile io.ReadCloser
|
||||||
|
infile io.WriteCloser
|
||||||
|
errfile io.ReadCloser
|
||||||
|
running bool
|
||||||
|
runningChan chan int
|
||||||
|
//Store AlL of the Standed Outputs
|
||||||
|
stdout []byte
|
||||||
|
//Store All of the Standed Errors
|
||||||
|
errout []byte
|
||||||
|
runerr error
|
||||||
|
exitcode int
|
||||||
|
customCtx context.Context
|
||||||
|
stdoutBuf *bytes.Buffer
|
||||||
|
stderrBuf *bytes.Buffer
|
||||||
|
stdoutpoint int
|
||||||
|
stderrpoint int
|
||||||
|
prewrite []string
|
||||||
|
prewritetime time.Duration
|
||||||
|
stopctxfunc context.CancelFunc
|
||||||
|
stopctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func Command(command string, args ...string) (*StarCmd, error) {
|
||||||
|
var err error
|
||||||
|
shell := new(StarCmd)
|
||||||
|
shell.running = false
|
||||||
|
shell.prewritetime = time.Millisecond * 200
|
||||||
|
shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
shell.stderrBuf = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
shell.runningChan = make(chan int, 3)
|
||||||
|
shell.stopctx, shell.stopctxfunc = context.WithCancel(context.Background())
|
||||||
|
cmd := exec.Command(command, args...)
|
||||||
|
shell.CMD = cmd
|
||||||
|
shell.infile, err = shell.CMD.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.errfile, err = shell.CMD.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.outfile, err = shell.CMD.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.runerr = nil
|
||||||
|
shell.exitcode = -999
|
||||||
|
return shell, nil
|
||||||
|
}
|
||||||
|
func CommandContext(ctx context.Context, command string, args ...string) (*StarCmd, error) {
|
||||||
|
var err error
|
||||||
|
shell := new(StarCmd)
|
||||||
|
shell.running = false
|
||||||
|
shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
shell.stderrBuf = bytes.NewBuffer(make([]byte, 0))
|
||||||
|
shell.runningChan = make(chan int, 3)
|
||||||
|
shell.prewritetime = time.Millisecond * 200
|
||||||
|
shell.stopctx, shell.stopctxfunc = context.WithCancel(context.Background())
|
||||||
|
cmd := exec.CommandContext(ctx, command, args...)
|
||||||
|
shell.CMD = cmd
|
||||||
|
shell.infile, err = shell.CMD.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.errfile, err = shell.CMD.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.outfile, err = shell.CMD.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return shell, err
|
||||||
|
}
|
||||||
|
shell.runerr = nil
|
||||||
|
shell.exitcode = -999
|
||||||
|
return shell, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
||||||
|
for starcli.running && starcli.CMD != nil {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
out := make([]byte, 65535)
|
||||||
|
n, err := starcli.outfile.Read(out)
|
||||||
|
if n != 0 {
|
||||||
|
starcli.stdoutBuf.Write(out[:n])
|
||||||
|
for _, v := range out[:n] {
|
||||||
|
starcli.stdout = append(starcli.stdout, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
starcli.runerr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
||||||
|
for starcli.running && starcli.CMD != nil {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
out := make([]byte, 65535)
|
||||||
|
n, err := starcli.errfile.Read(out)
|
||||||
|
if n != 0 {
|
||||||
|
starcli.stderrBuf.Write(out[:n])
|
||||||
|
for _, v := range out[:n] {
|
||||||
|
starcli.errout = append(starcli.errout, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
starcli.runerr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (starcli *StarCmd) NowLineOutput() (string, error) {
|
||||||
|
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
||||||
|
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
||||||
|
if len(buferr) != 0 {
|
||||||
|
return string(buf), errors.New(string(buferr))
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) NowLineStdOut() string {
|
||||||
|
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) NowLineStdErr() error {
|
||||||
|
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
|
||||||
|
if len(buferr) != 0 {
|
||||||
|
return errors.New(string(buferr))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) NowAllOutput() (string, error) {
|
||||||
|
var outstr string
|
||||||
|
buf := make([]byte, starcli.stdoutBuf.Len())
|
||||||
|
n, _ := starcli.stdoutBuf.Read(buf)
|
||||||
|
if n != 0 {
|
||||||
|
outstr = string(buf[:n])
|
||||||
|
}
|
||||||
|
if starcli.runerr != nil {
|
||||||
|
return outstr, starcli.runerr
|
||||||
|
}
|
||||||
|
buf = make([]byte, starcli.stderrBuf.Len())
|
||||||
|
n, _ = starcli.stderrBuf.Read(buf)
|
||||||
|
if n != 0 {
|
||||||
|
return outstr, errors.New(string(buf[:n]))
|
||||||
|
}
|
||||||
|
return outstr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) NowStdOut() string {
|
||||||
|
var outstr string
|
||||||
|
buf := make([]byte, starcli.stdoutBuf.Len())
|
||||||
|
n, _ := starcli.stdoutBuf.Read(buf)
|
||||||
|
if n != 0 {
|
||||||
|
outstr = string(buf[:n])
|
||||||
|
}
|
||||||
|
return outstr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) NowStdErr() error {
|
||||||
|
|
||||||
|
buf := make([]byte, starcli.stderrBuf.Len())
|
||||||
|
n, _ := starcli.stderrBuf.Read(buf)
|
||||||
|
if n != 0 {
|
||||||
|
return errors.New(string(buf[:n]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) AllOutPut() (string, error) {
|
||||||
|
err := starcli.runerr
|
||||||
|
if err == nil && len(starcli.errout) != 0 {
|
||||||
|
err = errors.New(string(starcli.errout))
|
||||||
|
}
|
||||||
|
return string(starcli.stdout), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) AllStdOut() string {
|
||||||
|
return string(starcli.stdout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) AllStdErr() error {
|
||||||
|
err := starcli.runerr
|
||||||
|
if err == nil && len(starcli.errout) != 0 {
|
||||||
|
err = errors.New(string(starcli.errout))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Start() error {
|
||||||
|
if err := starcli.CMD.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
starcli.running = true
|
||||||
|
go func() {
|
||||||
|
err := starcli.CMD.Wait()
|
||||||
|
if err != nil {
|
||||||
|
starcli.runerr = err
|
||||||
|
}
|
||||||
|
starcli.stopctxfunc()
|
||||||
|
starcli.running = false
|
||||||
|
starcli.exitcode = starcli.CMD.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
|
||||||
|
starcli.runningChan <- 1
|
||||||
|
}()
|
||||||
|
go starcli.queryStdout(starcli.stopctx)
|
||||||
|
go starcli.queryStderr(starcli.stopctx)
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
if len(starcli.prewrite) != 0 {
|
||||||
|
for _, v := range starcli.prewrite {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
starcli.WriteCmd(v)
|
||||||
|
time.Sleep(starcli.prewritetime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(starcli.stopctx)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) IsRunning() bool {
|
||||||
|
return starcli.running
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Stoped() <-chan int {
|
||||||
|
return starcli.runningChan
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Exec(cmd string, wait int) (string, error) {
|
||||||
|
starcli.infile.Write([]byte(cmd + "\n"))
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(wait))
|
||||||
|
return starcli.NowAllOutput()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) WriteCmd(cmdstr string) {
|
||||||
|
starcli.infile.Write([]byte(cmdstr + "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) PreWrite(cmd ...string) {
|
||||||
|
for _, v := range cmd {
|
||||||
|
starcli.prewrite = append(starcli.prewrite, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) PreWriteInterval(dt time.Duration) {
|
||||||
|
starcli.prewritetime = dt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) ExitCode() int {
|
||||||
|
return starcli.exitcode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Kill() {
|
||||||
|
starcli.CMD.Process.Kill()
|
||||||
|
starcli.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) GetPid() int {
|
||||||
|
return starcli.CMD.Process.Pid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Signal(sig os.Signal) error {
|
||||||
|
return starcli.CMD.Process.Signal(sig)
|
||||||
|
}
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
// +build linux darwin
|
|
||||||
|
|
||||||
package staros
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// FindProcessByName 通过进程名来查询应用信息
|
|
||||||
func FindProcessByName(pname string) (datas []Process, err error) {
|
|
||||||
var name, main string
|
|
||||||
var mainb []byte
|
|
||||||
paths, errs := ioutil.ReadDir("/proc")
|
|
||||||
if errs != nil {
|
|
||||||
err = errs
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, v := range paths {
|
|
||||||
if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") {
|
|
||||||
name, err = readAsString("/proc/" + v.Name() + "/comm")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(name) == pname {
|
|
||||||
var tmp Process
|
|
||||||
main, err = readAsString("/proc/" + v.Name() + "/status")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data := splitBy(main, ":")
|
|
||||||
tmp.Name = pname
|
|
||||||
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])
|
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/cmdline")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
args := bytes.Split(mainb, []byte{0})
|
|
||||||
for _, v := range args {
|
|
||||||
tmp.Args = append(tmp.Args, string(v))
|
|
||||||
}
|
|
||||||
tmp.LocalPath, err = os.Readlink("/proc/" + v.Name() + "/exe")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tmp.LocalPath = filepath.Dir(tmp.LocalPath)
|
|
||||||
tmp.ExecPath, err = os.Readlink("/proc/" + v.Name() + "/cwd")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
main, err = readAsString("/proc/" + v.Name() + "/stat")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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))
|
|
||||||
datas = append(datas, tmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindProcessByPid 通过Pid来查询应用信息
|
|
||||||
func FindProcessByPid(pid int64) (datas Process, err error) {
|
|
||||||
var name, main string
|
|
||||||
var mainb []byte
|
|
||||||
if !Exists("/proc/" + fmt.Sprint(pid) + "/comm") {
|
|
||||||
err = errors.New("Not Found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/status")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data := splitBy(main, ":")
|
|
||||||
datas.Name = strings.TrimSpace(name)
|
|
||||||
datas.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
|
|
||||||
datas.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
|
|
||||||
datas.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
|
|
||||||
uids := splitBySpace(data["Uid"])
|
|
||||||
gids := splitBySpace(data["Gid"])
|
|
||||||
datas.RUID, _ = strconv.Atoi(uids[0])
|
|
||||||
datas.EUID, _ = strconv.Atoi(uids[1])
|
|
||||||
datas.RGID, _ = strconv.Atoi(gids[0])
|
|
||||||
datas.EGID, _ = strconv.Atoi(gids[1])
|
|
||||||
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/cmdline")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
args := bytes.Split(mainb, []byte{0})
|
|
||||||
for _, v := range args {
|
|
||||||
datas.Args = append(datas.Args, string(v))
|
|
||||||
}
|
|
||||||
datas.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
datas.LocalPath = filepath.Dir(datas.LocalPath)
|
|
||||||
datas.ExecPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/cwd")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/stat")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
times := splitBySpace(main)
|
|
||||||
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
|
|
||||||
datas.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Daemon(path string, args ...string) (int, error) {
|
|
||||||
cmd := exec.Command(path, args...)
|
|
||||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
|
||||||
Setsid: true,
|
|
||||||
}
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
pid := cmd.Process.Pid
|
|
||||||
err := cmd.Process.Release()
|
|
||||||
return pid, err
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,27 @@
|
|||||||
package staros
|
package staros
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_Process(t *testing.T) {
|
func Test_Process(t *testing.T) {
|
||||||
fmt.Println(FindProcessByPid(16652))
|
fmt.Println(FindProcessByPid(16652))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_StarCmd(t *testing.T) {
|
||||||
|
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
|
||||||
|
cmd, _ := CommandContext(ctx, "cmd.exe", "/c", "ping -t 127.0.0.1")
|
||||||
|
cmd.Start()
|
||||||
|
for cmd.IsRunning() {
|
||||||
|
fmt.Print(cmd.NowLineOutput())
|
||||||
|
time.Sleep(time.Millisecond * 50)
|
||||||
|
}
|
||||||
|
fmt.Println(cmd.NowAllOutput())
|
||||||
|
fmt.Print("all is ")
|
||||||
|
fmt.Println(cmd.AllOutPut())
|
||||||
|
fmt.Println(cmd.ExitCode())
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
+232
@@ -0,0 +1,232 @@
|
|||||||
|
// +build linux darwin
|
||||||
|
|
||||||
|
package staros
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//FindProcessByName 通过进程名来查询应用信息
|
||||||
|
func FindProcessByName(name string) (datas []Process, err error) {
|
||||||
|
return FindProcess(func(in Process) bool {
|
||||||
|
if name == in.Name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindProcess 通过进程信息来查询应用信息
|
||||||
|
func FindProcess(compare func(Process) bool) (datas []Process, err error) {
|
||||||
|
var name, main string
|
||||||
|
var mainb []byte
|
||||||
|
paths, errs := ioutil.ReadDir("/proc")
|
||||||
|
if errs != nil {
|
||||||
|
err = errs
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range paths {
|
||||||
|
if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") {
|
||||||
|
name, err = readAsString("/proc/" + v.Name() + "/comm")
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var tmp Process
|
||||||
|
tmp.LocalPath, err = os.Readlink("/proc/" + v.Name() + "/exe")
|
||||||
|
tmp.Path = tmp.LocalPath
|
||||||
|
tmp.LocalPath = filepath.Dir(tmp.LocalPath)
|
||||||
|
tmp.ExecPath, err = os.Readlink("/proc/" + v.Name() + "/cwd")
|
||||||
|
tmp.Name = strings.TrimSpace(name)
|
||||||
|
main, err = readAsString("/proc/" + v.Name() + "/status")
|
||||||
|
if err != nil {
|
||||||
|
if compare(tmp) {
|
||||||
|
datas = append(datas, tmp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
if err != nil {
|
||||||
|
if compare(tmp) {
|
||||||
|
datas = append(datas, tmp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
if err != nil {
|
||||||
|
if compare(tmp) {
|
||||||
|
datas = append(datas, tmp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = bytes.Split(mainb, []byte{0})
|
||||||
|
for _, v := range args {
|
||||||
|
tmp.Env = append(tmp.Env, string(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
main, err = readAsString("/proc/" + v.Name() + "/stat")
|
||||||
|
if err != nil {
|
||||||
|
if compare(tmp) {
|
||||||
|
datas = append(datas, tmp)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
datas = append(datas, tmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindProcessByPid 通过Pid来查询应用信息
|
||||||
|
func FindProcessByPid(pid int64) (datas Process, err error) {
|
||||||
|
var name, main string
|
||||||
|
var mainb []byte
|
||||||
|
if !Exists("/proc/" + fmt.Sprint(pid) + "/comm") {
|
||||||
|
err = errors.New("Not Found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/status")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := splitBy(main, ":")
|
||||||
|
datas.Name = strings.TrimSpace(name)
|
||||||
|
datas.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
|
||||||
|
datas.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
|
||||||
|
datas.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
|
||||||
|
uids := splitBySpace(data["Uid"])
|
||||||
|
gids := splitBySpace(data["Gid"])
|
||||||
|
datas.RUID, _ = strconv.Atoi(uids[0])
|
||||||
|
datas.EUID, _ = strconv.Atoi(uids[1])
|
||||||
|
datas.RGID, _ = strconv.Atoi(gids[0])
|
||||||
|
datas.EGID, _ = strconv.Atoi(gids[1])
|
||||||
|
datas.VmPeak, _ = strconv.ParseInt(splitBySpace(data["VmPeak"])[0], 10, 64)
|
||||||
|
datas.VmSize, _ = strconv.ParseInt(splitBySpace(data["VmSize"])[0], 10, 64)
|
||||||
|
datas.VmHWM, _ = strconv.ParseInt(splitBySpace(data["VmHWM"])[0], 10, 64)
|
||||||
|
datas.VmRSS, _ = strconv.ParseInt(splitBySpace(data["VmRSS"])[0], 10, 64)
|
||||||
|
datas.VmLck, _ = strconv.ParseInt(splitBySpace(data["VmLck"])[0], 10, 64)
|
||||||
|
datas.VmData, _ = strconv.ParseInt(splitBySpace(data["VmData"])[0], 10, 64)
|
||||||
|
datas.VmLck *= 1024
|
||||||
|
datas.VmData *= 1024
|
||||||
|
datas.VmPeak *= 1024
|
||||||
|
datas.VmSize *= 1024
|
||||||
|
datas.VmHWM *= 1024
|
||||||
|
datas.VmRSS *= 1024
|
||||||
|
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/cmdline")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
args := bytes.Split(mainb, []byte{0})
|
||||||
|
for _, v := range args {
|
||||||
|
datas.Args = append(datas.Args, string(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/environ")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
args = bytes.Split(mainb, []byte{0})
|
||||||
|
for _, v := range args {
|
||||||
|
datas.Env = append(datas.Env, string(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
datas.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe")
|
||||||
|
datas.Path = datas.LocalPath
|
||||||
|
datas.LocalPath = filepath.Dir(datas.LocalPath)
|
||||||
|
datas.ExecPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/cwd")
|
||||||
|
main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/stat")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
times := splitBySpace(main)
|
||||||
|
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
|
||||||
|
datas.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Daemon(path string, args ...string) (int, error) {
|
||||||
|
cmd := exec.Command(path, args...)
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Setsid: true,
|
||||||
|
}
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
pid := cmd.Process.Pid
|
||||||
|
err := cmd.Process.Release()
|
||||||
|
return pid, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
|
||||||
|
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Credential: &syscall.Credential{
|
||||||
|
Uid: uid,
|
||||||
|
Gid: gid,
|
||||||
|
},
|
||||||
|
Setsid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) Release() error {
|
||||||
|
if err := starcli.CMD.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
|
||||||
|
Setsid: true,
|
||||||
|
}
|
||||||
|
starcli.CMD.Process.Release()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) SetKeepCaps() error {
|
||||||
|
_, _, err := syscall.RawSyscall(157 /*SYS PRCTL */, 0x8 /*PR SET KEEPCAPS*/, 1, 0)
|
||||||
|
if 0 != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -58,3 +58,7 @@ func Daemon(path string, args ...string) (int, error) {
|
|||||||
cmd.Process.Release()
|
cmd.Process.Release()
|
||||||
return pid, nil
|
return pid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,26 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KB = 1024
|
||||||
|
MB = KB << 10
|
||||||
|
GB = MB << 10
|
||||||
|
TB = GB << 10
|
||||||
|
PB = TB << 10
|
||||||
|
)
|
||||||
|
|
||||||
|
type NetAdapter struct {
|
||||||
|
Name string
|
||||||
|
RecvBytes uint64
|
||||||
|
SendBytes uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetSpeed struct {
|
||||||
|
Name string
|
||||||
|
RecvBytes float64
|
||||||
|
SendBytes float64
|
||||||
|
}
|
||||||
|
|
||||||
// Process 定义一个进程的信息
|
// Process 定义一个进程的信息
|
||||||
type Process struct {
|
type Process struct {
|
||||||
PPid int64
|
PPid int64
|
||||||
@@ -11,13 +31,21 @@ type Process struct {
|
|||||||
Name string
|
Name string
|
||||||
ExecPath string
|
ExecPath string
|
||||||
LocalPath string
|
LocalPath string
|
||||||
|
Path string
|
||||||
Args []string
|
Args []string
|
||||||
|
Env []string
|
||||||
RUID int
|
RUID int
|
||||||
EUID int
|
EUID int
|
||||||
RGID int
|
RGID int
|
||||||
EGID int
|
EGID int
|
||||||
TPid int64
|
TPid int64
|
||||||
Uptime time.Time
|
Uptime time.Time
|
||||||
|
VmPeak int64
|
||||||
|
VmSize int64
|
||||||
|
VmLck int64
|
||||||
|
VmHWM int64
|
||||||
|
VmRSS int64
|
||||||
|
VmData int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemStatus struct {
|
type MemStatus struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user