process_solaris.go 8.2 KB

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