8 Commits

Author SHA1 Message Date
b612 c3a165e64a bug fix:struct error while get file creation date 2020-12-22 09:27:55 +08:00
b612 ad5c18667a add mathmatic calc 2020-12-21 17:19:41 +08:00
b612 cdf3a18981 bug fix 2020-11-27 11:20:23 +08:00
b612 6de9af62cc fix bug while use common user 2020-11-26 16:14:12 +08:00
b612 bca0d42559 fix bug while use common user 2020-11-26 15:54:46 +08:00
b612 26da8c8b88 fix bug that darwin cannot compile due to syscall_t error 2020-08-21 11:17:48 +08:00
b612 5c2cce2da2 cli bug fix 2020-07-27 14:19:05 +08:00
b612 a94fc8d19d new feature add 2020-07-17 09:56:23 +08:00
15 changed files with 1069 additions and 169 deletions
+21
View File
@@ -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)
}
+19
View File
@@ -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())
}
+294
View File
@@ -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
}
+8
View File
@@ -0,0 +1,8 @@
//+build darwin
package staros
// Memory 系统内存信息
func Memory() MemStatus {
return MemStatus{}
}
+24
View File
@@ -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
View File
@@ -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")
}
+26
View File
@@ -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 -22
View File
@@ -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)
+4
View File
@@ -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
View File
@@ -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)
}
-147
View File
@@ -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
}
+17
View File
@@ -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
View File
@@ -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
}
+4
View File
@@ -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) {
}
+28
View File
@@ -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 {