- 重构 sysconf 为文档模型 INI Parser 与 Config Framework - 强化 hosts 解析、插入校验、写回与异常输入处理 - 完善 StarCmd 生命周期、等待 API、流式输出与 IO 重定向 - 扩展跨平台文件时间、文件锁、内存、进程与网络能力 - 将 Windows 进程适配更新到 b612.me/wincmd v0.1.0 - 移除本地 wincmd/win32api replace,改用发布版依赖 - 将最低 Go 版本提升到 1.18 - 补充 hosts、sysconf、FileLock、StarCmd 与平台适配回归测试
198 lines
4.4 KiB
Go
198 lines
4.4 KiB
Go
//go:build windows
|
|
// +build windows
|
|
|
|
package staros
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"b612.me/wincmd"
|
|
)
|
|
|
|
// FindProcessByName 通过进程名来查询应用信息
|
|
func FindProcessByName(pname string) (data []Process, err error) {
|
|
var lists []map[string]string
|
|
lists, err = wincmd.GetRunningProcess()
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, v := range lists {
|
|
if v["name"] == pname {
|
|
var tmp Process
|
|
tmp.Name = pname
|
|
tmp.Pid, _ = strconv.ParseInt(v["pid"], 10, 64)
|
|
tmp.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
|
|
data = append(data, tmp)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func FindProcess(compare func(Process) bool) (data []Process, err error) {
|
|
var lists []map[string]string
|
|
lists, err = wincmd.GetRunningProcess()
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, v := range lists {
|
|
var tmp Process
|
|
tmp.Name = v["name"]
|
|
tmp.Pid, _ = strconv.ParseInt(v["pid"], 10, 64)
|
|
tmp.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
|
|
if compare(tmp) {
|
|
data = append(data, tmp)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// FindProcessByPid 通过pid来查询应用信息
|
|
func FindProcessByPid(pid int64) (data Process, err error) {
|
|
var lists []map[string]string
|
|
lists, err = wincmd.GetRunningProcess()
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, v := range lists {
|
|
if v["pid"] == fmt.Sprint(pid) {
|
|
data.Name = v["name"]
|
|
data.Pid = pid
|
|
data.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64)
|
|
return
|
|
}
|
|
}
|
|
err = errors.New("Not Found")
|
|
return
|
|
}
|
|
|
|
func Daemon(path string, args ...string) (int, error) {
|
|
cmd := exec.Command(path, args...)
|
|
if err := cmd.Start(); err != nil {
|
|
return -1, err
|
|
}
|
|
pid := cmd.Process.Pid
|
|
cmd.Process.Release()
|
|
return pid, nil
|
|
}
|
|
|
|
func DaemonWithUser(uid, gid uint32, groups []uint32, path string, args ...string) (int, error) {
|
|
return -1, ERR_UNSUPPORTED
|
|
}
|
|
|
|
func (starcli *StarCmd) SetRunUser(uid, gid uint32, groups []uint32) {
|
|
_ = starcli.SetRunUserE(uid, gid, groups)
|
|
}
|
|
|
|
func (starcli *StarCmd) SetRunUserE(uid, gid uint32, groups []uint32) error {
|
|
if starcli == nil || starcli.CMD == nil {
|
|
return errNilCommand
|
|
}
|
|
if atomic.LoadInt32(&starcli.started) != 0 {
|
|
return errCommandAlreadyStarted
|
|
}
|
|
return ERR_UNSUPPORTED
|
|
}
|
|
|
|
func (starcli *StarCmd) Release() error {
|
|
return starcli.ReleaseE()
|
|
}
|
|
|
|
func (starcli *StarCmd) Detach() error {
|
|
return starcli.DetachE()
|
|
}
|
|
|
|
func (starcli *StarCmd) ReleaseE() error {
|
|
if starcli == nil || starcli.CMD == nil {
|
|
return errNilCommand
|
|
}
|
|
if !atomic.CompareAndSwapInt32(&starcli.released, 0, 1) {
|
|
return errCommandAlreadyReleased
|
|
}
|
|
if atomic.LoadInt32(&starcli.started) != 0 {
|
|
if starcli.CMD.Process == nil {
|
|
starcli.lock.Lock()
|
|
err := starcli.runerr
|
|
starcli.lock.Unlock()
|
|
if err != nil {
|
|
atomic.StoreInt32(&starcli.released, 0)
|
|
return err
|
|
}
|
|
atomic.StoreInt32(&starcli.released, 0)
|
|
return errCommandAlreadyStarted
|
|
}
|
|
return nil
|
|
}
|
|
if err := starcli.Start(); err != nil {
|
|
atomic.StoreInt32(&starcli.released, 0)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (starcli *StarCmd) DetachE() error {
|
|
if starcli == nil || starcli.CMD == nil {
|
|
return errNilCommand
|
|
}
|
|
if !atomic.CompareAndSwapInt32(&starcli.detached, 0, 1) {
|
|
return errCommandAlreadyDetached
|
|
}
|
|
if atomic.LoadInt32(&starcli.started) != 0 {
|
|
atomic.StoreInt32(&starcli.detached, 0)
|
|
return errCommandAlreadyStarted
|
|
}
|
|
cmd := exec.Command(starcli.CMD.Path, starcli.CMD.Args[1:]...)
|
|
cmd.Dir = starcli.CMD.Dir
|
|
cmd.Env = append([]string(nil), starcli.CMD.Env...)
|
|
if starcli.CMD.SysProcAttr != nil {
|
|
attr := *starcli.CMD.SysProcAttr
|
|
cmd.SysProcAttr = &attr
|
|
}
|
|
devNull, err := os.OpenFile(os.DevNull, os.O_RDWR, 0)
|
|
if err != nil {
|
|
atomic.StoreInt32(&starcli.detached, 0)
|
|
return err
|
|
}
|
|
defer devNull.Close()
|
|
cmd.Stdin = devNull
|
|
cmd.Stdout = devNull
|
|
cmd.Stderr = devNull
|
|
if err := cmd.Start(); err != nil {
|
|
atomic.StoreInt32(&starcli.detached, 0)
|
|
return err
|
|
}
|
|
starcli.CMD.Process = cmd.Process
|
|
atomic.StoreInt32(&starcli.started, 1)
|
|
starcli.setRunning(false)
|
|
starcli.finish()
|
|
if err := cmd.Process.Release(); err != nil {
|
|
atomic.StoreInt32(&starcli.detached, 0)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (starcli *StarCmd) SetKeepCaps() error {
|
|
if starcli == nil || starcli.CMD == nil {
|
|
return errNilCommand
|
|
}
|
|
return ERR_UNSUPPORTED
|
|
}
|
|
|
|
func SetKeepCaps() error {
|
|
return ERR_UNSUPPORTED
|
|
}
|
|
|
|
func CpuUsageByPid(pid int, sleep time.Duration) float64 {
|
|
return 0
|
|
}
|
|
|
|
func Whoami() (uid, gid int, uname, gname, home string, err error) {
|
|
return 0, 0, "", "", "", ERR_UNSUPPORTED
|
|
}
|