new feature add

master
兔子 3 years ago
parent 3501166592
commit cf453821ef

@ -1,6 +1,18 @@
package staros package staros
import "os" import (
"errors"
"os"
)
var ERR_ALREADY_LOCKED = errors.New("ALREADY LOCKED")
var ERR_TIMEOUT = errors.New("TIME OUT")
func NewFileLock(filepath string) FileLock {
return FileLock{
filepath: filepath,
}
}
// 检测文件/文件夹是否存在 // 检测文件/文件夹是否存在
func Exists(path string) bool { func Exists(path string) bool {

@ -0,0 +1,22 @@
package staros
import (
"fmt"
"os"
"testing"
"time"
)
func Test_FileLock(t *testing.T) {
filename := "./test.file"
lock := NewFileLock(filename)
lock2 := NewFileLock(filename)
fmt.Println("lock1", lock.LockNoBlocking())
time.Sleep(time.Second)
fmt.Println("lock2", lock2.LockWithTimeout(time.Second*5))
fmt.Println("unlock1", lock.Unlock())
time.Sleep(time.Second)
fmt.Println("lock2", lock2.LockNoBlocking())
fmt.Println("unlock2", lock2.Unlock())
os.Remove(filename)
}

@ -3,11 +3,17 @@
package staros package staros
import ( import (
"b612.me/stario"
"os" "os"
"syscall" "syscall"
"time" "time"
) )
type FileLock struct {
fd int
filepath string
}
func timespecToTime(ts syscall.Timespec) time.Time { func timespecToTime(ts syscall.Timespec) time.Time {
return time.Unix(int64(ts.Sec), int64(ts.Nsec)) return time.Unix(int64(ts.Sec), int64(ts.Nsec))
} }
@ -19,3 +25,55 @@ 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)
} }
func (f *FileLock) openFileForLock() error {
fd, err := syscall.Open(f.filepath, syscall.O_CREAT|syscall.O_RDONLY, 0600)
if err != nil {
return err
}
f.filepath = f.filepath
f.fd = fd
return nil
}
func (f *FileLock) Lock() error {
if err := f.openFileForLock(); err != nil {
return err
}
return syscall.Flock(f.fd, syscall.LOCK_EX)
}
func (f *FileLock) LockNoBlocking() error {
if err := f.openFileForLock(); err != nil {
return err
}
err := syscall.Flock(f.fd, syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil {
syscall.Close(f.fd)
if err == syscall.EWOULDBLOCK {
return ERR_ALREADY_LOCKED
}
}
return err
}
func (f *FileLock) Unlock() error {
err := syscall.Flock(f.fd, syscall.LOCK_UN)
if err != nil {
return err
}
return syscall.Close(f.fd)
}
func (f *FileLock) LockWithTimeout(tm time.Duration) error {
return stario.StopUntilTimeout(tm, func(tmout chan struct{}) error {
err := f.Lock()
select {
case <-tmout:
f.Unlock()
return nil
default:
}
return err
})
}

@ -3,11 +3,17 @@
package staros package staros
import ( import (
"b612.me/win32api"
"os" "os"
"syscall" "syscall"
"time" "time"
) )
type FileLock struct {
filepath string
handle win32api.HANDLE
}
func GetFileCreationTime(fileinfo os.FileInfo) time.Time { func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
d := fileinfo.Sys().(*syscall.Win32FileAttributeData) d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
return time.Unix(0, d.CreationTime.Nanoseconds()) return time.Unix(0, d.CreationTime.Nanoseconds())
@ -18,10 +24,82 @@ func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
return time.Unix(0, d.LastAccessTime.Nanoseconds()) return time.Unix(0, d.LastAccessTime.Nanoseconds())
} }
func SetFileTimes(file *os.File,info os.FileInfo) { func SetFileTimes(file *os.File, info os.FileInfo) {
} }
func SetFileTimesbyTime(file *os.File) { func SetFileTimesbyTime(file *os.File) {
} }
func (f *FileLock) openFileForLock() error {
name, err := syscall.UTF16PtrFromString(f.filepath)
if err != nil {
return err
}
handle, err := syscall.CreateFile(
name,
syscall.GENERIC_READ,
syscall.FILE_SHARE_READ,
nil,
syscall.OPEN_ALWAYS,
syscall.FILE_FLAG_OVERLAPPED|0x00000080,
0)
if err != nil {
return err
}
f.handle = win32api.HANDLE(handle)
return nil
}
func (f *FileLock) lockForTimeout(timeout time.Duration, lockType win32api.DWORD) error {
var err error
if err = f.openFileForLock(); err != nil {
return err
}
event, err := win32api.CreateEventW(nil, true, false, nil)
if err != nil {
return err
}
myEvent := &syscall.Overlapped{HEvent: syscall.Handle(event)}
defer syscall.CloseHandle(myEvent.HEvent)
_, err = win32api.LockFileEx(f.handle, lockType, 0, 1, 0, myEvent)
if err == nil {
return nil
}
if err != syscall.ERROR_IO_PENDING {
return err
}
millis := uint32(syscall.INFINITE)
if timeout >= 0 {
millis = uint32(timeout.Nanoseconds() / 1000000)
}
s, err := syscall.WaitForSingleObject(myEvent.HEvent, millis)
switch s {
case syscall.WAIT_OBJECT_0:
// success!
return nil
case syscall.WAIT_TIMEOUT:
f.Unlock()
return ERR_TIMEOUT
default:
f.Unlock()
return err
}
}
func (f *FileLock) Lock() error {
return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK)
}
func (f *FileLock) LockWithTimeout(tm time.Duration) error {
return f.lockForTimeout(tm, win32api.LOCKFILE_EXCLUSIVE_LOCK)
}
func (f *FileLock) LockNoBlocking() error {
return f.lockForTimeout(0, win32api.LOCKFILE_EXCLUSIVE_LOCK|win32api.LOCKFILE_FAIL_IMMEDIATELY)
}
func (f *FileLock) Unlock() error {
return syscall.Close(syscall.Handle(f.handle))
}

@ -87,16 +87,28 @@ func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections // 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 // 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) { func NetConnections(analysePid bool,types string) ([]NetConn, error) {
var result []NetConn var result []NetConn
var inodeMap map[string]int64 var inodeMap map[string]int64
var err error var err error
fileList := []string{ var fileList []string
"/proc/net/tcp", if types=="" || strings.Contains(strings.ToLower(types),"all") {
"/proc/net/tcp6", fileList = []string{
"/proc/net/udp", "/proc/net/tcp",
"/proc/net/udp6", "/proc/net/tcp6",
"/proc/net/unix", "/proc/net/udp",
"/proc/net/udp6",
"/proc/net/unix",
}
}
if strings.Contains(strings.ToLower(types),"tcp") {
fileList =append(fileList,"/proc/net/tcp","/proc/net/tcp6")
}
if strings.Contains(strings.ToLower(types),"udp") {
fileList =append(fileList,"/proc/net/udp","/proc/net/udp6")
}
if strings.Contains(strings.ToLower(types),"unix") {
fileList =append(fileList,"/proc/net/unix")
} }
if analysePid { if analysePid {
inodeMap, err = GetInodeMap() inodeMap, err = GetInodeMap()
@ -135,6 +147,9 @@ func GetInodeMap() (map[string]int64, error) {
if err != nil { if err != nil {
continue continue
} }
if !strings.Contains(socket, "socket") {
continue
}
start := strings.Index(socket, "[") start := strings.Index(socket, "[")
if start < 0 { if start < 0 {
continue continue
@ -147,7 +162,7 @@ func GetInodeMap() (map[string]int64, error) {
} }
} }
} }
return nil, err return res, err
} }
func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) { func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
@ -177,6 +192,60 @@ func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]Ne
} }
res.RemoteAddr = ip res.RemoteAddr = ip
res.RemotePort = port res.RemotePort = port
//connection state
if strings.Contains(typed, "tcp") {
state, err := strconv.ParseInt(strings.TrimSpace(v[3]), 16, 64)
if err != nil {
return result, err
}
res.Status = TCP_STATE[state]
}
txrx_queue := strings.Split(strings.TrimSpace(v[4]), ":")
if len(txrx_queue) != 2 {
return result, errors.New("not a valid net file")
}
tx_queue, err := strconv.ParseInt(txrx_queue[0], 16, 64)
if err != nil {
return result, err
}
res.TX_Queue = tx_queue
rx_queue, err := strconv.ParseInt(txrx_queue[1], 16, 64)
if err != nil {
return result, err
}
res.RX_Queue = rx_queue
timer := strings.Split(strings.TrimSpace(v[5]), ":")
if len(timer) != 2 {
return result, errors.New("not a valid net file")
}
switch timer[0] {
case "00":
res.TimerActive = "NO_TIMER"
case "01":
//重传定时器
res.TimerActive = "RETRANSMIT"
case "02":
//连接定时器、FIN_WAIT_2定时器或TCP保活定时器
res.TimerActive = "KEEPALIVE"
case "03":
//TIME_WAIT定时器
res.TimerActive = "TIME_WAIT"
case "04":
//持续定时器
res.TimerActive = "ZERO_WINDOW_PROBE"
default:
res.TimerActive = "UNKNOWN"
}
timerJif, err := strconv.ParseInt(timer[1], 16, 64)
if err != nil {
return result, err
}
res.TimerJiffies = timerJif
timerCnt, err := strconv.ParseInt(strings.TrimSpace(v[6]), 16, 64)
if err != nil {
return result, err
}
res.RtoTimer = timerCnt
res.Uid, err = strconv.ParseInt(v[7], 10, 64) res.Uid, err = strconv.ParseInt(v[7], 10, 64)
if err != nil { if err != nil {
return result, err return result, err
@ -229,7 +298,7 @@ func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]N
res.Pid = -1 res.Pid = -1
} else { } else {
_, ok := pidMap[res.Pid] _, ok := pidMap[res.Pid]
if !ok { if !ok || pidMap[res.Pid] == nil {
tmp, err := FindProcessByPid(res.Pid) tmp, err := FindProcessByPid(res.Pid)
if err != nil { if err != nil {
pidMap[res.Pid] = nil pidMap[res.Pid] = nil
@ -237,8 +306,10 @@ func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]N
pidMap[res.Pid] = &tmp pidMap[res.Pid] = &tmp
} }
} }
res.Uid = int64(pidMap[res.Pid].RUID) if pidMap[res.Pid] != nil {
res.Process = pidMap[res.Pid] res.Uid = int64(pidMap[res.Pid].RUID)
res.Process = pidMap[res.Pid]
}
} }
} }
res.Typed = typed res.Typed = typed

@ -3,6 +3,7 @@
package staros package staros
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os/user" "os/user"
@ -12,6 +13,8 @@ import (
"time" "time"
) )
var clockTicks = 100 // default value
// StartTime 开机时间 // StartTime 开机时间
func StartTime() time.Time { func StartTime() time.Time {
tmp, _ := readAsString("/proc/stat") tmp, _ := readAsString("/proc/stat")
@ -63,9 +66,9 @@ func getCPUSample() (idle, total uint64) {
if err != nil { if err != nil {
fmt.Println("Error: ", i, fields[i], err) fmt.Println("Error: ", i, fields[i], err)
} }
total += val // tally up all the numbers to get total ticks total += val // tally up all the numbers to get total ticks
if i == 4 { // idle is the 5th field in the cpu line if i == 4 || i == 5 { // idle is the 5th field in the cpu line
idle = val idle += val
} }
} }
return return
@ -73,6 +76,55 @@ func getCPUSample() (idle, total uint64) {
} }
return return
} }
func splitProcStat(content []byte) []string {
nameStart := bytes.IndexByte(content, '(')
nameEnd := bytes.LastIndexByte(content, ')')
restFields := strings.Fields(string(content[nameEnd+2:])) // +2 skip ') '
name := content[nameStart+1 : nameEnd]
pid := strings.TrimSpace(string(content[:nameStart]))
fields := make([]string, 3, len(restFields)+3)
fields[1] = string(pid)
fields[2] = string(name)
fields = append(fields, restFields...)
return fields
}
func getCPUSampleByPid(pid int) float64 {
contents, err := ioutil.ReadFile("/proc/" + strconv.Itoa(pid) + "/stat")
if err != nil {
return 0
}
fields := splitProcStat(contents)
utime, err := strconv.ParseFloat(fields[14], 64)
if err != nil {
return 0
}
stime, err := strconv.ParseFloat(fields[15], 64)
if err != nil {
return 0
}
// There is no such thing as iotime in stat file. As an approximation, we
// will use delayacct_blkio_ticks (aggregated block I/O delays, as per Linux
// docs). Note: I am assuming at least Linux 2.6.18
var iotime float64
if len(fields) > 42 {
iotime, err = strconv.ParseFloat(fields[42], 64)
if err != nil {
iotime = 0 // Ancient linux version, most likely
}
} else {
iotime = 0 // e.g. SmartOS containers
}
return utime/float64(clockTicks) + stime/float64(clockTicks) + iotime/float64(clockTicks)
}
func CpuUsageByPid(pid int, sleep time.Duration) float64 {
total1 := getCPUSampleByPid(pid)
time.Sleep(sleep)
total2 := getCPUSampleByPid(pid)
return (total2 - total1) / sleep.Seconds() * 100
}
// CpuUsage 获取CPU使用量 // CpuUsage 获取CPU使用量
func CpuUsage(sleep time.Duration) float64 { func CpuUsage(sleep time.Duration) float64 {

@ -9,6 +9,7 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
) )
@ -16,12 +17,11 @@ import (
//StarCmd Is Here //StarCmd Is Here
type StarCmd struct { type StarCmd struct {
CMD *exec.Cmd CMD *exec.Cmd
outfile io.ReadCloser outfile io.ReadCloser
infile io.WriteCloser infile io.WriteCloser
errfile io.ReadCloser errfile io.ReadCloser
running bool running int32
runningChan chan int
//Store AlL of the Standed Outputs //Store AlL of the Standed Outputs
stdout []byte stdout []byte
//Store All of the Standed Errors //Store All of the Standed Errors
@ -42,11 +42,10 @@ type StarCmd struct {
func Command(command string, args ...string) (*StarCmd, error) { func Command(command string, args ...string) (*StarCmd, error) {
var err error var err error
shell := new(StarCmd) shell := new(StarCmd)
shell.running = false shell.running = 0
shell.prewritetime = time.Millisecond * 200 shell.prewritetime = time.Millisecond * 200
shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0)) shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0))
shell.stderrBuf = 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()) shell.stopctx, shell.stopctxfunc = context.WithCancel(context.Background())
cmd := exec.Command(command, args...) cmd := exec.Command(command, args...)
shell.CMD = cmd shell.CMD = cmd
@ -69,10 +68,9 @@ func Command(command string, args ...string) (*StarCmd, error) {
func CommandContext(ctx context.Context, command string, args ...string) (*StarCmd, error) { func CommandContext(ctx context.Context, command string, args ...string) (*StarCmd, error) {
var err error var err error
shell := new(StarCmd) shell := new(StarCmd)
shell.running = false shell.running = 0
shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0)) shell.stdoutBuf = bytes.NewBuffer(make([]byte, 0))
shell.stderrBuf = bytes.NewBuffer(make([]byte, 0)) shell.stderrBuf = bytes.NewBuffer(make([]byte, 0))
shell.runningChan = make(chan int, 3)
shell.prewritetime = time.Millisecond * 200 shell.prewritetime = time.Millisecond * 200
shell.stopctx, shell.stopctxfunc = context.WithCancel(context.Background()) shell.stopctx, shell.stopctxfunc = context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, command, args...) cmd := exec.CommandContext(ctx, command, args...)
@ -95,7 +93,7 @@ func CommandContext(ctx context.Context, command string, args ...string) (*StarC
} }
func (starcli *StarCmd) queryStdout(ctx context.Context) { func (starcli *StarCmd) queryStdout(ctx context.Context) {
for starcli.running && starcli.CMD != nil { for starcli.IsRunning() && starcli.CMD != nil {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
@ -115,7 +113,7 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
if err == io.EOF { if err == io.EOF {
break break
} else { } else {
if !strings.Contains(err.Error(),"file already closed") { if !strings.Contains(err.Error(), "file already closed") {
starcli.runerr = err starcli.runerr = err
} }
return return
@ -125,7 +123,7 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
} }
func (starcli *StarCmd) queryStderr(ctx context.Context) { func (starcli *StarCmd) queryStderr(ctx context.Context) {
for starcli.running && starcli.CMD != nil { for starcli.IsRunning() && starcli.CMD != nil {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
@ -145,7 +143,7 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
if err == io.EOF { if err == io.EOF {
break break
} else { } else {
if !strings.Contains(err.Error(),"file already closed") { if !strings.Contains(err.Error(), "file already closed") {
starcli.runerr = err starcli.runerr = err
} }
return return
@ -247,20 +245,38 @@ func (starcli *StarCmd) AllStdErr() error {
return err return err
} }
func (starcli *StarCmd) setRunning(alive bool) {
if alive {
val := atomic.LoadInt32(&starcli.running)
if val == 0 {
atomic.AddInt32(&starcli.running, 1)
} else {
atomic.AddInt32(&starcli.running, 1-val)
}
return
}
val := atomic.LoadInt32(&starcli.running)
if val == 1 {
atomic.AddInt32(&starcli.running, -1)
} else {
atomic.AddInt32(&starcli.running, -val)
}
}
func (starcli *StarCmd) Start() error { func (starcli *StarCmd) Start() error {
if err := starcli.CMD.Start(); err != nil { if err := starcli.CMD.Start(); err != nil {
return err return err
} }
starcli.running = true starcli.setRunning(true)
go func() { go func() {
err := starcli.CMD.Wait() err := starcli.CMD.Wait()
if err != nil { if err != nil {
starcli.runerr = err starcli.runerr = err
} }
starcli.stopctxfunc() starcli.stopctxfunc()
starcli.running = false starcli.setRunning(false)
starcli.exitcode = starcli.CMD.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() if starcli.CMD.ProcessState != nil {
starcli.runningChan <- 1 starcli.exitcode = starcli.CMD.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
}
}() }()
go starcli.queryStdout(starcli.stopctx) go starcli.queryStdout(starcli.stopctx)
go starcli.queryStderr(starcli.stopctx) go starcli.queryStderr(starcli.stopctx)
@ -282,11 +298,11 @@ func (starcli *StarCmd) Start() error {
} }
func (starcli *StarCmd) IsRunning() bool { func (starcli *StarCmd) IsRunning() bool {
return starcli.running return 0 != atomic.LoadInt32(&starcli.running)
} }
func (starcli *StarCmd) Stoped() <-chan int { func (starcli *StarCmd) Stoped() <-chan struct{} {
return starcli.runningChan return starcli.stopctx.Done()
} }
func (starcli *StarCmd) Exec(cmd string, wait int) (string, error) { func (starcli *StarCmd) Exec(cmd string, wait int) (string, error) {
@ -313,12 +329,12 @@ func (starcli *StarCmd) ExitCode() int {
return starcli.exitcode return starcli.exitcode
} }
func (starcli *StarCmd) Kill() error{ func (starcli *StarCmd) Kill() error {
err:=starcli.CMD.Process.Kill() err := starcli.CMD.Process.Kill()
if err!=nil{ if err != nil {
return err return err
} }
starcli.running = false starcli.setRunning(false)
return nil return nil
} }

@ -36,7 +36,7 @@ func FindProcess(compare func(Process) bool) (datas []Process, err error) {
if err != nil { if err != nil {
return return
} }
netInfo, netErr = NetConnections(false) netInfo, netErr = NetConnections(false, "")
appendNetInfo := func(p *Process) { appendNetInfo := func(p *Process) {
if netErr != nil { if netErr != nil {
p.netErr = netErr p.netErr = netErr
@ -170,7 +170,7 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
err = errors.New("Not Found") err = errors.New("Not Found")
return return
} }
netInfo, netErr := NetConnections(false) netInfo, netErr := NetConnections(false, "")
appendNetInfo := func(p *Process) { appendNetInfo := func(p *Process) {
if netErr != nil { if netErr != nil {
p.netErr = netErr p.netErr = netErr
@ -283,12 +283,12 @@ func Daemon(path string, args ...string) (int, error) {
return pid, err return pid, err
} }
func DaemonWithUser(uid, gid uint32,groups []uint32,path string, args ...string) (int, error) { func DaemonWithUser(uid, gid uint32, groups []uint32, path string, args ...string) (int, error) {
cmd := exec.Command(path, args...) cmd := exec.Command(path, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{ cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{ Credential: &syscall.Credential{
Uid: uid, Uid: uid,
Gid: gid, Gid: gid,
Groups: groups, Groups: groups,
}, },
Setsid: true, Setsid: true,
@ -301,11 +301,11 @@ func DaemonWithUser(uid, gid uint32,groups []uint32,path string, args ...string)
return pid, err return pid, err
} }
func (starcli *StarCmd) SetRunUser(uid, gid uint32,groups []uint32) { func (starcli *StarCmd) SetRunUser(uid, gid uint32, groups []uint32) {
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{ starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{ Credential: &syscall.Credential{
Uid: uid, Uid: uid,
Gid: gid, Gid: gid,
Groups: groups, Groups: groups,
}, },
Setsid: true, Setsid: true,
@ -318,13 +318,16 @@ func (starcli *StarCmd) Release() error {
Setsid: true, Setsid: true,
} }
} else { } else {
starcli.CMD.SysProcAttr.Setsid = true if !starcli.CMD.SysProcAttr.Setsid {
starcli.CMD.SysProcAttr.Setsid = true
}
} }
if !starcli.IsRunning() { if !starcli.IsRunning() {
if err := starcli.CMD.Start(); err != nil { if err := starcli.CMD.Start(); err != nil {
return err return err
} }
} }
time.Sleep(time.Millisecond * 10)
return starcli.CMD.Process.Release() return starcli.CMD.Process.Release()
} }

@ -78,8 +78,7 @@ func (syscfg *SysConf) ParseFromFile(filepath string) error {
if err != nil { if err != nil {
return err return err
} }
syscfg.Parse(data) return syscfg.Parse(data)
return nil
} }
// Parse 生成INI文件结构 // Parse 生成INI文件结构

@ -11,6 +11,22 @@ const (
TB = GB << 10 TB = GB << 10
PB = TB << 10 PB = TB << 10
) )
const (
TCP_UNKNOWN = iota
TCP_ESTABLISHED
TCP_SYN_SENT
TCP_SYN_RECV
TCP_FIN_WAIT1
TCP_FIN_WAIT2
TCP_TIME_WAIT
TCP_CLOSE
TCP_CLOSE_WAIT
TCP_LAST_ACL
TCP_LISTEN
TCP_CLOSING
)
var TCP_STATE = []string{"TCP_UNKNOWN", "TCP_ESTABLISHED", "TCP_SYN_SENT", "TCP_SYN_RECV", "TCP_FIN_WAIT1", "TCP_FIN_WAIT2", "TCP_TIME_WAIT", "TCP_CLOSE", "TCP_CLOSE_WAIT", "TCP_LAST_ACL", "TCP_LISTEN", "TCP_CLOSING"}
type NetAdapter struct { type NetAdapter struct {
Name string Name string
@ -79,14 +95,20 @@ type DiskStatus struct {
} }
type NetConn struct { type NetConn struct {
LocalAddr string LocalAddr string
LocalPort int LocalPort int
Typed string Typed string
RemoteAddr string RemoteAddr string
RemotePort int RemotePort int
Socket string Socket string
Inode string Inode string
Pid int64 Status string
Uid int64 TX_Queue int64
Process *Process RX_Queue int64
TimerActive string
TimerJiffies int64
RtoTimer int64
Pid int64
Uid int64
Process *Process
} }

Loading…
Cancel
Save