new feature add

master
兔子 5 years ago
parent 4a026c0935
commit a94fc8d19d

@ -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
@ -105,8 +105,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
}

@ -0,0 +1,305 @@
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)
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)
}

@ -60,6 +60,7 @@ func FindProcessByName(pname string) (datas []Process, err error) {
if err != nil { if err != nil {
return return
} }
tmp.Path = tmp.LocalPath
tmp.LocalPath = filepath.Dir(tmp.LocalPath) tmp.LocalPath = filepath.Dir(tmp.LocalPath)
tmp.ExecPath, err = os.Readlink("/proc/" + v.Name() + "/cwd") tmp.ExecPath, err = os.Readlink("/proc/" + v.Name() + "/cwd")
if err != nil { if err != nil {
@ -118,6 +119,7 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
if err != nil { if err != nil {
return return
} }
datas.Path = datas.LocalPath
datas.LocalPath = filepath.Dir(datas.LocalPath) datas.LocalPath = filepath.Dir(datas.LocalPath)
datas.ExecPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/cwd") datas.ExecPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/cwd")
if err != nil { if err != nil {
@ -145,3 +147,32 @@ func Daemon(path string, args ...string) (int, error) {
err := cmd.Process.Release() err := cmd.Process.Release()
return pid, err 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
}

@ -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())
}

@ -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,6 +31,7 @@ type Process struct {
Name string Name string
ExecPath string ExecPath string
LocalPath string LocalPath string
Path string
Args []string Args []string
RUID int RUID int
EUID int EUID int

Loading…
Cancel
Save