process_solaris.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package process
  2. import (
  3. "bytes"
  4. "context"
  5. "io/ioutil"
  6. "os"
  7. "strconv"
  8. "strings"
  9. "github.com/shirou/gopsutil/v3/cpu"
  10. "github.com/shirou/gopsutil/v3/internal/common"
  11. "github.com/shirou/gopsutil/v3/net"
  12. )
  13. type MemoryMapsStat struct {
  14. Path string `json:"path"`
  15. Rss uint64 `json:"rss"`
  16. Size uint64 `json:"size"`
  17. Pss uint64 `json:"pss"`
  18. SharedClean uint64 `json:"sharedClean"`
  19. SharedDirty uint64 `json:"sharedDirty"`
  20. PrivateClean uint64 `json:"privateClean"`
  21. PrivateDirty uint64 `json:"privateDirty"`
  22. Referenced uint64 `json:"referenced"`
  23. Anonymous uint64 `json:"anonymous"`
  24. Swap uint64 `json:"swap"`
  25. }
  26. type MemoryInfoExStat struct{}
  27. func pidsWithContext(ctx context.Context) ([]int32, error) {
  28. return readPidsFromDir(common.HostProc())
  29. }
  30. func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
  31. out := []*Process{}
  32. pids, err := PidsWithContext(ctx)
  33. if err != nil {
  34. return out, err
  35. }
  36. for _, pid := range pids {
  37. p, err := NewProcessWithContext(ctx, pid)
  38. if err != nil {
  39. continue
  40. }
  41. out = append(out, p)
  42. }
  43. return out, nil
  44. }
  45. func (p *Process) PpidWithContext(ctx context.Context) (int32, error) {
  46. return 0, common.ErrNotImplementedError
  47. }
  48. func (p *Process) NameWithContext(ctx context.Context) (string, error) {
  49. return "", common.ErrNotImplementedError
  50. }
  51. func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
  52. return 0, common.ErrNotImplementedError
  53. }
  54. func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
  55. exe, err := p.fillFromPathAOutWithContext(ctx)
  56. if os.IsNotExist(err) {
  57. exe, err = p.fillFromExecnameWithContext(ctx)
  58. }
  59. return exe, err
  60. }
  61. func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
  62. return p.fillFromCmdlineWithContext(ctx)
  63. }
  64. func (p *Process) CmdlineSliceWithContext(ctx context.Context) ([]string, error) {
  65. return p.fillSliceFromCmdlineWithContext(ctx)
  66. }
  67. func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
  68. return 0, common.ErrNotImplementedError
  69. }
  70. func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
  71. return p.fillFromPathCwdWithContext(ctx)
  72. }
  73. func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
  74. return []string{""}, common.ErrNotImplementedError
  75. }
  76. func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
  77. return false, common.ErrNotImplementedError
  78. }
  79. func (p *Process) UidsWithContext(ctx context.Context) ([]int32, error) {
  80. return nil, common.ErrNotImplementedError
  81. }
  82. func (p *Process) GidsWithContext(ctx context.Context) ([]int32, error) {
  83. return nil, common.ErrNotImplementedError
  84. }
  85. func (p *Process) GroupsWithContext(ctx context.Context) ([]int32, error) {
  86. return nil, common.ErrNotImplementedError
  87. }
  88. func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
  89. return "", common.ErrNotImplementedError
  90. }
  91. func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
  92. return 0, common.ErrNotImplementedError
  93. }
  94. func (p *Process) IOniceWithContext(ctx context.Context) (int32, error) {
  95. return 0, common.ErrNotImplementedError
  96. }
  97. func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
  98. return nil, common.ErrNotImplementedError
  99. }
  100. func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
  101. return nil, common.ErrNotImplementedError
  102. }
  103. func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
  104. return nil, common.ErrNotImplementedError
  105. }
  106. func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
  107. return nil, common.ErrNotImplementedError
  108. }
  109. func (p *Process) NumFDsWithContext(ctx context.Context) (int32, error) {
  110. _, fnames, err := p.fillFromfdListWithContext(ctx)
  111. return int32(len(fnames)), err
  112. }
  113. func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
  114. return 0, common.ErrNotImplementedError
  115. }
  116. func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
  117. return nil, common.ErrNotImplementedError
  118. }
  119. func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) {
  120. return nil, common.ErrNotImplementedError
  121. }
  122. func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
  123. return nil, common.ErrNotImplementedError
  124. }
  125. func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
  126. return nil, common.ErrNotImplementedError
  127. }
  128. func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
  129. return nil, common.ErrNotImplementedError
  130. }
  131. func (p *Process) PageFaultsWithContext(ctx context.Context) (*PageFaultsStat, error) {
  132. return nil, common.ErrNotImplementedError
  133. }
  134. func (p *Process) ChildrenWithContext(ctx context.Context) ([]*Process, error) {
  135. return nil, common.ErrNotImplementedError
  136. }
  137. func (p *Process) OpenFilesWithContext(ctx context.Context) ([]OpenFilesStat, error) {
  138. return nil, common.ErrNotImplementedError
  139. }
  140. func (p *Process) ConnectionsWithContext(ctx context.Context) ([]net.ConnectionStat, error) {
  141. return nil, common.ErrNotImplementedError
  142. }
  143. func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net.ConnectionStat, error) {
  144. return nil, common.ErrNotImplementedError
  145. }
  146. func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
  147. return nil, common.ErrNotImplementedError
  148. }
  149. func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) {
  150. return nil, common.ErrNotImplementedError
  151. }
  152. /**
  153. ** Internal functions
  154. **/
  155. func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) {
  156. pid := p.Pid
  157. statPath := common.HostProc(strconv.Itoa(int(pid)), "fd")
  158. d, err := os.Open(statPath)
  159. if err != nil {
  160. return statPath, []string{}, err
  161. }
  162. defer d.Close()
  163. fnames, err := d.Readdirnames(-1)
  164. return statPath, fnames, err
  165. }
  166. func (p *Process) fillFromPathCwdWithContext(ctx context.Context) (string, error) {
  167. pid := p.Pid
  168. cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "cwd")
  169. cwd, err := os.Readlink(cwdPath)
  170. if err != nil {
  171. return "", err
  172. }
  173. return cwd, nil
  174. }
  175. func (p *Process) fillFromPathAOutWithContext(ctx context.Context) (string, error) {
  176. pid := p.Pid
  177. cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "a.out")
  178. exe, err := os.Readlink(cwdPath)
  179. if err != nil {
  180. return "", err
  181. }
  182. return exe, nil
  183. }
  184. func (p *Process) fillFromExecnameWithContext(ctx context.Context) (string, error) {
  185. pid := p.Pid
  186. execNamePath := common.HostProc(strconv.Itoa(int(pid)), "execname")
  187. exe, err := ioutil.ReadFile(execNamePath)
  188. if err != nil {
  189. return "", err
  190. }
  191. return string(exe), nil
  192. }
  193. func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) {
  194. pid := p.Pid
  195. cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
  196. cmdline, err := ioutil.ReadFile(cmdPath)
  197. if err != nil {
  198. return "", err
  199. }
  200. ret := strings.FieldsFunc(string(cmdline), func(r rune) bool {
  201. if r == '\u0000' {
  202. return true
  203. }
  204. return false
  205. })
  206. return strings.Join(ret, " "), nil
  207. }
  208. func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) {
  209. pid := p.Pid
  210. cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
  211. cmdline, err := ioutil.ReadFile(cmdPath)
  212. if err != nil {
  213. return nil, err
  214. }
  215. if len(cmdline) == 0 {
  216. return nil, nil
  217. }
  218. if cmdline[len(cmdline)-1] == 0 {
  219. cmdline = cmdline[:len(cmdline)-1]
  220. }
  221. parts := bytes.Split(cmdline, []byte{0})
  222. var strParts []string
  223. for _, p := range parts {
  224. strParts = append(strParts, string(p))
  225. }
  226. return strParts, nil
  227. }
  228. func readPidsFromDir(path string) ([]int32, error) {
  229. var ret []int32
  230. d, err := os.Open(path)
  231. if err != nil {
  232. return nil, err
  233. }
  234. defer d.Close()
  235. fnames, err := d.Readdirnames(-1)
  236. if err != nil {
  237. return nil, err
  238. }
  239. for _, fname := range fnames {
  240. pid, err := strconv.ParseInt(fname, 10, 32)
  241. if err != nil {
  242. // if not numeric name, just skip
  243. continue
  244. }
  245. ret = append(ret, int32(pid))
  246. }
  247. return ret, nil
  248. }