// +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.Path = tmp.LocalPath 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.Path = datas.LocalPath 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 } 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 }