new feature add
This commit is contained in:
parent
3501166592
commit
cf453821ef
14
files.go
14
files.go
@ -1,6 +1,18 @@
|
||||
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 {
|
||||
|
22
files_test.go
Normal file
22
files_test.go
Normal file
@ -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
|
||||
|
||||
import (
|
||||
"b612.me/stario"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileLock struct {
|
||||
fd int
|
||||
filepath string
|
||||
}
|
||||
|
||||
func timespecToTime(ts syscall.Timespec) time.Time {
|
||||
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 {
|
||||
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
|
||||
|
||||
import (
|
||||
"b612.me/win32api"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileLock struct {
|
||||
filepath string
|
||||
handle win32api.HANDLE
|
||||
}
|
||||
|
||||
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
|
||||
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
|
||||
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())
|
||||
}
|
||||
|
||||
func SetFileTimes(file *os.File,info os.FileInfo) {
|
||||
func SetFileTimes(file *os.File, info os.FileInfo) {
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
// 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 inodeMap map[string]int64
|
||||
var err error
|
||||
fileList := []string{
|
||||
"/proc/net/tcp",
|
||||
"/proc/net/tcp6",
|
||||
"/proc/net/udp",
|
||||
"/proc/net/udp6",
|
||||
"/proc/net/unix",
|
||||
var fileList []string
|
||||
if types=="" || strings.Contains(strings.ToLower(types),"all") {
|
||||
fileList = []string{
|
||||
"/proc/net/tcp",
|
||||
"/proc/net/tcp6",
|
||||
"/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 {
|
||||
inodeMap, err = GetInodeMap()
|
||||
@ -135,6 +147,9 @@ func GetInodeMap() (map[string]int64, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(socket, "socket") {
|
||||
continue
|
||||
}
|
||||
start := strings.Index(socket, "[")
|
||||
if start < 0 {
|
||||
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) {
|
||||
@ -177,6 +192,60 @@ func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]Ne
|
||||
}
|
||||
res.RemoteAddr = ip
|
||||
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)
|
||||
if err != nil {
|
||||
return result, err
|
||||
@ -229,7 +298,7 @@ func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]N
|
||||
res.Pid = -1
|
||||
} else {
|
||||
_, ok := pidMap[res.Pid]
|
||||
if !ok {
|
||||
if !ok || pidMap[res.Pid] == nil {
|
||||
tmp, err := FindProcessByPid(res.Pid)
|
||||
if err != nil {
|
||||
pidMap[res.Pid] = nil
|
||||
@ -237,8 +306,10 @@ func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]N
|
||||
pidMap[res.Pid] = &tmp
|
||||
}
|
||||
}
|
||||
res.Uid = int64(pidMap[res.Pid].RUID)
|
||||
res.Process = pidMap[res.Pid]
|
||||
if pidMap[res.Pid] != nil {
|
||||
res.Uid = int64(pidMap[res.Pid].RUID)
|
||||
res.Process = pidMap[res.Pid]
|
||||
}
|
||||
}
|
||||
}
|
||||
res.Typed = typed
|
||||
|
58
os_unix.go
58
os_unix.go
@ -3,6 +3,7 @@
|
||||
package staros
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/user"
|
||||
@ -12,6 +13,8 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var clockTicks = 100 // default value
|
||||
|
||||
// StartTime 开机时间
|
||||
func StartTime() time.Time {
|
||||
tmp, _ := readAsString("/proc/stat")
|
||||
@ -63,9 +66,9 @@ func getCPUSample() (idle, total uint64) {
|
||||
if err != nil {
|
||||
fmt.Println("Error: ", i, fields[i], err)
|
||||
}
|
||||
total += val // tally up all the numbers to get total ticks
|
||||
if i == 4 { // idle is the 5th field in the cpu line
|
||||
idle = val
|
||||
total += val // tally up all the numbers to get total ticks
|
||||
if i == 4 || i == 5 { // idle is the 5th field in the cpu line
|
||||
idle += val
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -73,6 +76,55 @@ func getCPUSample() (idle, total uint64) {
|
||||
}
|
||||
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使用量
|
||||
func CpuUsage(sleep time.Duration) float64 {
|
||||
|
66
process.go
66
process.go
@ -9,6 +9,7 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@ -16,12 +17,11 @@ import (
|
||||
//StarCmd Is Here
|
||||
|
||||
type StarCmd struct {
|
||||
CMD *exec.Cmd
|
||||
outfile io.ReadCloser
|
||||
infile io.WriteCloser
|
||||
errfile io.ReadCloser
|
||||
running bool
|
||||
runningChan chan int
|
||||
CMD *exec.Cmd
|
||||
outfile io.ReadCloser
|
||||
infile io.WriteCloser
|
||||
errfile io.ReadCloser
|
||||
running int32
|
||||
//Store AlL of the Standed Outputs
|
||||
stdout []byte
|
||||
//Store All of the Standed Errors
|
||||
@ -42,11 +42,10 @@ type StarCmd struct {
|
||||
func Command(command string, args ...string) (*StarCmd, error) {
|
||||
var err error
|
||||
shell := new(StarCmd)
|
||||
shell.running = false
|
||||
shell.running = 0
|
||||
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
|
||||
@ -69,10 +68,9 @@ func Command(command string, args ...string) (*StarCmd, error) {
|
||||
func CommandContext(ctx context.Context, command string, args ...string) (*StarCmd, error) {
|
||||
var err error
|
||||
shell := new(StarCmd)
|
||||
shell.running = false
|
||||
shell.running = 0
|
||||
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...)
|
||||
@ -95,7 +93,7 @@ func CommandContext(ctx context.Context, command string, args ...string) (*StarC
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
||||
for starcli.running && starcli.CMD != nil {
|
||||
for starcli.IsRunning() && starcli.CMD != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
@ -115,7 +113,7 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else {
|
||||
if !strings.Contains(err.Error(),"file already closed") {
|
||||
if !strings.Contains(err.Error(), "file already closed") {
|
||||
starcli.runerr = err
|
||||
}
|
||||
return
|
||||
@ -125,7 +123,7 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
||||
for starcli.running && starcli.CMD != nil {
|
||||
for starcli.IsRunning() && starcli.CMD != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
@ -145,7 +143,7 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else {
|
||||
if !strings.Contains(err.Error(),"file already closed") {
|
||||
if !strings.Contains(err.Error(), "file already closed") {
|
||||
starcli.runerr = err
|
||||
}
|
||||
return
|
||||
@ -247,20 +245,38 @@ func (starcli *StarCmd) AllStdErr() error {
|
||||
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 {
|
||||
if err := starcli.CMD.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
starcli.running = true
|
||||
starcli.setRunning(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
|
||||
starcli.setRunning(false)
|
||||
if starcli.CMD.ProcessState != nil {
|
||||
starcli.exitcode = starcli.CMD.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
|
||||
}
|
||||
}()
|
||||
go starcli.queryStdout(starcli.stopctx)
|
||||
go starcli.queryStderr(starcli.stopctx)
|
||||
@ -282,11 +298,11 @@ func (starcli *StarCmd) Start() error {
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) IsRunning() bool {
|
||||
return starcli.running
|
||||
return 0 != atomic.LoadInt32(&starcli.running)
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) Stoped() <-chan int {
|
||||
return starcli.runningChan
|
||||
func (starcli *StarCmd) Stoped() <-chan struct{} {
|
||||
return starcli.stopctx.Done()
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) Exec(cmd string, wait int) (string, error) {
|
||||
@ -313,12 +329,12 @@ func (starcli *StarCmd) ExitCode() int {
|
||||
return starcli.exitcode
|
||||
}
|
||||
|
||||
func (starcli *StarCmd) Kill() error{
|
||||
err:=starcli.CMD.Process.Kill()
|
||||
if err!=nil{
|
||||
func (starcli *StarCmd) Kill() error {
|
||||
err := starcli.CMD.Process.Kill()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
starcli.running = false
|
||||
starcli.setRunning(false)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ func FindProcess(compare func(Process) bool) (datas []Process, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
netInfo, netErr = NetConnections(false)
|
||||
netInfo, netErr = NetConnections(false, "")
|
||||
appendNetInfo := func(p *Process) {
|
||||
if netErr != nil {
|
||||
p.netErr = netErr
|
||||
@ -170,7 +170,7 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
|
||||
err = errors.New("Not Found")
|
||||
return
|
||||
}
|
||||
netInfo, netErr := NetConnections(false)
|
||||
netInfo, netErr := NetConnections(false, "")
|
||||
appendNetInfo := func(p *Process) {
|
||||
if netErr != nil {
|
||||
p.netErr = netErr
|
||||
@ -283,12 +283,12 @@ func Daemon(path string, args ...string) (int, error) {
|
||||
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.SysProcAttr = &syscall.SysProcAttr{
|
||||
Credential: &syscall.Credential{
|
||||
Uid: uid,
|
||||
Gid: gid,
|
||||
Uid: uid,
|
||||
Gid: gid,
|
||||
Groups: groups,
|
||||
},
|
||||
Setsid: true,
|
||||
@ -301,11 +301,11 @@ func DaemonWithUser(uid, gid uint32,groups []uint32,path string, args ...string)
|
||||
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{
|
||||
Credential: &syscall.Credential{
|
||||
Uid: uid,
|
||||
Gid: gid,
|
||||
Uid: uid,
|
||||
Gid: gid,
|
||||
Groups: groups,
|
||||
},
|
||||
Setsid: true,
|
||||
@ -318,13 +318,16 @@ func (starcli *StarCmd) Release() error {
|
||||
Setsid: true,
|
||||
}
|
||||
} else {
|
||||
starcli.CMD.SysProcAttr.Setsid = true
|
||||
if !starcli.CMD.SysProcAttr.Setsid {
|
||||
starcli.CMD.SysProcAttr.Setsid = true
|
||||
}
|
||||
}
|
||||
if !starcli.IsRunning() {
|
||||
if err := starcli.CMD.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
return starcli.CMD.Process.Release()
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,7 @@ func (syscfg *SysConf) ParseFromFile(filepath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
syscfg.Parse(data)
|
||||
return nil
|
||||
return syscfg.Parse(data)
|
||||
}
|
||||
|
||||
// Parse 生成INI文件结构
|
||||
|
42
typed.go
42
typed.go
@ -11,6 +11,22 @@ const (
|
||||
TB = GB << 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 {
|
||||
Name string
|
||||
@ -79,14 +95,20 @@ type DiskStatus struct {
|
||||
}
|
||||
|
||||
type NetConn struct {
|
||||
LocalAddr string
|
||||
LocalPort int
|
||||
Typed string
|
||||
RemoteAddr string
|
||||
RemotePort int
|
||||
Socket string
|
||||
Inode string
|
||||
Pid int64
|
||||
Uid int64
|
||||
Process *Process
|
||||
LocalAddr string
|
||||
LocalPort int
|
||||
Typed string
|
||||
RemoteAddr string
|
||||
RemotePort int
|
||||
Socket string
|
||||
Inode string
|
||||
Status string
|
||||
TX_Queue int64
|
||||
RX_Queue int64
|
||||
TimerActive string
|
||||
TimerJiffies int64
|
||||
RtoTimer int64
|
||||
Pid int64
|
||||
Uid int64
|
||||
Process *Process
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user